Utiliser Git pour opérer sur Kubernetes avec ArgoCD

Utiliser Git pour opérer sur Kubernetes avec ArgoCD

Sommaire

Présentation d’ArgoCD

Argo CD est un outil de déploiement continu (CD) pour Kubernetes basé sur le concept de GitOps. Il permet de synchroniser automatiquement l’état de votre cluster avec la configuration déclarative stockée dans un dépôt Git. Grâce à son interface web, sa CLI et son API, Argo CD offre un suivi visuel des applications, la possibilité de revenir à un état antérieur et un contrôle précis des mises à jour. Il facilite ainsi des déploiements fiables, traçables et reproductibles, tout en s’intégrant parfaitement dans les workflows DevOps modernes.

Pré-requis

  • Un cluster Kubernetes (voir cet article)
  • Wireguard (recommandé pour coller à l’article)
  • Des connaissances de base de git
  • Un compte Gitlab

Installation d’ArgoCD

Pour plus de détails, consultez la documentation officielle : Getting Started – Argo CD

# Créer un namespace dédié à Argo CD
kubectl create namespace argocd

# Déployer Argo CD avec les manifestes officiels
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Une fois ces commandes exécutées, Argo CD sera installé dans le namespace argocd et prêt à être configuré.

Fixer l’adresse IP de l’interface de ArgoCD dans Wireguard

kubectl config set-context --current --namespace=argocd
kubectl patch svc argocd-server -n argocd -p '{"spec": {"externalIPs": ["10.0.0.1"]}}'

Maintenant, l’adresse IP de l’interface de ArgoCD est 10.0.0.1 dans le réseau Wireguard

Création Dépôt Git (ici, Gitlab)

L’arborescence ressemblera à ceci :

.
├── blog                         # Dossier contenant les manifestes Kubernetes pour l'application "blog"
│   ├── blog-app.yml             # Définition de l'application ou du chart Helm (si utilisé) : image, variables, configuration globale
│   ├── blog-deployment.yml      # Manifeste Kubernetes pour le Deployment : pods, replicas, stratégie de déploiement, etc.
│   ├── blog-ingress.yml         # Manifeste Kubernetes pour l'Ingress : règles de routage HTTP/HTTPS vers le service blog
│   └── blog-service.yml         # Manifeste Kubernetes pour le Service : expose le déploiement interne/externe (ClusterIP, NodePort ou LoadBalancer)
└── infra                        # Dossier contenant les manifestes liés à l'infrastructure et à la configuration globale du cluster
    ├── namespaces               # Dossier pour organiser les namespaces Kubernetes
    │   └── blog-ns.yml          # Manifeste pour la création du namespace "blog" (isolation des ressources)
    └── root-app.yml             # Définition de l'application racine ou composant global pour gérer les dépendances et la configuration cluster-wide

Séparation logique

Le dossier blog contient uniquement les ressources propres à l’application blog.

Le dossier infra gère les éléments d’infrastructure (comme les namespaces et autres ressources transverses) en mode App of Apps.

Évolutivité

Cette structure est conçue pour s’adapter facilement si d’autres applications doivent être ajoutées (par ex. un dossier shop/ pour une app e-commerce).

Ajout du dépôt dans les dépôts argoCD

argocd login 10.0.0.1
argocd repo add https://gitlab.com/{{PROJECT_NAME}}/gitops.git \
  --username {{IDENTIFIANT}} --password {{ACCESS_TOKEN}}> \
  --name gitops-gitlab

⚠️ Ceci ajoute le secret dans le namespace argocd. C’est important pour après

Le pattern App of Apps

Le pattern App of Apps est une approche d’organisation et de déploiement dans Kubernetes, principalement utilisée avec Argo CD.

Il consiste à avoir une application « racine » (l’App of Apps) qui référence et gère plusieurs autres applications Argo CD.

Chaque application enfant pointe vers son propre dépôt ou dossier Git et définit ses propres manifestes Kubernetes (Helm, Kustomize, YAML…).

Ce pattern permet :

  • Centralisation de la configuration : un seul point d’entrée pour déployer et gérer toutes les applications.
  • Scalabilité et modularité : ajout ou suppression d’applications en modifiant uniquement l’application racine.
  • Séparation des responsabilités : chaque application reste indépendante, tout en étant orchestrée par la racine.
  • Facilité d’automatisation GitOps : les environnements et composants peuvent être définis dynamiquement via Git.

Mise en place de la root-app infra en mode App of Apps

infra/root-app.yml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: infra-root
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://gitlab.com/{{PROJECT_NAME}}/gitops.git
    targetRevision: master
    path: infra
    directory:
      recurse: true
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

⚠️ On note que l’application est déclaré dans le namespace argocd. Elle a donc accès au secret.

infra/namespaces/blog-ns.yml

apiVersion: v1
kind: Namespace
metadata:
  name: blog-ns
  labels:
    environment: prod
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: blog-ns
  name: argocd-deployer
rules:
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
  resources: ["*"]
  verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: blog-ns
  name: argocd-deployer-binding
subjects:
- kind: ServiceAccount
  name: argocd-application-controller
  namespace: argocd-apps
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: argocd-deployer

Déploiement de l’application infra

⚠️ Vérifier que les fichiers sont poussés sur le dépôt git.

kubectl apply -f infra/root-app.yaml

Cela aura pour effet de créer et synchroniser l’application root-app dans argocd.

Celle-ci est maintenant visible dans l’interface web de argocd.

Mise en place des autres applications

On va déclarer une application blog

blog/blog-app.yml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: blog-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://gitlab.com/{{PROJECT_NAME}}/gitops.git
    targetRevision: master
    path: blog
    directory:
      recurse: true
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

⚠️ On note que l’application est dans le namespace argocd

blog/blog-service.yml

apiVersion: v1
kind: Service
metadata:
  name: blog-service
  namespace: blog-ns
spec:
  ports:
    - port: 80
      protocol: TCP
  selector:
    app: blog

⚠️ On note que le service est dans le namespace blog-ns

blog/blog-deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: blog-deployment
  namespace: blog-ns
spec:
  selector:
    matchLabels:
      app: blog
  replicas: 1
  template:
    metadata:
      labels:
        app: blog
    spec:
      imagePullSecrets:
      - name: gitlab-registry-secret
      containers:
      - name: blog
        image: registry.gitlab.com/{{PROJECT_NAME}}/{{IMAGE_NAME}}:{{IMAGE_TAG}}
        imagePullPolicy: Always
        ports:
        - containerPort: 80

⚠️ On note que le déploiement est dans le namespace blog-ns

blog/blog-ingress.yml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: static
  namespace: blog-ns
  annotations:
    kubernetes.io/ingress.class: "traefik"
    cert-manager.io/issuer: "{{ID_ISSUER}}" # <== Si vous utilisez cert-manager/let's encrypt
spec:
  tls: # <== Si vous utilisez cert-manager/let's encrypt
    - hosts:
      - "{{DOMAIN_NAME}}"
      secretName: tls-static-ingress-http 
  rules:
  - host: "{{DOMAIN_NAME}}"
    http:
      paths:
      - pathType: Prefix
        path: / # <== Ici c'est la racine du domaine {{DOMAIN_NAME}}
        backend:
          service:
            name: blog-service
            port:
              number: 80

⚠️ On note que l’ingress est dans le namespace blog-ns

Déploiement de l’application blog

⚠️ Vérifier que les fichiers sont poussés sur le dépôt git.

kubectl apply -f blog/blog-app.yaml

Cela aura pour effet de créer et synchroniser l’application blog-app dans argocd.

Celle-ci est maintenant visible dans l’interface web de argocd.

Elle devrait être accessible sur le domaine que vous avez choisi à l’adresse suivante : https://{{DOMAIN_NAME}}

Troubleshooting

Vérifier l’existence de l’application dans argocd

argocd login 10.0.0.1 # si nécessaire
argocd app list
argocd app get infra-root
kubectl -n argocd get applications

Vérifier que les apps argocd sont bien dans le même namespace que le gitlab-registry-secret pour accéder au dépôt

les apps peuvent être créer dans le namespace argocd, ainsi que le secret gitlab-registry-secret. Cela simplifie la gestion des permissions.

Partager :