Skip to main content

Argo CD with GitLab CI, Part 4: Argo CD Configuration (Add GitLab Host Keys, GitLab Registry Kubernetes Secret, Connect GitLab Repository, Deploy Argo CD Application)

1158 words·
Argo CD Argo CD CLI GitLab GitLab CI CI Pipeline Kubernetes CoreDNS Python Flask
Table of Contents
ArgoCD - This article is part of a series.
Part 4: This Article



Kubernetes Cluster Requirements
#

Create Namespace for the Flask-App
#

Create a namespace for the deployment of the Python Flask web application, the same namespace must be defined in the Argo CD application manifest:

# Create a namespace
kubectl create namespace flask-app



GitLab Host Keys
#

Scan GitLab Host Keys
#

From the node where the Argo CLI is installed (or any other host that can resolve the GitLab DNS name), 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.7
gitlab.jklug.work ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPUxIo1glUPlmYJDbAOvHlRd/qjxdIEJCtBlcFLCMXECbRdp9IN/qePZdFtOnMWWVNvi8qy+7V8XbIFbzHoYwcg=
# gitlab.jklug.work:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.7
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.7
gitlab.jklug.work ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH6GrjO8VqbiFMwtOfaEuKd3bV2vb7jH4r5Xl9PW1TFY
# gitlab.jklug.work:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.7
# gitlab.jklug.work:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.7

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”

  • Click “ADD SSH KNOWN HOSTS”

  • Paste the GitLab SSH keys in the text box, one entry per line, it should look like this:

gitlab.jklug.work ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPUxIo1glUPlmYJDbAOvHlRd/qjxdIEJCtBlcFLCMXECbRdp9IN/qePZdFtOnMWWVNvi8qy+7V8XbIFbzHoYwcg=
gitlab.jklug.work ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHAQj15hmfv3OwTY3RAPwx1UlZ8p4qgtAHiZ9hngfJTSScO1kf40oL3Ek5NVKSGYZQ4w6ozBFHKO3l6tHn8nPeD7mUk/nW2U5w9yYpcRyFknn/u/Z0QreHAkI8fg6LI4n+2QYFF1rZbIemtCG33FozwrWKJ+/UsJYLnuQ2fenjcvkwPYx7NKV07RtQ3xYvkFVdWQGFJK8pLG9UcsanwZbH2nVPbv3i9KKI9xxWmJDh9JOoLhG6JipNN4Q4CoodfR9k9A2PY88dEykMInSGzFddOqbHLyISO8H1oJrofPzovPR07f+bDBK6iGIqRSW00k6mM0RFkPPo9tulLJ87DgB84jVrtYGp71wmV9PQ8jPB1uaDx5JtRNc0G+IWlIzTy8hFW9djELdTdQmfxeaCceyn1AmuXhpwZin64WTqztXj29s1olZ0+Uchh2FGpEjvlVqveeMmgAQkQezidqVHKKwinW1zdeSaBaZkS0JpLtxNpA86vBnhtYE8Z4CaQAvoQXU=
gitlab.jklug.work ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH6GrjO8VqbiFMwtOfaEuKd3bV2vb7jH4r5Xl9PW1TFY
  • Click “CREATE” to save the entry



GitLab Deploy Key: For Argo CD
#

Create SSH Key Pair
#

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

# Create SSH RSA key pair: 4096 bit
ssh-keygen -t rsa -b 4096 -f argocd_repo_key
# Copy the public SSH key
cat argocd_repo_key.pub

Add Public SSH Key to GitLab Repository
#

Add the public SSH key to the GitLab repository with the Helm chart:

  • Go to: (Project) “Settings” > “Repository”

  • Expand the “Deploy keys” section

  • Click “Add new key”

  • Paste the value of the argocd_repo_key.pub public SSH key

  • Define a title like “argocd_repo_key”

  • Click “Add key”



GitLab Project Access Token
#

Create Project Access Token
#

Create a “Project Access Token” in the flask-app-code project used by Argo CD to access the GitLab Registry of the project:

  • Go to: (Project) “Settings” > “Access Tokens”

  • Click “Add new token”

  • Define a token name like registry-token

  • Define the scope of the token: “read_registry” Grants read-only access to container registry images on private projects.

  • Click “Create project access token”

  • Copy the project access token, it should look like this: glpat-Fkm7_j_1Bo4158eyETjV


Copy Project Token User
#

For each project token, a bot user is created. Copy the name of the user:

  • Go to: (Project) “Manage” > “Members”

  • Copy the registry-token username from the members section, it should looks like this:

# Copy project member "registry-token"
project_29_bot_39e3a29271544817376626f4e17b4d50

Create GitLab Registry Secret
#

# Create a secret with the GitLab access token
kubectl create secret docker-registry gitlab-registry-secret \
--docker-server=gitlab-registry.jklug.work \
--docker-username=project_29_bot_39e3a29271544817376626f4e17b4d50 \
--docker-password=glpat-Fkm7_j_1Bo4158eyETjV \
--docker-email=juergen@jklug.work \
--namespace=flask-app

# Shell output:
secret/gitlab-registry-secret created

Verify the Secret
#

# List secret details
kubectl get secret gitlab-registry-secret -o yaml -n flask-app

# Shell output:
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyJnaXRsYWItcmVnaXN0cnkuamtsdWcud29yayI6eyJ1c2VybmFtZSI6InByb2plY3RfMjlfYm90XzBmODgwY2FjN2YwYjE0YjU4ZTFhMjk4MzM3NzRlYjQxIiwicGFzc3dvcmQiOiJnbHBhdC1BS1NGeENSWkJtY19FTUpabXcyVyIsImVtYWlsIjoianVlcmdlbkBqa2x1Zy53b3JrIiwiYXV0aCI6ImNISnZhbVZqZEY4eU9WOWliM1JmTUdZNE9EQmpZV00zWmpCaU1UUmlOVGhsTVdFeU9UZ3pNemMzTkdWaU5ERTZaMnh3WVhRdFFVdFRSbmhEVWxwQ2JXTmZSVTFLV20xM01sYz0ifX19
kind: Secret
metadata:
  creationTimestamp: "2024-12-06T11:39:23Z"
  name: gitlab-registry-secret
  namespace: flask-app
  resourceVersion: "13851"
  uid: 598f2c8b-5325-4f49-a448-1290efffa3ba
type: kubernetes.io/dockerconfigjson



Argo CD Setup
#

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: Define path to private SSH key "argocd_repo_key"
argocd repo add git@gitlab.jklug.work:python/flask-app-helm.git --ssh-private-key-path argocd_repo_key

# Shell output:
Repository 'git@gitlab.jklug.work:python/flask-app-helm.git' added

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


Verify GitLab Repository
#

# List connected GitLab repositories
argocd repo list

# Shell output:
TYPE  NAME  REPO                                             INSECURE  OCI    LFS    CREDS  STATUS      MESSAGE  PROJECT
git         git@gitlab.jklug.work:python/flask-app-helm.git  false     false  false  false  Successful

Create an Argo CD Application
#

Manifest Version
#

Create an Argo CD application named flask-web-app that points to the Kubernetes manifests in the specified GitLab repository and deploys them to the default namespace of the Kubernetes cluster.

# Create a manifest for the application
vi flask-web-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: flask-web-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: git@gitlab.jklug.work:python/flask-app-helm.git
    targetRevision: main
    path: helm-chart
  destination:
    server: https://kubernetes.default.svc
    namespace: flask-app
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
# Apply the application manifest
kubectl apply -f flask-web-app.yaml

# Shell output:
application.argoproj.io/flask-web-app created

CLI Version
#

# Create Argi CD application
argocd app create flask-web-app \
  --project default \
  --repo git@gitlab.jklug.work:python/flask-app-helm.git \
  --revision main \
  --path helm-chart \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace flask-app \
  --sync-policy automated \
  --auto-prune \
  --self-heal

# Shell output:
application 'flask-web-app' created

Explanation
#

  • flask-web-app Name of the application.

  • --project default Specifies the built-in project that exists in every ArgoCD installation.

  • --repo: The Git repository URL.

  • --revision main: The branch or commit to track.

  • --path The sub-path within the repository containing the manifest/chart.

  • --dest-server https://kubernetes.default.svc The destination cluster.

  • --dest-namespace The namespace where the application will be deployed.

  • --sync-policy automated Enables automated synchronization.

  • --auto-prune Ensures resources that are removed from the Git repository are pruned.

  • --self-heal ArgoCD automatically corrects any differences by applying the desired state from the Git repository to the cluster.


Verify the Argo CD Application
#

# Verify Argo CD application
argocd app get flask-web-app

# Shell output:
Name:               argocd/flask-web-app
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          flask-app
URL:                https://argocd.jklug.work/applications/flask-web-app
Source:
- Repo:             git@gitlab.jklug.work:python/flask-app-helm.git
  Target:           main
  Path:             helm-chart
SyncWindow:         Sync Allowed
Sync Policy:        Automated (Prune)
Sync Status:        Synced to main (1f90590)
Health Status:      Progressing

GROUP  KIND        NAMESPACE  NAME       STATUS  HEALTH       HOOK  MESSAGE
       Service     flask-app  flask-app  Synced  Healthy            service/flask-app created
apps   Deployment  flask-app  flask-app  Synced  Progressing        deployment.apps/flask-app created

Very Flask Web App Deployment
#

# List resources in the "flask-app" namespace
kubectl get all -n flask-app

# Shell output:
NAME                             READY   STATUS    RESTARTS   AGE
pod/flask-app-5b5946578f-lpgqf   1/1     Running   0          17s
pod/flask-app-5b5946578f-p7rvx   1/1     Running   0          17s

NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/flask-app   ClusterIP   10.108.139.47   <none>        8080/TCP   17s

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/flask-app   2/2     2            2           17s

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/flask-app-5b5946578f   2         2         2       17s
# Create a port forwarding
kubectl port-forward service/flask-app 8080:8080 -n flask-app

# Curl the Flask application (in a new shell)
curl http://localhost:8080

# Shell output:
Hi there from Python Flask application

Manually Trigger Synchronization
#

# Manually trigger the synchronization of the application with the Git repository
app sync flask-web-app --prunene

# Shell output:
TIMESTAMP                  GROUP        KIND   NAMESPACE                  NAME    STATUS   HEALTH        HOOK  MESSAGE
2024-12-07T17:35:31+00:00            Service   flask-app             flask-app    Synced  Healthy
2024-12-07T17:35:31+00:00   apps  Deployment   flask-app             flask-app    Synced  Healthy
2024-12-07T17:35:32+00:00            Service   flask-app             flask-app    Synced  Healthy              service/flask-app unchanged
2024-12-07T17:35:32+00:00   apps  Deployment   flask-app             flask-app    Synced  Healthy              deployment.apps/flask-app configured
2024-12-07T17:35:32+00:00   apps  Deployment   flask-app             flask-app  OutOfSync  Progressing              deployment.apps/flask-app configured

Name:               argocd/flask-web-app
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          flask-app
URL:                https://argocd.jklug.work/applications/flask-web-app
Source:
- Repo:             git@gitlab.jklug.work:python/flask-app-helm.git
  Target:           main
  Path:             helm-chart
SyncWindow:         Sync Allowed
Sync Policy:        Automated (Prune)
Sync Status:        Synced to main (c65793d)
Health Status:      Progressing

Operation:          Sync
Sync Revision:      c65793dd73e4951cf680c1a6c3d3e9adb06a0c0f
Phase:              Succeeded
Start:              2024-12-07 17:35:31 +0000 UTC
Finished:           2024-12-07 17:35:32 +0000 UTC
Duration:           1s
Message:            successfully synced (all tasks run)

GROUP  KIND        NAMESPACE  NAME       STATUS  HEALTH       HOOK  MESSAGE
       Service     flask-app  flask-app  Synced  Healthy            service/flask-app unchanged
apps   Deployment  flask-app  flask-app  Synced  Progressing        deployment.apps/flask-app configured

Delete Argo CD Application
#

# Delete the Argo CD application
argocd app delete flask-web-app
ArgoCD - This article is part of a series.
Part 4: This Article