How to Deploy and Configure Argocd in Kubernetes

ArgoCD is a GitOps principle-based continuous delivery tool for Kubernetes. Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.

Checkout this related post

# Requirements

Before proceeding, ensure that you:

  • Have installed kubectl command-line tool.
  • Have a kubeconfig file (default location is ~/.kube/config).

# Install Argo CD

Create namespace and switch to it before kustomize installing it

1
2
kubectl create ns argocd
kubectl config set-context --current --namespace=argocd

Then install argocd nstall

1
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

If you are not interested in UI, SSO, multi-cluster features then you can install core Argo CD components only:

1
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/core-install.yaml

# Installing the argocd CLI

Download the latest Argo CD version from this link. More detailed installation instructions can be found via the CLI installation documentation.

Also available in Mac, Linux and WSL Homebrew:

1
brew install argocd

# Access The Argo CD API Server

By default, the Argo CD API server is not exposed with an external IP. To access the API server, choose one of the following techniques to expose the Argo CD API server:

# Service Type Load Balancer

Change the argocd-server service type to LoadBalancer:

1
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

# Port Forwarding¶

Kubectl port-forwarding can also be used to connect to the API server without exposing the service.

1
kubectl port-forward svc/argocd-server -n argocd 8080:443

The API server can then be accessed using https://localhost:8080

# Ingress

The API server should be run with TLS disabled for ingress to work. Edit the argocd-server deployment to add the --insecure flag to the argocd-server command or set server.insecure: "true" in the argocd-cmd-params-cm ConfigMap.

Edit the configmap:

1
kubectl edit cm argocd-cmd-params-cm

Update it to look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: v1
kind: ConfigMap
metadata:
  annotations:
  labels:
    app.kubernetes.io/name: argocd-cmd-params-cm
    app.kubernetes.io/part-of: argocd
  name: argocd-cmd-params-cm
  namespace: argocd
data:
  server.insecure: "true"

Then restart the argocd-server deployment.

1
kubectl rollout restart deploy argocd-server

Create an ingress file.

1
2

vim ingress.yaml

Add this content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-server
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod-issuer
spec:
  ingressClassName: traefik
  rules:
  - host: argocd.citizix.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: argocd-server
            port:
              number: 80
  tls:
  - hosts:
    - argocd.citizix.com
    secretName: argocd-server-tls-ingress

Apply ingress

1
kubectl apply -f ingress.yaml

# Login Using The CLI

The initial password for the admin account is auto-generated and stored as clear text in the field password in a secret named argocd-initial-admin-secret in your Argo CD installation namespace. You can simply retrieve this password using the argocd CLI:

1
argocd admin initial-password -n argocd

Or decoding the secret

1
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 --decode; echo

  You should delete the argocd-initial-admin-secret from the Argo CD namespace once you changed the password. The secret serves no other purpose than to store the initially generated password in clear and can safely be deleted at any time. It will be re-created on demand by Argo CD if a new admin password must be re-generated.  

Using the username admin and the password from above, login to Argo CD’s IP or hostname:

1
argocd login <ARGOCD_SERVER>

  The CLI environment must be able to communicate with the Argo CD API server. If it isn’t directly accessible as described above in step 3, you can tell the CLI to access it using port forwarding through one of these mechanisms: 1) add –port-forward-namespace argocd flag to every CLI command; or 2) set ARGOCD_OPTS environment variable: export ARGOCD_OPTS=’–port-forward-namespace argocd’.  

Change the password using the command:

1
argocd account update-password

# Register an external Cluster To Deploy Apps To

This step registers a cluster’s credentials to Argo CD, and is only necessary when deploying to an external cluster. When deploying internally (to the same cluster that Argo CD is running in), https://kubernetes.default.svc should be used as the application’s K8s API server address.

First list all clusters contexts in your current kubeconfig:

1
kubectl config get-contexts -o name

By default, the cluster where Argo CD is deployed is already configured by Argo CD. You can also see the list of clusters by CLI:

1
argocd cluster list

Choose a context name from the list and supply it to argocd cluster add CONTEXTNAME. For example, for docker-desktop context, run:

1
argocd cluster add docker-desktop

The above command installs a ServiceAccount (argocd-manager), into the kube-system namespace of that kubectl context, and binds the service account to an admin-level ClusterRole. Argo CD uses this service account token to perform its management tasks (i.e. deploy/monitoring).

# Kustomizing Helm charts

Rendering helm charts with kustomization requires that you pass the --enable-helm flag to the kustomize build command.

To enable this in argocd, modify the argocd-cm ConfigMap to include the --enable-helm flag globally for all Kustomize applications:

Edit configmap:

1
kubectl edit cm argocd-cm

Then update it to look like this:

1
2
3
4
5
6
7
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  kustomize.buildOptions: --enable-helm

Restart argocd server to apply the changes

1
kubectl rollout restart deployment.apps

# Deploying Your App With Argo

Everything’s ready to start deploying apps to Argo!

First we need to set the current namespace to argocd running the following command:

1
kubectl config set-context --current --namespace=argocd

Then run the following CLI command to register your app:

1
2
3
4
5
6
7
$ argocd app create argo-demo \
  --repo https://github.com/<username>/<repo>.git \
  --path . \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace argo-demo

application 'argo-demo' created

Let’s unpack what’s happening here:

  • The --repo flag specifies the URL of your Git repository.
  • The --path flag instructs Argo to search for Kubernetes manifests, Helm charts, and other deployable assets inside this path within your repo. . is used here because the example manifests are stored in the repo’s root.
  • The --dest-server flag specifies the URL of the Kubernetes cluster to deploy to. You can use kubernetes.default.svc when you’re deploying to the same cluster that Argo’s running in.
  • --dest-namespace sets the Kubernetes namespace that your app will be deployed into. This should match the metadata.namespace fields set on your resources.

Your app will now be registered with Argo. You can retrieve its details with the argocd app list command:

1
2
NAME              CLUSTER                         NAMESPACE   PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                   PATH  TARGET
argocd/argo-demo  https://kubernetes.default.svc  argo-demo   default  OutOfSync  Missing  <none>      <none>      https://github.com/ilmiont/spacelift-argo-cd-demo.git

The app also shows up in the Argo UI:

The sync results display in your terminal. You should see the Namespace, Service, and Deployment objects all get synced into your cluster, as in the command output above. The messages for all three objects confirm they were created successfully.

Repeat the apps list command to check the app’s new status:

1
argocd app list

Now the app is Synced and Healthy! It’s also green in the Argo UI:

As a final proof, use Kubectl to inspect the deployments in the app’s namespace. This should confirm that nginx is up and running three replicas:

1
2
3
$ kubectl get deployment -n argo-demo
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   3/3     3            3           7m56s

Once the application is created, you can now view its status:

1
argocd app get argo-demo

To manually sync the application

1
argocd app sync guestbook

This command retrieves the manifests from the repository and performs a kubectl apply of the manifests

# Repository credentials

Github repository credentials can be created as secrets, argocd will automatically pick them. Create a yaml file argo-k8s-releases-repo-key.yaml with the following content

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: v1
kind: Secret
metadata:
  annotations:
    managed-by: argocd.argoproj.io
  labels:
    argocd.argoproj.io/secret-type: repository
  name: argo-k8s-releases-github-repo-key
  namespace: argocd
data:
  name: argo-k8s-releases-github-repo-key
  password: ghp_xpmXXXXXXXXXX
  project: default
  type: git
  url: https://github.com/citizix/argo-k8s-releases.git
  username: citizix

Then create the secret:

1
kubectl apply -f argo-k8s-releases-repo-key.yaml

Confirm in the UI - http://127.0.0.1:8080/settings/repos that the repository has been added successfully.

# Application Project

Projects provide a logical grouping of applications, which is useful when Argo CD is used by multiple teams. Projects provide the following features:

  • restrict what may be deployed (trusted Git source repositories)
  • restrict where apps may be deployed to (destination clusters and namespaces)
  • restrict what kinds of objects may or may not be deployed (e.g. RBAC, CRDs, DaemonSets, NetworkPolicy etc…)
  • defining project roles to provide application RBAC (bound to OIDC groups and/or JWT tokens)

Every application belongs to a single project. If unspecified, an application belongs to the default project, which is created automatically and by default, permits deployments from any source repo, to any cluster, and all resource Kinds.

Create an application project for the local cluster manifests

Create a local-cluster.yaml file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
---
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: main-cluster-apps
  namespace: argocd
  # Finalizer that ensures that project is not deleted until it is not referenced by any application
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  description: Project for argocd local cluster argo-k8s-releases related resources

  # Allow manifests to deploy from kubernetes Git repo
  sourceRepos:
  - "https://github.com/etowett/argo-k8s-releases.git"

  # Permit applications to deploy to any namespace in local argocd cluster
  destinations:
  - namespace: "*"
    server: "https://kubernetes.default.svc"

  # Allow to deploy any resource
  clusterResourceWhitelist:
    - group: '*'
      kind: '*'

Then apply the changes

1
k apply -f local-cluster.yaml

# Conclusion

In this guide we managed to set up and install argocd in kubernetes.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy