Skip to main content

Deploying with Argo CD: Installation, CLI Setup, Helm Chart Deployment from GitLab Repository in Kubernetes Cluster

1396 words·
Argo CD GitLab Kubernetes K8s
ArgoCD - This article is part of a series.
Part 1: This Article

Overview
#

In this tutorial I’m using a Kubernetes K8s cluster with MetalLB deployed with Kubespray on Debian 12 servers. My GitLab instance is running on an Ubuntu 22.04 server:

192.168.30.71 deb-02 # Controller / Master Node
192.168.30.72 deb-03 # Controller / Master Node
192.168.30.73 deb-04 # Worker Node
192.168.30.74 deb-05 # Worker Node

192.168.70.4 # GitLab Server

Argo CD Deployment
#

Create Namespace
#

# Create a Kubernetes namespace for Argo CD deployment
kubectl create namespace argocd

Deployment
#

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

Verify the Resources
#

# List the Argo CD resources
kubectl get all -n argocd
Shell Output:
# Shell output:
NAME                                                   READY   STATUS    RESTARTS   AGE
pod/argocd-application-controller-0                    1/1     Running   0          46s
pod/argocd-applicationset-controller-c74dfc889-r5t8z   1/1     Running   0          47s
pod/argocd-dex-server-957c97b7d-dj7hl                  1/1     Running   0          46s
pod/argocd-notifications-controller-7df7749d5-zk2cs    1/1     Running   0          46s
pod/argocd-redis-cc756f67-j5cmz                        1/1     Running   0          46s
pod/argocd-repo-server-6959444795-86snx                1/1     Running   0          46s
pod/argocd-server-55dcfc7c76-4g96q                     1/1     Running   0          46s

NAME                                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/argocd-applicationset-controller          ClusterIP   10.233.47.199   <none>        7000/TCP,8080/TCP            47s
service/argocd-dex-server                         ClusterIP   10.233.13.1     <none>        5556/TCP,5557/TCP,5558/TCP   47s
service/argocd-metrics                            ClusterIP   10.233.9.250    <none>        8082/TCP                     47s
service/argocd-notifications-controller-metrics   ClusterIP   10.233.27.228   <none>        9001/TCP                     47s
service/argocd-redis                              ClusterIP   10.233.17.198   <none>        6379/TCP                     47s
service/argocd-repo-server                        ClusterIP   10.233.1.6      <none>        8081/TCP,8084/TCP            47s
service/argocd-server                             ClusterIP   10.233.56.46    <none>        80/TCP,443/TCP               47s
service/argocd-server-metrics                     ClusterIP   10.233.35.44    <none>        8083/TCP                     47s

NAME                                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/argocd-applicationset-controller   1/1     1            1           47s
deployment.apps/argocd-dex-server                  1/1     1            1           47s
deployment.apps/argocd-notifications-controller    1/1     1            1           47s
deployment.apps/argocd-redis                       1/1     1            1           46s
deployment.apps/argocd-repo-server                 1/1     1            1           46s
deployment.apps/argocd-server                      1/1     1            1           46s

NAME                                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/argocd-applicationset-controller-c74dfc889   1         1         1       47s
replicaset.apps/argocd-dex-server-957c97b7d                  1         1         1       47s
replicaset.apps/argocd-notifications-controller-7df7749d5    1         1         1       46s
replicaset.apps/argocd-redis-cc756f67                        1         1         1       46s
replicaset.apps/argocd-repo-server-6959444795                1         1         1       46s
replicaset.apps/argocd-server-55dcfc7c76                     1         1         1       46s

NAME                                             READY   AGE
statefulset.apps/argocd-application-controller   1/1     46s

Argo CD Server Service
#

Convert ClusterIP to LoadBalancer Service
#

# Change the Argo CD Service service to type LoadBalancer
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

Verify Service Details
#

# List Argo CD serivce details
kubectl describe service argocd-server -n argocd
Shell Output:
# Shell output:
Name:                     argocd-server
Namespace:                argocd
Labels:                   app.kubernetes.io/component=server
                          app.kubernetes.io/name=argocd-server
                          app.kubernetes.io/part-of=argocd
Annotations:              metallb.universe.tf/ip-allocated-from-pool: primary
Selector:                 app.kubernetes.io/name=argocd-server
Type:                     LoadBalancer
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.233.56.46
IPs:                      10.233.56.46
LoadBalancer Ingress:     192.168.30.241
Port:                     http  80/TCP
TargetPort:               8080/TCP
NodePort:                 http  30132/TCP
Endpoints:                10.233.71.6:8080
Port:                     https  443/TCP
TargetPort:               8080/TCP
NodePort:                 https  31740/TCP
Endpoints:                10.233.71.6:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason        Age   From                Message
  ----    ------        ----  ----                -------
  Normal  IPAllocated   16s   metallb-controller  Assigned IP ["192.168.30.241"]
  Normal  nodeAssigned  16s   metallb-speaker     announcing from node "node4" with protocol "layer2"

DNS Entry
#

To access the Argo CD webinterface, create a DNS entry that points to the external IP provided by the LoadBalancer service:

# Create a DNS entry
192.168.30.241 argocd.jklug.work

Custom TLS Certificate Secret
#

Update the default self-signed TLS certificate with a custom TLS certificate:

# Update the TLS Kubernetes secret
kubectl create -n argocd secret tls argocd-server-tls \
  --cert=fullchain.pem \
  --key=privkey.pem

Argo CD Webinterface
#

# Access the webinterface: Via LoadBalancer service
https://argocd.jklug.work

Initial Admin Password
#

# Default user
admin

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

# Shell output:
ocL8NX0pPvB9V8Rn

Delete the Kubernetes secret after the password was retrieved:

# Delete the "argocd-initial-admin-secret" secret
kubectl delete secret argocd-initial-admin-secret



Argo CD CLI
#

Installation
#

Find the latest stable release:
https://github.com/argoproj/argo-cd/tags

# Install Argo CD CLI
curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/download/v2.11.2/argocd-linux-amd64

# Change permissions
chmod +x argocd

# Move the binary
sudo mv argocd /usr/local/bin/
# Verify the installation / check version
argocd version

# Shell output:
argocd version
argocd: v2.11.2+25f7504
  BuildDate: 2024-05-23T13:58:43Z
  GitCommit: 25f7504ecc198e7d7fdc055fdb83ae50eee5edd0
  GitTreeState: clean
  GoVersion: go1.21.10
  Compiler: gc
  Platform: linux/amd64
FATA[0000] Argo CD server address unspecified

Configuration
#

DNS Entry
#

Make sure the host where the Argo CD CLI is deploy can resolve the DNS name of the Argo CD server:

# Make sure a DNS entry for the Argo CD server is set
192.168.30.241 argocd.jklug.work

Argo CD Server Address
#

# Set the the Argo CD server address
argocd login argocd.jklug.work

# Shell output:
Username: admin
Password: # Enter the admin pw
'admin:login' logged in successfully
Context 'argocd.jklug.work' updated

GitLab Repository
#

DNS Entry
#

Make sure the server where the Argo CD CLI is running is able to resolve the DNS name of GitLab:

# Add DNS entry
192.168.70.4 gitlab.jklug.work

Known Hosts
#

GitLab Host Keys
#

Scan the host keys of GitLab:

# List the GitLab host keys
ssh-keyscan gitlab.jklug.work

# Shell output:
# gitlab.jklug.work:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6
gitlab.jklug.work ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHAQj15hmfv3OwTY3RAPwx1UlZ8p4qgtAHiZ9hngfJTSScO1kf40oL3Ek5NVKSGYZQ4w6ozBFHKO3l6tHn8nPeD7mUk/nW2U5w9yYpcRyFknn/u/Z0QreHAkI8fg6LI4n+2QYFF1rZbIemtCG33FozwrWKJ+/UsJYLnuQ2fenjcvkwPYx7NKV07RtQ3xYvkFVdWQGFJK8pLG9UcsanwZbH2nVPbv3i9KKI9xxWmJDh9JOoLhG6JipNN4Q4CoodfR9k9A2PY88dEykMInSGzFddOqbHLyISO8H1oJrofPzovPR07f+bDBK6iGIqRSW00k6mM0RFkPPo9tulLJ87DgB84jVrtYGp71wmV9PQ8jPB1uaDx5JtRNc0G+IWlIzTy8hFW9djELdTdQmfxeaCceyn1AmuXhpwZin64WTqztXj29s1olZ0+Uchh2FGpEjvlVqveeMmgAQkQezidqVHKKwinW1zdeSaBaZkS0JpLtxNpA86vBnhtYE8Z4CaQAvoQXU=
# gitlab.jklug.work:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6
gitlab.jklug.work ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPUxIo1glUPlmYJDbAOvHlRd/qjxdIEJCtBlcFLCMXECbRdp9IN/qePZdFtOnMWWVNvi8qy+7V8XbIFbzHoYwcg=
# gitlab.jklug.work:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6
gitlab.jklug.work ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH6GrjO8VqbiFMwtOfaEuKd3bV2vb7jH4r5Xl9PW1TFY
# gitlab.jklug.work:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6
# gitlab.jklug.work:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6

Add GitLab Host Keys to Argo CD
#

Open the Argo CD webinterface an add the GitLab host keys:

  • Go to: “Settings” > “Repository certificates and known hosts” > “ADD SSH KNOWN HOSTS”
  • Paste the GitLab SSH keys in the text box, one entry per line
  • Click “CREATE” to save the entry

SSH Key
#

Create a SSH key on the Argo CD CLI host and add they public key to GitLab:

# Create RSA Key: 4096 bit
ssh-keygen -t rsa -b 4096

Connect GitLab Repository:
#

Add the GitLab repository to Argo CD, this allows Argo CD to access and manage the repository using the specified SSH private key:

# Connect a GitLab repository via SSH
argocd repo add git@gitlab.jklug.work:root/k8s-example-project.git --ssh-private-key-path /home/debian/.ssh/id_rsa

# Connect a GitLab repository via SSH: Ignore insecure host key (For usage without GitLab host keys)
argocd repo add git@gitlab.jklug.work:root/k8s-example-project.git --ssh-private-key-path /home/debian/.ssh/id_rsa --insecure-ignore-host-key

# Shell output:
Repository 'git@gitlab.jklug.work:root/k8s-example-project.git' added

The GitLab repository should now be availble in the Argo CD webinterface under: “Settings” > “Repositories”

Create an Application in Argo CD
#

Create an Argo CD application named gitlab-k8s-example-project that points to the Kubernetes manifests in the specified GitLab repository and deploys them to the default namespace of the Kubernetes cluster.

CLI Version
#

# Deploy the GitLab repository
argocd app create gitlab-k8s-example-project \
  --repo git@gitlab.jklug.work:root/k8s-example-project.git \
  --path . \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace default

# Shell output:
application 'gitlab-k8s-example-project' created
  • --path . Helm chart location in the repository: root

  • --dest-server https://kubernetes.default.svc API server URL of the Kubernetes cluster where the application should be deployed (same Kubernetes cluster where Argo CD is running).

  • --dest-namespace default Defines the Kubernetes namespace

The application should now be available in the “Applications” section of the Argo CD webinterface.

Sync / Deploy the Application
#

# Deploy resources into the Kubernetes cluster
argocd app sync gitlab-k8s-example-project
Shell Output
# Shell output:
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME                         STATUS    HEALTH        HOOK  MESSAGE
2024-06-06T23:52:58+02:00   apps  Deployment     default  gitlab-k8s-example-project-helm-guestbook  OutOfSync  Missing
2024-06-06T23:52:58+02:00            Service     default  gitlab-k8s-example-project-helm-guestbook  OutOfSync  Missing
2024-06-06T23:52:59+02:00            Service     default  gitlab-k8s-example-project-helm-guestbook  OutOfSync  Missing              service/gitlab-k8s-example-project-helm-guestbook created
2024-06-06T23:52:59+02:00   apps  Deployment     default  gitlab-k8s-example-project-helm-guestbook  OutOfSync  Missing              deployment.apps/gitlab-k8s-example-project-helm-guestbook created
2024-06-06T23:52:59+02:00            Service     default  gitlab-k8s-example-project-helm-guestbook    Synced  Healthy                  service/gitlab-k8s-example-project-helm-guestbook created
2024-06-06T23:52:59+02:00   apps  Deployment     default  gitlab-k8s-example-project-helm-guestbook    Synced  Progressing              deployment.apps/gitlab-k8s-example-project-helm-guestbook created

Name:               argocd/gitlab-k8s-example-project
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://argocd.jklug.work/applications/gitlab-k8s-example-project
Source:
- Repo:             git@gitlab.jklug.work:root/k8s-example-project.git
  Target:
  Path:             .
SyncWindow:         Sync Allowed
Sync Policy:        Manual
Sync Status:        Synced to  (0b62635)
Health Status:      Progressing

Operation:          Sync
Sync Revision:      0b626353f37e785e15062ab757d8e7c96ae4bad5
Phase:              Succeeded
Start:              2024-06-06 23:52:58 +0200 CEST
Finished:           2024-06-06 23:52:59 +0200 CEST
Duration:           1s
Message:            successfully synced (all tasks run)

GROUP  KIND        NAMESPACE  NAME                                       STATUS  HEALTH       HOOK  MESSAGE
       Service     default    gitlab-k8s-example-project-helm-guestbook  Synced  Healthy            service/gitlab-k8s-example-project-helm-guestbook created
apps   Deployment  default    gitlab-k8s-example-project-helm-guestbook  Synced  Progressing        deployment.apps/gitlab-k8s-example-project-helm-guestbook created

Check Application Status
#

# List the application status
argocd app get gitlab-k8s-example-project

# Shell output:
Name:               argocd/gitlab-k8s-example-project
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://argocd.jklug.work/applications/gitlab-k8s-example-project
Source:
- Repo:             git@gitlab.jklug.work:root/k8s-example-project.git
  Target:
  Path:             .
SyncWindow:         Sync Allowed
Sync Policy:        Manual
Sync Status:        Synced to  (0b62635)
Health Status:      Healthy

GROUP  KIND        NAMESPACE  NAME                                       STATUS  HEALTH   HOOK  MESSAGE
       Service     default    gitlab-k8s-example-project-helm-guestbook  Synced  Healthy        service/gitlab-k8s-example-project-helm-guestbook created
apps   Deployment  default    gitlab-k8s-example-project-helm-guestbook  Synced  Healthy        deployment.apps/gitlab-k8s-example-project-helm-guestbook created

Verify the Kubernetes Deployment
#

# Verify the deployment
kubectl get all -n default

# Shell output:
NAME                                                             READY   STATUS    RESTARTS   AGE
pod/gitlab-k8s-example-project-helm-guestbook-867fb8b54c-tk7hh   1/1     Running   0          107s

NAME                                                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/gitlab-k8s-example-project-helm-guestbook   ClusterIP   10.233.21.63   <none>        80/TCP    107s
service/kubernetes                                  ClusterIP   10.233.0.1     <none>        443/TCP   6d2h

NAME                                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/gitlab-k8s-example-project-helm-guestbook   1/1     1            1           107s

NAME                                                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/gitlab-k8s-example-project-helm-guestbook-867fb8b54c   1         1         1       107s

Delete the Kubernetes Deployment
#

# Delete the deployment
argocd app delete gitlab-k8s-example-project

# Shell output:
Are you sure you want to delete 'gitlab-k8s-example-project' and all its resources? [y/n] # y
application 'gitlab-k8s-example-project' deleted

Links #

# Official Documentation: Installation
https://argo-cd.readthedocs.io/en/stable/getting_started/

# Official Documentation: TLS Certificates
https://argo-cd.readthedocs.io/en/stable/operator-manual/tls/
ArgoCD - This article is part of a series.
Part 1: This Article