La livraison d'applications moderne exige non seulement de la rapidité, mais aussi de la fiabilité. Dans l'univers de Kubernetes, les déploiements sans interruption ne sont plus un luxe ; ils constituent une exigence de base pour les systèmes de production. En combinant la robustesse de GitLab CI pour les processus de compilation et de test avec la puissance déclarative de ArgoCD pour l'orchestration des déploiements, vous pouvez créer un pipeline piloté par GitOps qui garantit la disponibilité de vos services pendant les mises à jour.
Pourquoi combiner GitLab CI et ArgoCD ?
Les outils CI/CD traditionnels gèrent souvent la compilation et le déploiement dans une étape unique et monolithique. Bien qu'efficace, cette approche peut entraîner des problèmes complexes de gestion d'état. La séparation des responsabilités offre des avantages distincts :
- GitLab CI : Excelle dans la compilation, les tests unitaires, la construction d'images et la poussée d'artefacts vers un registre de conteneurs.
- ArgoCD : Spécialisé dans la synchronisation de l'état souhaité défini dans votre dépôt Git avec l'état en direct de votre cluster Kubernetes.
Cette séparation vous permet de découpler le « comment construire » du « comment déployer », offrant ainsi des pistes d'audit plus claires et des mécanismes de retour arrière plus simples.
Configuration du pipeline GitLab CI
D'abord, définissons le flux de travail GitLab CI. L'objectif principal ici est de produire une image conteneur et de mettre à jour les manifestes Kubernetes dans votre dépôt Git. C'est le principe fondamental de GitOps : le dépôt Git est la source unique de vérité.
stages:
- build
- push
- deploy
variables:
REGISTRY_IMAGE: $CI_REGISTRY_IMAGE
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $REGISTRY_IMAGE:$CI_COMMIT_SHA .
only:
- main
push:
stage: push
image: alpine:latest
script:
- apk add --no-cache git
- git config --global user.email "gitlab-ci-token@gl-sa-pipeline"
- git config --global user.name "GitLab CI"
- echo "$CI_REGISTRY_PASSWORD" > ~/.netrc
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $REGISTRY_IMAGE:$CI_COMMIT_SHA
update-manifests:
stage: deploy
image: alpine:latest
script:
- apk add --no-cache git
- git config --global user.email "gitlab-ci-token@gl-sa-pipeline"
- git config --global user.name "GitLab CI"
- cd k8s-manifests
- sed -i 's|image: .*$|image: '$REGISTRY_IMAGE':$CI_COMMIT_SHA|' deployment.yaml
- git add .
- git commit -m "Update image to $CI_COMMIT_SHA" || true
- git push origin main
only:
- main
after_script:
- echo "Manifests updated. ArgoCD will now detect the change."
Remarquez le travail update-manifests. Il ne déploie pas directement vers Kubernetes. Au lieu de cela, il met à jour le fichier deployment.yaml dans le dépôt avec la nouvelle étiquette d'image. Cela déclenche ArgoCD pour qu'il détecte le changement dans le dépôt Git.
Configuration d'ArgoCD pour GitOps
ArgoCD fonctionne comme un contrôleur dans votre cluster Kubernetes. Il surveille en continu votre dépôt Git. Lorsqu'il détecte un changement dans les manifestes (comme la mise à jour de l'étiquette d'image par GitLab CI), il synchronise automatiquement le cluster avec le nouvel état.
Pour garantir une interruption nulle, la stratégie de déploiement Kubernetes doit être définie sur RollingUpdate. C'est la stratégie par défaut, mais il est bon d'être explicite.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: registry.gitlab.com/group/my-app:latest
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
Configuration clé pour une interruption nulle :
maxUnavailable: 0: Assure que plus de zéro pods ne sont pas disponibles pendant la mise à jour. Cela garantit qu'au moinsreplicas(3 dans ce cas) pods sont toujours en cours d'exécution et prêts à servir le trafic.readinessProbe: ArgoCD et Kubernetes s'appuient sur cette sonde pour déterminer si un pod est « Prêt ». Un nouveau pod ne sera considéré comme sain et son IP ajoutée aux Endpoints du Service qu'après le passage de cette sonde. Cela empêche le trafic d'être routé vers des pods qui ne sont pas entièrement initialisés.
Le flux sans interruption
Voici le processus étape par étape lorsqu'un développeur fusionne du code dans la branche main :
- Déclencheur : Le pipeline GitLab CI démarre.
- Compilation & Poussée : Une nouvelle image Docker est compilée et poussée vers le registre avec une étiquette SHA de commit unique.
- Mise à jour des manifestes : Le travail CI met à jour le
deployment.yamldans le dépôt Git pour référencer la nouvelle étiquette d'image et le committe. - Synchronisation ArgoCD : ArgoCD détecte le changement de commit Git. Il compare l'état souhaité (nouvelle image) avec l'état en direct (ancienne image).
- Mise à jour progressive : ArgoCD applique le nouveau manifeste à Kubernetes.
- Kubernetes crée un nouveau ReplicaSet avec la nouvelle image.
- Les nouveaux pods démarrent et passent leurs sondes de préparation.
- Seulement après que les nouveaux pods sont prêts, Kubernetes commence à terminer les anciens pods.
- Le LoadBalancer/Service continue de router le trafic vers les pods sains tout au long de cette transition.
- Terminaison : Tous les nouveaux pods sont en cours d'exécution, les anciens pods sont terminés, et l'application est entièrement mise à jour sans interruption.
Meilleures pratiques pour la résilience
- Utiliser la version sémantique pour les images : Bien que les SHA de commit soient précis, l'utilisation d'étiquettes sémantiques (par exemple,
v1.2.0) facilite les retours arrière dans l'interface d'ArgoCD. Vous pouvez simplement annuler le commit Git pour changer l'étiquette d'image vers la version stable précédente. - Les vérifications de santé sont critiques : Assurez-vous que vos
livenessProbeetreadinessProbesont correctement configurés. Si un nouveau pod échoue à sa vérification de préparation, ArgoCD marquera la synchronisation comme non saine, vous permettant d'intervenir avant que les anciens pods ne soient supprimés. - Fenêtres de synchronisation ArgoCD : Pour un contrôle plus strict, configurez les fenêtres de synchronisation ArgoCD pour empêcher les déploiements automatiques pendant les heures critiques d'activité.
- Surveillance : Intégrez les métriques ArgoCD avec Prometheus/Grafana pour surveiller l'état de synchronisation, la santé et la durée des déploiements.
Conclusion
En exploitant GitLab CI pour l'automatisation de la compilation et ArgoCD pour le déploiement déclaratif, vous créez un pipeline CI/CD robuste, auditable et résilient. La clé d'une interruption nulle ne réside pas dans les outils eux-mêmes, mais dans la configuration correcte des stratégies de mise à jour progressive Kubernetes et des sondes de santé rigoureuses. Cette approche GitOps garantit que vos déploiements sont prévisibles, réversibles et toujours synchronisés avec votre source de vérité : votre dépôt Git.