Livraison continue et tests avec datree et Argo CD

Magazine
Marque
Linux Pratique
HS n°
Numéro
56
Mois de parution
février 2023
Spécialité(s)


Résumé

Tester les manifestes Kubernetes pour se prévenir des erreurs de configuration avant de déployer sur un cluster de production est l’une des étapes cruciales après les tests applicatifs. Automatiser ces tests à travers un pipeline GitLab-CI et assurer un Continuous Delivery via Argo CD est le scénario parfait pour la mise en œuvre d’une démarche DevOps/GitOps. C’est ce que nous allons découvrir dans cet article.


Body

Introduction

L’un des objectifs du DevOps est de limiter les possibilités d’erreurs humaines. Cependant, il s’avère que le développement logiciel est bien sujet à ce type d’erreurs. Les erreurs dans le cycle de vie des logiciels peuvent entraîner des défauts et des défaillances dans le système logiciel affecté.

L’assurance qualité est nécessaire pour éviter ces situations, réduire le nombre d’erreurs et améliorer la qualité d’un produit. Les tests logiciels constituent une technique d’assurance qualité essentielle qui exécute une série de validations et analyse les différents aspects du fonctionnement d’un logiciel.

Dans cet article, nous détaillerons en bref les différents tests à mettre en place dans un pipeline de CI/CD. Nous consacrons une grande partie aux tests des fichiers de configuration et de déploiement des ressources Kubernetes. L’outil que j’apprécie beaucoup en ce moment est datree. Un outil avec lequel on peut définir nos propres règles de contrôle de la qualité de nos fichiers de déploiement. La suite de l’article est également consacrée à l’automatisation de ces tests et au déploiement des ressources résultantes à travers l’outil de Continuous Delivery Argo CD. Toute la partie automatisation du CI/CD sera réalisée avec GitLab-CI. Bonne lecture !

1. Présentation des outils

Avant d’entrer dans le vif du sujet, passons en revue les différents outils qui seront exposés dans l’article.

1.1 GitLab-CI

GitLab-CI est une plateforme d’intégration et de déploiement continue, assurant la gestion complète d’un projet et le suivi du cycle de développement logiciel. Aujourd’hui, GitLab est considéré comme une plateforme de DevOps, car et à la différence d’autres outils et à l’instar de Jenkins, elle permet d’avoir une usine logicielle intégrée permettant de :

  • gérer le versionning du code source ;
  • mettre en place un workflow complet de gestion du projet ;
  • une implémentation intégrée des pipelines d’intégration et de déploiement continu ;
  • mettre à disposition des registry de gestion des livrables et des conteneurs ;
  • une intégration avec les plateformes d’orchestration de conteneurs et particulièrement Kubernetes.

La plateforme est accessible soit on-promise (en version communautaire ou commerciale), soit en SAAS via l’offre gitlab.com.

1.2 Kubernetes

Kubernetes est un système open source permettant d’automatiser le déploiement, la mise à l’échelle et la gestion des applications conteneurisées. Aujourd’hui, Kubernetes est considéré comme la plateforme idéale pour la création des environnements cloud native et c’est la raison pour laquelle les différents fournisseurs cloud publics disposent d’une offre managée des clusters Kubernetes.

1.3 datree

Comme évoqué à l’introduction de cet article, l’outil de test datree permet d’appliquer des règles et d’en définir d’autres pour assurer le respect des bonnes pratiques de déploiement des manifestes Kubernetes, mais aussi d’instaurer des règles universelles qui seront implémentées au sein des projets. L’outil datree s’intègre avec les outils de CI/CD pour contrôler l’état des fichiers de déploiement avant leur mise en production.

1.4 Argo CD

Argo CD est un outil de livraison continue, il est considéré comme étant l’outil incontournable pour la mise en œuvre du concept GitOps à l’instar de FluxCD. Le principe d’un tel outil est de reposer sur les changements au niveau de Git en tant que source unique de vérité pour déclencher le processus de déploiement des applications dans Kubernetes.

2. Provisionnement automatisé d’un cluster Kubernetes

Notre première étape dans cet article est de provisionner l’infrastructure pour déployer notre application. Kubernetes sera bien évidemment notre environnement cible pour la mise en place de notre projet de CI/CD.

L’installation de Kubernetes a été détaillée dans plusieurs articles de Linux Pratique. Cette fois, l’idée est d’automatiser le provisionnement d’un cluster Kubernetes à travers des manifestes Terraform.

Un projet permettant d’automatiser ce déploiement dans DigitalOcean est disponible via ce lien GitHub : https://github.com/hivenetes/k8s-bootstrapper.

2.1 Mise à disposition du projet d’amorçage de cluster

Commençons par cloner le dépôt contenant les fichiers Terraform de déploiement de Kubernetes :

$ git clone https://github.com/hivenetes/k8s-bootstrapper.git
Cloning into 'k8s-bootstrapper'...
remote: Enumerating objects: 270, done.
remote: Counting objects: 100% (270/270), done.
remote: Compressing objects: 100% (190/190), done.
remote: Total 270 (delta 136), reused 195 (delta 66), pack-reused 0
Receiving objects: 100% (270/270), 9.78 MiB | 6.14 MiB/s, done.
Resolving deltas: 100% (136/136), done.

Ensuite, il faut initialiser notre projet Terraform :

$ cd k8s-bootstrapper/infrastructure
$ terraform init
 
Initializing the backend...
 
Initializing provider plugins...
- Reusing previous version of digitalocean/digitalocean from the dependency lock file
- Installing digitalocean/digitalocean v2.22.3...
- Installed digitalocean/digitalocean v2.22.3 (signed by a HashiCorp partner, key ID F82037E524B9C0E8)
 
Terraform has been successfully initialized!

Paramétrons notre fichier de variable comme suit :

# DigitalOcean infrastructure setup terraform variables
# Note: `check variables.tf` more default values and modify as deemed fit
 
# DigitalOcean API token: begins with ""
do_token = "*******************************************"
# DigitalOcean cluster name
name = "kube-argo"
# DigitalOcean cluster region: default "ams3"
region = "ams3"
# DigitalOcean K8s version: default = "1.24.4-do.0"
k8s_version = "1.24.4-do.0"
# DigitalOcean HighAvailability Control Plane: default = true
ha = "false"
# DigitalOcean Container Registry(DOCR): default = "hivenetes-cr"
container_registry = ""

Vérifions ensuite les ressources qui seront déployées par Terraform :

$ terraform plan -var-file="variables.tfvars.example"
 
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
 
Terraform will perform the following actions:
 
  # digitalocean_kubernetes_cluster.cluster will be created
  + resource "digitalocean_kubernetes_cluster" "cluster" {
      + auto_upgrade   = false
      + cluster_subnet = (known after apply)
      + created_at     = (known after apply)
      + endpoint       = (known after apply)
      + ha             = false
      + id             = (known after apply)
      + ipv4_address   = (known after apply)
      + kube_config    = (sensitive value)
      + name           = "kube-argo"
      + region         = "ams3"
      + service_subnet = (known after apply)
      + status         = (known after apply)
      + surge_upgrade = false
      + updated_at     = (known after apply)
      + urn            = (known after apply)
      + version        = "1.24.4-do.0"
      + vpc_uuid       = (known after apply)
 
      + maintenance_policy {
          + day        = (known after apply)
          + duration   = (known after apply)
          + start_time = (known after apply)
        }
 
      + node_pool {
          + actual_node_count = (known after apply)
          + auto_scale        = true
          + id                = (known after apply)
          + max_nodes         = 5
          + min_nodes         = 3
          + name              = "island-pool"
          + node_count        = 3
          + nodes             = (known after apply)
          + size              = "s-1vcpu-1gb"
        }
    }
 
Plan: 1 to add, 0 to change, 0 to destroy.
 
Changes to Outputs:
  + cluster_id   = (known after apply)
+ cluster_name = "kube-argo"

2.2 Provisionning du cluster Kubernetes

Une seule commande permet d’installer notre cluster :

$ terraform apply -var-file="variables.tfvars.example" --auto-approve
 
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
 
Terraform will perform the following actions:
 
  # digitalocean_kubernetes_cluster.cluster will be created
  + resource "digitalocean_kubernetes_cluster" "cluster" {
      + auto_upgrade   = false
      + cluster_subnet = (known after apply)
      + created_at     = (known after apply)
      + endpoint       = (known after apply)
      + ha             = false
      + id             = (known after apply)
      + ipv4_address   = (known after apply)
      + kube_config    = (sensitive value)
      + name           = "kube-argo"
      + region         = "ams3"
      + service_subnet = (known after apply)
      + status         = (known after apply)
      + surge_upgrade = false
      + updated_at     = (known after apply)
      + urn            = (known after apply)
      + version        = "1.25.4-do.0"
      + vpc_uuid       = (known after apply)
 
      + maintenance_policy {
          + day        = (known after apply)
          + duration   = (known after apply)
          + start_time = (known after apply)
        }
 
      + node_pool {
          + actual_node_count = (known after apply)
          + auto_scale        = true
          + id                = (known after apply)
          + max_nodes         = 5
          + min_nodes         = 3
          + name              = "ams-pool"
          + node_count        = 3
          + nodes             = (known after apply)
          + size              = "s-1vcpu-2gb"
        }
    }
 
Plan: 1 to add, 0 to change, 0 to destroy.
 
Changes to Outputs:
  + cluster_id = (known after apply)
digitalocean_kubernetes_cluster.cluster: Creating...
digitalocean_kubernetes_cluster.cluster: Still creating... [10s elapsed]
digitalocean_kubernetes_cluster.cluster: Still creating... [20s elapsed]
digitalocean_kubernetes_cluster.cluster: Still creating... [30s elapsed]

Le provisionning reste une dizaine de minutes pour déployer le control plane et les workers du cluster.

Sur le tableau de bord de DigitalOcean, on aperçoit que le cluster est bel est bien là  (Figure 1) !

kubernetes-do-s

Figure 1

2.3 Accès au cluster Kubernetes

Pour pouvoir accéder au cluster Kubernetes et déployer des ressources, nous aurons besoin de deux étapes à mettre en place :

  • Installer le client kubectl :
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
 
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl
  • Importer le kubeconfig contenant le certificat d’accès au cluster :
$ mkdir kube

Puis, ajouter le contenu du kubeconfig dans le répertoire kube :

$ vim kube-argo-kubeconfig.yaml
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data:
******************************************************************
------ tronquée -------------------------
    server: https://f389d839-fcc6-4d71-a693-7b7022c52144.k8s.ondigitalocean.com
  name: do-ams3-kube-argo
contexts:
- context:
    cluster: do-ams3-kube-argo
    user: do-ams3-kube-argo-admin
  name: do-ams3-kube-argo
current-context: do-ams3-kube-argo
kind: Config
preferences: {}
users:
- name: do-ams3-kube-argo-admin
  user:
    token: **********************************************

Vérifions l’accès au cluster en affichant la liste des nœuds Kubernetes :

$ kubectl get nodes --kubeconfig=kube-argo-kubeconfig.yaml
NAME             STATUS   ROLES    AGE   VERSION
ams-pool-mtc2j   Ready    <none>   30m   v1.25.4
ams-pool-mtc2o   Ready    <none>   30m   v1.25.4
ams-pool-mtc2x   Ready    <none>   30m   v1.25.4

3. Déploiement d’Argo CD

L’outil Argo CD est déployable en ressources Kubernetes au sein de notre cluster provisionné précédemment. Les étapes de déploiement se résument par les deux commandes suivantes :

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

La première commande ajoute le namespace argocd. La deuxième commande créera les ressources nécessaires dans le namespace argocd.

Sans entrer dans les détails de l’architecture Argo CD pour le moment, voici les pods créés par les manifestes de déploiement :

$ kubectl get pods -n argocd --kubeconfig=kube-argo-kubeconfig.yaml
NAME                                                READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                     1/1     Running   0          4m16s
argocd-applicationset-controller-74575b6959-8n78n   1/1     Running   0          4m18s
argocd-dex-server-64897989f8-9l2rs                  1/1     Running   0          4m18s
argocd-notifications-controller-566bc99494-lwdj6    1/1     Running   0          4m18s
argocd-redis-79c755c747-fdjtl                       1/1     Running   0          4m17s
argocd-repo-server-bc9c646dc-79q74                  1/1     Running   0          4m17s
argocd-server-757fddb4d7-pbl4l                      1/1     Running   0          4m17s

On est presque arrivés ! Il nous faut l’URL d’accès à l’IHM Argo CD, pour cela il faut trouver le port exposé par le service Argo CD :

kubectl edit svc/argocd-server -n argocd –kubeconfig=kube-argo-kubeconfig.yaml

Il faut changer le type de service de ClusterIP à NodePort.

Affichons maintenant le port exposé :

$ kubectl get svc/argocd-server -n argocd --kubeconfig=kube-argo-kubeconfig.yaml
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
argocd-server   NodePort   10.245.144.58   <none>        80:30384/TCP,443:30098/TCP   13m

Le port est 30384.

Essayons de nous connecter : https://161.35.94.40:30384/ (Figure 2).

argo-dashboard-s

Figure 2

Pour s’authentifier et accéder à Argo CD (Figure 3), il faut récupérer le mot de passe depuis le secret Kubernetes, le nom d’utilisateur est admin :

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

argo-access-s

Figure 3

On revient dans la suite de l’article à Argo CD pour ajouter une application.

4. GitLab et les dépôts du projet

Notre projet est divisé en deux dépôts, le premier contient le code source de notre application et le second contient les manifestes de déploiement des ressources Kubernetes. En effet, c’est dans le second dépôt que l’outil de test datree réalisera les checks nécessaires pour s’assurer du bon respect des règles de déploiement mises en place.

Le rapport de test est généré lors du lancement du pipeline, ce dernier nous permettra d’inspecter si les règles ont été bien respectées, dans le cas contraire il est possible de suspendre le déploiement vers le cluster Kubernetes.

Argo CD n’intervient que lorsque le dépôt Git qui héberge les manifestes Kubernetes est modifié. Un commit dans ce dépôt permet à Argo de déployer les ressources. Dans notre article, le changement sera soit une nouvelle mise à jour de version d’image de notre application, soit un changement du nombre de réplicas du déploiement Kubernetes.

Argo CD, étant donné que c’est un outil de GitOps, va s’assurer que l’état souhaité dans le cluster Kubernetes est celui qui est décrit dans les fichiers manifestes du dépôt Git.

Le premier dépôt contenant le code de notre application exemple (code source en Node.js) est : https://gitlab.com/gitops_project/node-js-application.git.

Le dépôt contenant les ressources Kubernetes : https://gitlab.com/imejri/shark-app-deploy.git.

5. Intégration de l’outil datree et implémentation des règles de test

datree est un outil simple d’utilisation, en effet il s’appuie sur des règles prédéfinies pour éviter les erreurs de configuration des ressources Kubernetes créées dans les fichiers manifestes (yaml).

Il assure :

  • la compatibilité entre les manifestes créés et le schéma Kubernetes ;
  • l’instauration des bonnes pratiques et des politiques de déploiement et de configuration des ressources Kubernetes.

En mettant en œuvre le test avec datree, un déploiement peut être bloqué si une violation des règles a été détectée lors de l’exécution des tests automatisés dans un pipeline de CI/CD.

5.1 Installation de datree

Deux modes d’installation peuvent être établis avec datree :

  • Une installation indépendante du cluster Kubernetes, dans ce cas on installe datree comme binaire en local ou dans un runner GitLab (voir paragraphe 6) et qui sera invoqué lors du déroulement du pipeline.
  • La deuxième possibilité est d’installer datree directement au sein du cluster Kubernetes, dans ce cas datree assure le scan des différentes violations des règles mises en place à travers sa politique.

Pour installer en ligne de commandes datree :

$ curl https://get.datree.io | /bin/bash

Une fois installé, une simple commande permet de tester notre fichier de déploiement. Voici notre manifeste Kubernetes à tester :

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: shark
  name: shark
  namespace: shark-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: shark
  template:
    metadata:
      labels:
        app: shark
    spec:
      containers:
      - image: imejri.jfrog.io/front-docker-local/nodeapp
        name: shark

Lancement du test :

$ datree test shark-deployment.yaml
>> File: shark-deployment.yaml
 
[V] YAML validation
[V] Kubernetes schema validation
 
[X] Policy check
 
❌ Ensure each container image has a pinned (tag) version [1 occurrence]
    - metadata.name: shark (kind: Deployment)
      > key: spec.template.spec.containers.0.image (line: 19:16)
 
💡 Incorrect value for key `image` - specify an image version to avoid unpleasant "version surprises" in the future
 
❌ Ensure Deployment has more than one replica configured [1 occurrence]
    - metadata.name: shark (kind: Deployment)
      > key: spec.replicas (line: 9:13)
 
💡 Incorrect value for key `replicas` - running 2 or more replicas will increase the availability of the service
 
 
(Summary)
 
- Passing YAML validation: 1/1
 
- Passing Kubernetes (1.19.0) schema validation: 1/1
 
- Passing policy check: 0/1
 
+-----------------------------------+-----------------------+
| Enabled rules in policy "Default" | 14                    |
| Configs tested against policy     | 1                     |
| Total rules evaluated             | 14                    |
| Total rules skipped               | 0                     |
| Total rules failed                | 2                     |
| Total rules passed                | 12                    |
| See all rules in policy           | https://app.datree.io |

Le rapport de test est généré par datree, détectant des erreurs de configuration dans notre manifeste :

  • pas de tag (version) pour notre image Docker, dans ce cas, il faut spécifier la version d’image à déployer ;
  • le nombre de réplicas doit être supérieur à 1 pour assurer la disponibilité de l’application en cas d’erreurs ou de bugs du pod (conteneur) en exécution.

Le rapport affiche également le nombre des règles évaluées (14) ainsi que celles qui sont en échec (2).

5.2 Gestion des règles dans le tableau de bord datree

Pour l’activation ou la désactivation des règles datree dans le processus de tests, il faut créer un compte dur app.datree.io. Une fois le compte créé, il faut lier la commande datree à un token pour importer l’ensemble des règles déclarées dans le tableau de bord datree. Voici en figure 4 ce à quoi ressemble le tableau de bord datree.

datree-dashboard-s 1

Figure 4

Les règles sont définies par catégorie (Deprecation, Container, Networking, Workload…) et par statut (active/inactive).

Pour relier la commande datree à notre compte, il faut passer en paramètre le token :

$ datree config set token « ******************************* »

Pour récupérer le token, cliquez sur la barre latérale gauche sur Policies, puis sur le volet droit, cliquez sur le deuxième cadre en vert, indiquant la connexion de la CLI avec le compte datree.

datree-account-s

Figure 5

6. Analyse du pipeline CI/CD

L’approche CI/CD définit l’automatisation comme l’un des concepts fondamentaux du DevOps. GitLab CI est un outil très prisé des utilisateurs qui permet d’automatiser la compilation, le test et le déploiement d’applications. Le pipeline est la mise en œuvre de cette automatisation. En effet, lorsqu’un changement est détecté dans un référentiel Git, Gitlab CI exécute une compilation automatisée pour vérifier que les nouvelles modifications sont correctes. Il s’agit d’une série de phases (stage) de vérifications qui forment ce que l’on appelle un pipeline d’intégration continue. Un pipeline CI se compose généralement des étapes suivantes :

  • Extraction : GitLab CI détecte les changements dans le référentiel git et télécharge les nouvelles modifications (le dernier commit) ;
  • Compilation : GitLab CI exécute les commandes nécessaires pour compiler et créer le paquetage de l’application ;
  • Test : c’est la phase des tests d’application pour s’assurer que les dernières modifications sont correctes et ne présentent pas de bugs.

À toutes ces phases s’ajoute la partie pipeline CD (pipeline de livraison ou de déploiement), cette phase est fortement liée aux premières, car une fois que les précédentes phases s’exécutent sans échec, le pipeline pourra déployer l’application (artifact, image Docker...) dans les environnements cibles. La figure 6 résume le process de CI/CD dans GitLab CI.

gitlab-ci-cd-s

Figure 6

Dans GitLab CI, les pipelines sont créées dans un fichier .gitlab-ci.yaml à la racine du projet. Voilà à quoi ressemble notre pipeline de CI/CD :

workflow:
  rules:
  # Run pipeline only on master branch or in merge request
    - if: $CI_COMMIT_BRANCH != "master" && $CI_PIPELINE_SOURCE != "merge_request_event"    
      when: never
    - when: always
 
variables:
  BRANCH: master
  REGISTRY_IMAGE: "quay.io/imejri_issam/nodeapp"
  REGISTRY_USER: "imejri_issam"
  ARTIFACTORY_URL: "quay.io"
  REPLICAS_COUNT: 4
 
stages:                    # List of stages for jobs, and their order of execution
  - build                  # Build a nodeJs Application (based on Dockerfile)
  - datree-test            # Execute a test of manifests Kubernetes
  - update-manifests       # Update a manifests with a new image container and pushe into a
                           # gilalb repo

1

Build-and-push-image-to-Quay:
    stage: build
    tags:
      - digitalocean       # Runner is located in digitalocean cloud with docker installed
      - docker
      - linux
    before_script:
     - echo $JFROG_KEY | docker login $ARTIFACTORY_URL --username $REGISTRY_USER --password-stdin
    - export PACKAGE_JSON_VERSION=$(cat package.json | jq -r .version) # fetch version from 
                                                                       # package.json
    - export IMAGE_TAG=$PACKAGE_JSON_VERSION.$CI_PIPELINE_IID
    - echo $IMAGE_TAG > version.txt
    - cat version.txt
    script:
     - docker build -t $REGISTRY_IMAGE:$IMAGE_TAG .
     - docker push $REGISTRY_IMAGE:$IMAGE_TAG
    artifacts:
      untracked: false
      expire_in: "30 days"
      paths:
        - "version.txt"
 
 

2

Datree-test:
  stage: datree-test
  tags:
      - digitalocean
      - docker
      - linux
  before_script:
    - git clone git@gitlab.com:imejri/shark-app-deploy.git
    - cd shark-app-deploy/kube
  script:
    - curl https://get.datree.io | /bin/bash               # Install datree
    - datree config set token $DATREE_TOKEN                # set token to push report to my
                                                           # datree account
    - pwd
    - datree test *.yaml | tee datree.log.$CI_COMMIT_SHA   # Execute datree policy check
  artifacts:
    paths:
      - ./shark-app-deploy/kube/datree.log.*               # store log Artifact for the
                                                           # datree policy check
    expire_in: 30 days
    allow_failure: true
 
deploy-new-image-version:
  variables:

3

        IMAGE_TAG: '$(cat version.txt)'
  stage: update-manifests
  needs:
    - Build-and-push-image-to-Quay                     # to import the artifacts
  tags:
      - digitalocean
      - docker
      - linux
  before_script:
    - rm -rf shark-app-deploy
    - git clone git@gitlab.com:imejri/shark-app-deploy.git
    - export REGISTRY_IMAGE="imejri.jfrog.io\/front-docker-local\/nodeapp"
    - export REPLICAS_COUNT=$REPLICAS_COUNT
    - export VERSION=$(cat version.txt)
    - export IMAGE=$REGISTRY_IMAGE:$VERSION
    - echo $IMAGE
    - cd shark-app-deploy/kube
  script:
    - 'sed -i "/^\([[:space:]]*- image: \).*/s//\1$IMAGE/" shark-deployment.yaml'
    - 'sed -i "/^\([[:space:]]*replicas: \).*/s//\1$REPLICAS_COUNT/" shark-deployment.yaml'
    - cat shark-deployment.yaml
    - git add shark-deployment.yaml
    - git commit -m "update image to $VERSION and replicas count to $REPLICAS_COUNT"
    - git status
    - git push origin main    # push to https://gitlab.com/imejri/shark-app-deploy.git
                              # repository to synchronise with ArgoCD
  allow_failure: true
  when: manual

Notre pipeline est composé de 3 stages :

  1. Permet de builder l’image de conteneur de l’application et de pousser vers le registry Quay.
  2. Réaliser les tests datree sur les manifestes kubernetes (situés dans un dépôt différent de celui où réside le code source de l’application) avant qu’Argo CD procède au déploiement des ressources au sein du cluster.
  3. Finalement, c’est la phase de mise à jour des manifestes avec la nouvelle version précédemment créée. L’étape de déploiement n’apparaît pas dans ce pipeline de façon explicite, car c’est Argo CD qui va déclencher la création des ressources quand il détecte un changement dans le référentiel Git. La configuration du workflow Argo CD (GitOps) sera réalisée dans le paragraphe qui suit.

6.1 Les Runners GitLab

Un GitLab Runner est une instance sur laquelle s’exécutent un ou plusieurs jobs. Un Runner peut être une machine virtuelle Linux, Windows, macOs déployée en local ou dans le cloud. Un job GitLab CI peut également s’exécuter dans un conteneur Docker.

Le runner doit éventuellement contenir tous les paquets et les binaires nécessaires pour réaliser les tâches qui lui sont confiées. Dans notre projet, il faut installer les outils : Git, Docker, datree, jq.

Une fois que ces outils sont installés, il faut installer le démon gitlab-runner et joindre le runner à l’instance GitLab (gitlab.com).

6.2 Installation du Runner GitLab

J’ai provisionné une VM CentOS 9 dans mon espace cloud comme Runner GitLab.

L’installation des différents outils a été réalisée. Maintenant, commençons l’installation de l’agent runner.

La première étape consiste à télécharger le binaire runner pour Linux :

$ curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

Ajouter les permissions d’exécution :

$ chmod +x /usr/local/bin/gitlab-runner

Créer l’utilisateur gitLab-runner :

$ useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash

Installer et exécuter le service runner :

$ gitlab-runner install --user=gitlab-runner –working-directory=/home/gitlab-runner
$ sudo gitlab-runner start

Finalement, enregistrer le runner :

$ gitlab-runner register --url https://gitlab.com/ --registration-token $REGISTRATION_TOKEN

La variable $REGISTRATION_TOKEN contient le token permettant de s’authentifier auprès de GitLab lors de la phase de l’enregistrement. Le token est disponible dans Settings > CI/CD > Runners.

install-runner-s 0

Figure 7

7. Création du projet dans Argo CD et mise en place du GitOps

La dernière brique à mettre en place dans notre projet est Argo CD. L’installation d’Argo CD a été abordée dans le paragraphe 3. Décrivons le mode de fonctionnement d’Argo CD.

Argo CD est un outil de GitOps, il permet d’assurer une réconciliation entre le contenu d’un dépôt Git et les ressources déployées dans Kubernetes, il valide ce qu’on appelle en anglais le desired state.

Les composants d’Argo CD sont :

  • l’API Server : semblable à Kubernetes, Argo CD dispose d'un serveur d'API qui expose des API avec lesquelles d'autres systèmes peuvent interagir, comme l'interface utilisateur web, la CLI, les événements Argo et les systèmes CI/CD. Le serveur API est responsable des éléments suivants :
    • gestion des applications et rapports d'états ;
    • appel d'opérations d'applications (par exemple, synchronisation, restauration, actions définies par l'utilisateur), gestion des informations d'identification du référentiel et du cluster (stockées sous forme de secrets Kubernetes) ;
    • authentification et délégation d'authentification aux fournisseurs d'identité externes ;
    • application des politiques RBAC.
  • le Repository server : le serveur de référentiel est un service interne qui maintient un cache local du référentiel Git contenant les manifestes d'application. Ce service est appelé par d'autres services pour obtenir les manifestes Kubernetes. Il est chargé de générer et de renvoyer les manifestes Kubernetes à d'autres services lorsque les entrées suivantes sont définies :
    • URL du référentiel ;
    • révision (commit, tag, branche) ;
    • chemin vers d'application ;
    • paramètres spécifiques aux templates : parameters, environnements ksonnet, helm values.yaml ;
    • application controller : le contrôleur d'application observe en permanence l'état en live de l'application et effectue une comparaison avec l'état souhaité dans le référentiel Git. Chaque fois qu'il y a une dérive et qu'ils ne sont pas synchronisés, il essaiera de les réparer et de les faire correspondre à l'état souhaité. Une dernière de ses responsabilités est d'exécuter tous les hooks définis par l'utilisateur pour les événements du cycle de vie de l'application.

La figure 8 résume les différents composants d’Argo CD.

argo-architecture-s

Figure 8

7.1 Création du projet dans Argo CD

Pour qu’Argo CD réalise la livraison continue de notre application dans Kubernetes, il a besoin d’une ressource permettant de référencer le dépôt Git de notre projet. Argo CD dispose d’une ressource personnalisée CRD (Custom Resource Record) nommée Application, c’est dans cette ressource que nous allons définir notre application qui fait référence au repository git et au cluster Kubernetes.

La création de cette ressource est réalisable soit en ligne de commandes, soit via l’IHM Argo CD.

7.1.1 Création d’application en ligne de commandes

Il faut tout d’abord installer la ligne de commandes Argo CD :

$ curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
$ install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
$ rm argocd-linux-amd64

Puis, s’authentifier auprès d’Argo CD. Pour créer l’application, il faut se connecter à Argo CD en CLI :

$ argocd login 161.35.94.40:30384
WARNING: server certificate had error: x509: “Argo CD” certificate is not trusted. Proceed insecurely (y/n)? y
Username: admin
Password:
'admin:login' logged in successfully
Context '161.35.94.40:30384' updated

Création de l’application :

$ argocd app create shark-app \
--repo https://gitlab.com/imejri/shark-app-deploy.git \
--path kube \
--dest-server https://kubernetes.default.svc \
--dest-namespace shark
application 'shark-app' created

L’application est apparue dans le tableau de bord d’Argo CD (Figure 9).

argo-create-app-s

Figure 9

7.1.2 Création d’application par le tableau de bord

Une fois authentifié à Argo CD via l’IHM, cliquez sur l’onglet New app.

Remplir les champs nécessaires à la création de la ressource application (Figures 10 et 11) et à la fin, cliquez sur le bouton Create.

create-app-1-s

Figure 10

create-app-2-s

Figure 11

Bien sûr, le résultat final est le même que celui en ligne de commandes.

7.2 Synchronisation et mise place du GitOps

Maintenant qu’Argo CD réalisera le suivi des changements dans Git pour rapatrier les éventuelles modifications au niveau du cluster Kubernetes (c’est le principe même du GitOps), il est temps de lancer la synchronisation. Il faut savoir que lors de la création de notre application nous avons laissé le type de synchronisation à « manuel ». Cliquons sur l’onglet Sync en haut à gauche de la fenêtre (Figure 12), sur la fenêtre qui s’affiche, cliquez sur Synchronize.

synch-app-s

Figure 12

C’est magique ! La synchronisation a créé les ressources Kubernetes comme prévu (mon service et mon déploiement qui définit deux réplicas de mon application et donc deux Pods) (Figure 13).

synchro-result-s

Figure 13

Vérifions la création de ces ressources dans Kubernetes :

$ kubectl get all -n shark-app –kubeconfig=kube-argo-kubeconfig.yaml
 
NAME                         READY   STATUS    RESTARTS   AGE
pod/shark-8699659984-mfb62   1/1     Running   0          11m
pod/shark-8699659984-vwdvk   1/1     Running   0          11m
 
NAME                    TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/shark-service   NodePort   10.245.229.16   <none>        8080:30200/TCP   11m
 
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/shark   2/2     2            2           11m
 
NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/shark-8699659984   2         2         2       11m

En se connectant avec l’une des IP des nœuds du cluster (en production, il est recommandé de créer un service de type LoadBalancer ou de passer par un Ingress Controler) et en spécifiant le port 30200 (c’est le port exposé par le service), on pourra accéder à notre application et rencontrer notre requin (Figure 14) !

shark-app-access-s

Figure 14

8. Exécution du workflow complet

Le workflow complet se présente comme suit.

Un commit au sein du code source génère le lancement du pipeline CI/CD dans GitLab. Le pipeline exécute les jobs qui sont présents dans le fichier gitlab-ci.yaml comme indiqué dans le paragraphe 6. Le job Build-and-push-image-to-Quay permet de créer la nouvelle version d’image et de la pousser dans le registry Quay (Figure 15).

image-version-quay-s

Figure 15

À la suite de ce job, on réalise les tests datree et on exécute les mises à jour des manifestes yaml dans le dépôt référencé dans Argo CD. À partir de ce moment, Argo CD détectera les nouvelles modifications et synchronisera l’état du dépôt git avec l’état des ressources dans le cluster Kubernetes.

Sans oublier que le job de test datree génère un artifact contenant le rapport de test, il est téléchargeable en cliquant sur le nom du job dans le pipeline, puis dans le volet droit on choisit soit Download, soit Browse pour accéder au rapport de test (Figure 16).

datree-artifact-s

Figure 16

Les différents jobs dans le pipeline de GitLab sont représentés en Figure 17.

listes-jobs-s

Figure 17

On finalise l’article avec une illustration d’un workflow complet en Figure 18.

workflow-complet-s

Figure 18

Conclusion

Implémenter des outils de tests et des outils de livraison continue dans le cadre d’un projet assure la fiabilité dans le cycle de développement logiciel et permet de bénéficier d’une accélération lors des étapes de déploiement en production. Des outils comme Argo CD ou datree, qui ont été détaillés dans cet article ont leur valeur ajoutée lorsqu’on peut les intégrer dans des pipelines de CI/CD et standardiser leur utilisation sur différents projets.

Références



Article rédigé par

Par le(s) même(s) auteur(s)

Builder des images de conteneurs

Magazine
Marque
Linux Pratique
Numéro
142
Mois de parution
mars 2024
Spécialité(s)
Résumé

La technologie des conteneurs a révolutionné le monde du développement et de la livraison logicielle en offrant une manière isolée, réplicable et éphémère de déployer des applications et leurs dépendances. Au cœur de cette révolution se trouve la création des images de conteneurs, qui sont essentiellement des instantanés de l'application et de son environnement d'exécution. Divers outils et technologies ont vu le jour pour faciliter et optimiser la création de ces images. Dans cet article, nous explorerons les différentes technologies dominantes de création d'images, telles que Docker, Podman, Buildah et Buildpacks, et nous plongerons dans leurs spécificités, et mettrons en pratique le build des images et la création des applications conteneurisées.

Gestion des releases avec JFrog Artifactory et Nexus

Magazine
Marque
GNU/Linux Magazine
Numéro
268
Mois de parution
mars 2024
Spécialité(s)
Résumé

La gestion des artefacts est importante pour garantir la cohérence et la traçabilité des composants logiciels au sein d'un projet. Dans cet article, nous vous présenterons deux plateformes populaires de gestion d’artefacts : JFrog Artifactory et Nexus. Nous aborderons leurs concepts clés, l'installation et la mise en œuvre, ainsi que l'intégration avec les pipelines de CI/CD. Enfin, nous discuterons des avantages de l'utilisation de ces plateformes dans un environnement DevOps.

Allier tests et DevSecOps : la route vers une application sécurisée

Magazine
Marque
GNU/Linux Magazine
Numéro
266
Mois de parution
novembre 2023
Spécialité(s)
Résumé

Depuis la rigidité du modèle Waterfall, où la sécurité des applications était souvent une réflexion tardive post-développement, l'évolution s'est dirigée vers la méthodologie Agile. Aujourd'hui, non seulement la sécurité des applications est intégrée dès le départ à travers les tests, mais elle se fond également dans des approches plus avancées comme le DevSecOps et l'intégration continue, reflétant une transition vers une conception sécurisée, agile et automatisée.

Les derniers articles Premiums

Les derniers articles Premium

La place de l’Intelligence Artificielle dans les entreprises

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

L’intelligence artificielle est en train de redéfinir le paysage professionnel. De l’automatisation des tâches répétitives à la cybersécurité, en passant par l’analyse des données, l’IA s’immisce dans tous les aspects de l’entreprise moderne. Toutefois, cette révolution technologique soulève des questions éthiques et sociétales, notamment sur l’avenir des emplois. Cet article se penche sur l’évolution de l’IA, ses applications variées, et les enjeux qu’elle engendre dans le monde du travail.

Petit guide d’outils open source pour le télétravail

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Ah le Covid ! Si en cette période de nombreux cas resurgissent, ce n’est rien comparé aux vagues que nous avons connues en 2020 et 2021. Ce fléau a contraint une large partie de la population à faire ce que tout le monde connaît sous le nom de télétravail. Nous avons dû changer nos habitudes et avons dû apprendre à utiliser de nombreux outils collaboratifs, de visioconférence, etc., dont tout le monde n’était pas habitué. Dans cet article, nous passons en revue quelques outils open source utiles pour le travail à la maison. En effet, pour les adeptes du costume en haut et du pyjama en bas, la communauté open source s’est démenée pour proposer des alternatives aux outils propriétaires et payants.

Sécurisez vos applications web : comment Symfony vous protège des menaces courantes

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Les frameworks tels que Symfony ont bouleversé le développement web en apportant une structure solide et des outils performants. Malgré ces qualités, nous pouvons découvrir d’innombrables vulnérabilités. Cet article met le doigt sur les failles de sécurité les plus fréquentes qui affectent même les environnements les plus robustes. De l’injection de requêtes à distance à l’exécution de scripts malveillants, découvrez comment ces failles peuvent mettre en péril vos applications et, surtout, comment vous en prémunir.

Bash des temps modernes

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Les scripts Shell, et Bash spécifiquement, demeurent un standard, de facto, de notre industrie. Ils forment un composant primordial de toute distribution Linux, mais c’est aussi un outil de prédilection pour implémenter de nombreuses tâches d’automatisation, en particulier dans le « Cloud », par eux-mêmes ou conjointement à des solutions telles que Ansible. Pour toutes ces raisons et bien d’autres encore, savoir les concevoir de manière robuste et idempotente est crucial.

Les listes de lecture

8 article(s) - ajoutée le 01/07/2020
Découvrez notre sélection d'articles pour faire vos premiers pas avec les conteneurs, apprendre à les configurer et les utiliser au quotidien.
11 article(s) - ajoutée le 02/07/2020
Si vous recherchez quels sont les outils du DevOps et comment les utiliser, cette liste est faite pour vous.
8 article(s) - ajoutée le 02/07/2020
Il est essentiel d'effectuer des sauvegardes régulières de son travail pour éviter de perdre toutes ses données bêtement. De nombreux outils sont disponibles pour nous assister dans cette tâche.
Voir les 60 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous