📖 docs Add: Added argocd pull docs (#168)

* Added argocd pull docs

Signed-off-by: Omar Farag <ofarag@redhat.com>

* Resolve suggestions

Signed-off-by: Omar Farag <ofarag@redhat.com>

---------

Signed-off-by: Omar Farag <ofarag@redhat.com>
This commit is contained in:
Omar Farag
2023-06-07 16:50:58 -04:00
committed by GitHub
parent 3105fbfc5b
commit 483612a615
16 changed files with 346 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
# ArgoCD Application Pull Controller
The [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) application controller uses the hub-spoke pattern or pull model mechanism for decentralized resource delivery to remote clusters.
By using [Open Cluster Management (OCM)](https://open-cluster-management.io/) APIs and components,
the ArgoCD Applications will be pulled from the multi-cluster control plane hub cluster down to
the registered OCM managed clusters. To try it out, check out the [Getting Started Guide](getting-started.md).
## Overview
The current ArgoCD resource delivery is primarily pushing resources from a centralized cluster to the remote/managed clusters.
![push model](./assets/push.png)
By using this controller, users can have a pull model resource delivery mechanism.
![pull model](./assets/pull.png)
The pull model may offers some advantages over the existing push model:
- Scalability: hub-spoke pattern may offers better scalability.
- Security: cluster credentials doesn't have to be stored in a centralized environment may enhance security.
- It may reduce the impact of a single point of centralized failure.
This ArgoCD pull model controller on the Hub cluster will create [ManifestWork](https://open-cluster-management.io/concepts/manifestwork/) objects wrapping Application objects as payload.
The OCM agent on the Managed cluster will see the ManifestWork on the Hub cluster and pull the Application down.

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

View File

@@ -0,0 +1,36 @@
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: guestbook-app-set
namespace: argocd
spec:
generators:
- clusterDecisionResource:
configMapRef: ocm-placement-generator
labelSelector:
matchLabels:
cluster.open-cluster-management.io/placement: guestbook-app-placement
requeueAfterSeconds: 30
template:
metadata:
name: '{{name}}-guestbook-app'
labels:
apps.open-cluster-management.io/pull-to-ocm-managed-cluster: 'true'
annotations:
argocd.argoproj.io/skip-reconcile: 'true'
apps.open-cluster-management.io/ocm-managed-cluster: '{{name}}'
apps.open-cluster-management.io/ocm-managed-cluster-app-namespace: argocd
spec:
project: default
source:
repoURL: 'https://github.com/argoproj/argocd-example-apps.git'
targetRevision: HEAD
path: guestbook
destination:
server: https://kubernetes.default.svc
namespace: guestbook
syncPolicy:
automated:
prune: true
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,14 @@
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: default
namespace: argocd
spec:
clusterResourceWhitelist:
- group: '*'
kind: '*'
destinations:
- namespace: '*'
server: '*'
sourceRepos:
- '*'

View File

@@ -0,0 +1,8 @@
apiVersion: cluster.open-cluster-management.io/v1beta2
kind: ManagedClusterSetBinding
metadata:
name: global
namespace: argocd
spec:
clusterSet: global

View File

@@ -0,0 +1,6 @@
apiVersion: cluster.open-cluster-management.io/v1beta1
kind: Placement
metadata:
name: guestbook-app-placement
namespace: argocd
spec: {}

View File

@@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ocm-placement-consumer
namespace: argocd
rules:
# Allow controller to manage placements/placementdecisions
- apiGroups: ["cluster.open-cluster-management.io"]
resources: ["placements"]
verbs: ["get", "list"]
- apiGroups: ["cluster.open-cluster-management.io"]
resources: ["placementdecisions"]
verbs: ["get", "list"]

View File

@@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ocm-placement-consumer:argocd
namespace: argocd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ocm-placement-consumer
subjects:
- kind: ServiceAccount
namespace: argocd
name: argocd-applicationset-controller

View File

@@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: ocm-placement-generator
namespace: argocd
data:
apiVersion: cluster.open-cluster-management.io/v1beta1
kind: placementdecisions
statusListKey: decisions
matchKey: clusterName

View File

@@ -0,0 +1,8 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: argocd-klusterlet-consumer
rules:
- apiGroups: ["argoproj.io"]
resources: ["applications", "appprojects"]
verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]

View File

@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: klusterlet-argocd-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: argocd-klusterlet-consumer
subjects:
- kind: ServiceAccount
name: klusterlet-work-sa
namespace: open-cluster-management-agent

View File

@@ -0,0 +1,14 @@
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: default
namespace: argocd
spec:
clusterResourceWhitelist:
- group: '*'
kind: '*'
destinations:
- namespace: '*'
server: '*'
sourceRepos:
- '*'

View File

@@ -0,0 +1,36 @@
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: nested-apps-app-set
namespace: argocd
spec:
generators:
- clusterDecisionResource:
configMapRef: ocm-placement-generator
labelSelector:
matchLabels:
cluster.open-cluster-management.io/placement: guestbook-app-placement
requeueAfterSeconds: 30
template:
metadata:
name: '{{name}}-nested-apps'
labels:
apps.open-cluster-management.io/pull-to-ocm-managed-cluster: 'true'
annotations:
argocd.argoproj.io/skip-reconcile: 'true'
apps.open-cluster-management.io/ocm-managed-cluster: '{{name}}'
apps.open-cluster-management.io/ocm-managed-cluster-app-namespace: argocd
spec:
project: default
source:
repoURL: 'https://github.com/argoproj/argocd-example-apps.git'
targetRevision: HEAD
path: apps
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,134 @@
# Getting Started
### Prerequisites
- [kind](https://kind.sigs.k8s.io) must be installed on your local machine. The Kubernetes version must be >= 1.19. See the [kind user guide](https://kind.sigs.k8s.io/docs/user/quick-start/#creating-a-cluster) for more details.
- Download and install [clusteradm](https://github.com/open-cluster-management-io/clusteradm/releases). For Linux OS, run the following commands:
```
wget -qO- https://github.com/open-cluster-management-io/clusteradm/releases/latest/download/clusteradm_linux_amd64.tar.gz | sudo tar -xvz -C /usr/local/bin/
sudo chmod +x /usr/local/bin/clusteradm
```
- The [kubectl](https://kubernetes.io/docs/reference/kubectl/) cli, which should be compatible with your Kubernetes version. See [install and setup](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#before-you-begin) for more info.
### Steps
1. Setup an OCM Hub cluster and registered an OCM Managed cluster.
```
curl -L https://raw.githubusercontent.com/open-cluster-management-io/OCM/main/solutions/setup-dev-environment/local-up.sh | bash
```
See [Open Cluster Management Quick Start](https://open-cluster-management.io/getting-started/quick-start/) for more details.
2. Install ArgoCD on the hub cluster and both managed clusters.
```
for i in "hub" "cluster1" "cluster2"
do
kubectl config use-context kind-$i
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
done
```
See [ArgoCD website](https://argo-cd.readthedocs.io/en/stable/getting_started/) for more details.
1. Install the Pull controller on the hub cluster:
```
kubectl config use-context kind-hub
kubectl apply -f https://raw.githubusercontent.com/open-cluster-management-io/argocd-pull-integration/main/deploy/install.yaml
```
2. If your controller starts successfully, you should see:
```
$ kubectl -n open-cluster-management get deploy | grep pull
argocd-pull-integration-controller-manager 1/1 1 1 106s
```
3. On the Hub cluster, create ArgoCD cluster secrets that represent the managed clusters. This step can be automated with [OCM auto import controller](https://github.com/open-cluster-management-io/multicloud-integrations/).
```
for i in "cluster1" "cluster2"
do
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: $i-secret # cluster1-secret
namespace: argocd
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: $i # cluster1
server: https://$i-control-plane:6443 # https://cluster1-control-plane:6443
EOF
done
```
4. On the Hub cluster, apply the manifests in `example/hub`:
```
kubectl config use-context kind-hub
kubectl apply -f example/hub
```
5. On the managed clusters, apply the manifests in `example/managed`:
```
for i in "cluster1" "cluster2"
do
kubectl config use-context kind-$i
kubectl apply -f example/managed
done
```
6. On the Hub cluster, apply the `guestbook-app-set` manifest:
```
kubectl apply -f example/guestbook-app-set.yaml
```
**Note:** The Application template inside the ApplicationSet must contain the following content:
```
labels:
apps.open-cluster-management.io/pull-to-ocm-managed-cluster: 'true'
annotations:
argocd.argoproj.io/skip-reconcile: 'true'
apps.open-cluster-management.io/ocm-managed-cluster: '{{name}}'
```
The label allows the pull model controller to select the Application for processing.
The `skip-reconcile` annotation is to prevent the Application from reconciling on the Hub cluster.
The `ocm-managed-cluster` annotation is for the ApplicationSet to generate multiple Application based on each cluster generator targets.
7. When this guestbook ApplicationSet reconciles, it will generate an Application for the registered managed clusters. For example:
```
$ kubectl -n argocd get appset
NAME AGE
guestbook-app 84s
$ kubectl -n argocd get app
NAME SYNC STATUS HEALTH STATUS
cluster1-guestbook-app Synced Healthy
cluster2-guestbook-app Synced Healthy
```
8. On the Hub cluster, the pull controller will wrap the Application with a ManifestWork. For example:
```
$ kubectl -n cluster1 get manifestwork
NAME AGE
cluster1-guestbook-app-d0e5 2m41s
```
9. On a managed cluster, you should see that the Application is pulled down successfully. For example:
```
$ kubectl -n argocd get app
NAME SYNC STATUS HEALTH STATUS
cluster1-guestbook-app Synced Healthy
$ kubectl -n guestbook get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
guestbook-ui 1/1 1 1 7m36s
```
10. On the Hub cluster, the status controller will sync the dormant Application with the ManifestWork status feedback. For example:
```
$ kubectl -n argocd get app
NAME SYNC STATUS HEALTH STATUS
cluster1-guestbook-app Synced Healthy
cluster2-guestbook-app Synced Healthy
```
If you have issues or need help troubleshooting, check out the [troubleshooting guide](./troubleshooting.md)

View File

@@ -0,0 +1,19 @@
# Troubleshooting
#### For ArgoCD components, check the following containers for logs:
* argocd-pull-integration-* in the `open-cluster-management` namespace (only on the hub cluster)
* argocd-applicationset-controller in the `argocd` namespace
* argocd-application-controller (only on managed clusters) in the `argocd` namespace
#### If the ApplicationSet contains the following status:
```
status:
conditions:
- lastTransitionTime: "2023-03-21T11:25:06Z"
message: Successfully generated parameters for all Applications
reason: ApplicationSetUpToDate
status: "False"
type: ErrorOccurred
```
Despite the type `ErrorOccurred`, the status is `"False"`, which means the ApplicationSet has been reconciled successfully. If the status is `"True"`, check the error message. If needed, check the `argocd-applicationset-controller` pod logs in the `argocd` namespace.