ArgoCD Image Updater : Automatiser les Déploiements GitOps
Le Problème du GitOps Manuel
Avec ArgoCD seul, mettre à jour une image Docker nécessite plusieurs étapes manuelles :
- CI build une nouvelle image
app:v1.2.3 - Push l’image vers le registry
- Modifier manuellement le fichier YAML Git :
image: app:v1.2.3 - Commit et push
- ArgoCD détecte le changement et déploie
Cette étape manuelle (3-4) casse le flux d’automatisation et ralentit les déploiements.
ArgoCD Image Updater résout ce problème : il surveille votre registry Docker et met à jour automatiquement les manifestes Git quand une nouvelle image est disponible.
Architecture du Workflow GitOps Complet
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Git Repo │────▶│ ArgoCD │────▶│ Kubernetes │
│ manifests │ │ sync auto │ │ Cluster │
└─────────────┘ └──────────────┘ └─────────────┘
▲
│
│ Git commit
│
┌──────────────────┐
│ Image Updater │
│ détecte nouvelle│
│ image + update │
└──────────────────┘
▲
│
┌──────────────────┐
│ Docker Registry │
│ nouvelle image │
│ app:v1.2.3 │
└──────────────────┘
▲
│
┌──────────────────┐
│ CI/CD │
│ build + push │
└──────────────────┘
Flux complet :
1. CI/CD build et push app:v1.2.3 vers le registry
2. Image Updater détecte la nouvelle image
3. Image Updater commit image: app:v1.2.3 dans Git
4. ArgoCD détecte le changement Git
5. ArgoCD déploie sur Kubernetes
Installation ArgoCD Image Updater
Prérequis
- Cluster Kubernetes avec ArgoCD installé
- Repository Git avec vos manifestes
- Docker registry (Docker Hub, ECR, GCR, Harbor…)
Installation via Manifestes
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml
Vérification
kubectl get pods -n argocd | grep image-updater
# argocd-image-updater-xyz 1/1 Running
Configuration : Trois Stratégies
1. Stratégie “Latest Tag” (Staging)
Déploie automatiquement la dernière image disponible.
Use case : Environnement staging qui doit toujours avoir la dernière version.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: app-staging
namespace: argocd
annotations:
argocd-image-updater.argoproj.io/image-list: myapp=myregistry/myapp
argocd-image-updater.argoproj.io/myapp.update-strategy: latest
spec:
source:
repoURL: https://github.com/mon-org/manifests
path: staging
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: staging
syncPolicy:
automated:
prune: true
selfHeal: true
Comportement :
- Nouvelle image myapp:abc123 poussée
- Image Updater détecte et update immédiatement
- Déploiement automatique en staging
2. Stratégie “Semver” (Production)
Déploie uniquement les versions sémantiques selon contraintes.
Use case : Production qui ne doit recevoir que des versions stables (pas de pre-release).
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: app-production
namespace: argocd
annotations:
argocd-image-updater.argoproj.io/image-list: myapp=myregistry/myapp
argocd-image-updater.argoproj.io/myapp.update-strategy: semver
argocd-image-updater.argoproj.io/myapp.allow-tags: "regexp:^[0-9]+\\.[0-9]+\\.[0-9]+$"
spec:
source:
repoURL: https://github.com/mon-org/manifests
path: production
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
Comportement :
- myapp:1.2.3 → ✅ Déployé
- myapp:1.2.4-beta → ❌ Ignoré (pre-release)
- myapp:1.3.0 → ✅ Déployé (version supérieure)
3. Stratégie “Name” (Tags Spécifiques)
Déploie uniquement les images correspondant à un pattern.
Use case : Déployer uniquement les tags release-*.
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: myapp=myregistry/myapp
argocd-image-updater.argoproj.io/myapp.update-strategy: name
argocd-image-updater.argoproj.io/myapp.allow-tags: "regexp:^release-.*"
Authentification au Registry
Docker Hub
apiVersion: v1
kind: Secret
metadata:
name: docker-hub-creds
namespace: argocd
type: Opaque
stringData:
username: mon-user
password: mon-token
---
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-image-updater-config
namespace: argocd
data:
registries.conf: |
registries:
- name: Docker Hub
prefix: docker.io
api_url: https://registry-1.docker.io
credentials: secret:argocd/docker-hub-creds
AWS ECR
data:
registries.conf: |
registries:
- name: ECR
prefix: 123456789.dkr.ecr.eu-west-3.amazonaws.com
api_url: https://123456789.dkr.ecr.eu-west-3.amazonaws.com
credentials: ext:/scripts/ecr-login.sh
credsexpire: 10h
Avec IAM role sur le pod Image Updater (IRSA).
Google GCR
data:
registries.conf: |
registries:
- name: GCR
prefix: gcr.io
api_url: https://gcr.io
credentials: pullsecret:argocd/gcr-creds
Workflow Git : Write-Back vs Branch
Mode Write-Back (Défaut)
Image Updater commit directement sur la branche principale.
metadata:
annotations:
argocd-image-updater.argoproj.io/write-back-method: git
argocd-image-updater.argoproj.io/git-branch: main
Avantages : - Simple - Déploiement immédiat
Inconvénients : - Pas de revue de code - Contourne les protections de branche
Mode Branch + Pull Request
Image Updater crée une branche et une PR.
metadata:
annotations:
argocd-image-updater.argoproj.io/write-back-method: git:branch
argocd-image-updater.argoproj.io/git-branch: main
argocd-image-updater.argoproj.io/git-branch-prefix: image-update/
Comportement :
1. Nouvelle image détectée
2. Image Updater crée branche image-update/myapp-1.2.3
3. Commit le changement d’image
4. (Optionnel) Déclenche webhook pour créer PR automatique
Avantages : - Revue possible avant déploiement - Trace dans Git - Compatible avec protections de branche
Workflow recommandé :
# Staging : write-back direct
argocd-image-updater.argoproj.io/write-back-method: git
# Production : branch + PR
argocd-image-updater.argoproj.io/write-back-method: git:branch
Configuration Git SSH
Image Updater a besoin de credentials Git pour commit.
Créer une Clé SSH
ssh-keygen -t ed25519 -C "argocd-image-updater" -f image-updater-key
Ajouter au Git Provider
GitHub :
- Settings → Deploy keys → Add deploy key
- Coller image-updater-key.pub
- ✅ Cocher “Allow write access”
GitLab : - Settings → Repository → Deploy Keys - Coller la clé publique - ✅ Grant write permissions
Créer le Secret Kubernetes
kubectl create secret generic git-creds \
--from-file=sshPrivateKey=image-updater-key \
-n argocd
Configurer Image Updater
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-image-updater-config
namespace: argocd
data:
git.user: argocd-image-updater
git.email: argocd-image-updater@example.com
Exemple Complet : Application Multi-Environnements
Structure Git Repository
manifests/
├── staging/
│ └── deployment.yaml
├── production/
│ └── deployment.yaml
└── base/
└── deployment.yaml
Staging : Latest Tag
# apps/app-staging.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-staging
namespace: argocd
annotations:
# Surveiller l'image
argocd-image-updater.argoproj.io/image-list: app=docker.io/myorg/myapp
# Stratégie : dernière image
argocd-image-updater.argoproj.io/app.update-strategy: latest
# Commit direct
argocd-image-updater.argoproj.io/write-back-method: git
argocd-image-updater.argoproj.io/git-branch: main
spec:
project: default
source:
repoURL: git@github.com:myorg/manifests.git
path: staging
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: staging
syncPolicy:
automated:
prune: true
selfHeal: true
Production : Semver avec PR
# apps/app-production.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-production
namespace: argocd
annotations:
# Surveiller l'image
argocd-image-updater.argoproj.io/image-list: app=docker.io/myorg/myapp
# Stratégie : versions stables uniquement
argocd-image-updater.argoproj.io/app.update-strategy: semver
argocd-image-updater.argoproj.io/app.allow-tags: "regexp:^[0-9]+\\.[0-9]+\\.[0-9]+$"
# Créer une branche + PR
argocd-image-updater.argoproj.io/write-back-method: git:branch
argocd-image-updater.argoproj.io/git-branch: main
spec:
project: default
source:
repoURL: git@github.com:myorg/manifests.git
path: production
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Cas d’Usage Réels
1. Staging Auto, Production Manuel
Objectif : Staging toujours à jour, production validée manuellement.
Configuration :
- Staging : update-strategy: latest + write-back: git
- Production : update-strategy: semver + write-back: git:branch
Workflow :
1. CI push myapp:abc123 vers registry
2. Staging déploie automatiquement
3. Tests automatisés en staging
4. CI tag myapp:1.2.3 si tests OK
5. Image Updater crée PR pour production
6. Revue + merge manuel
7. Production déployée
2. Canary Deployments
Objectif : Déployer 10% du trafic avec nouvelle version.
metadata:
annotations:
argocd-image-updater.argoproj.io/image-list: app=myregistry/myapp
argocd-image-updater.argoproj.io/app.update-strategy: semver
argocd-image-updater.argoproj.io/app.helm.image-name: image.tag
argocd-image-updater.argoproj.io/app.helm.image-spec: canary.image.tag
Avec Argo Rollouts pour gérer le canary progressif.
3. Multi-Cluster
Objectif : Même image sur dev/staging/prod sur clusters différents.
# Application par cluster
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-cluster-prod
annotations:
argocd-image-updater.argoproj.io/image-list: app=myregistry/myapp
argocd-image-updater.argoproj.io/app.update-strategy: semver
spec:
destination:
server: https://prod-cluster.example.com
namespace: production
Image Updater update le manifest, ArgoCD sync sur le cluster distant.
Monitoring et Debugging
Voir les Images Surveillées
kubectl get applications -n argocd -o json | \
jq '.items[] | select(.metadata.annotations["argocd-image-updater.argoproj.io/image-list"]) | {name: .metadata.name, images: .metadata.annotations["argocd-image-updater.argoproj.io/image-list"]}'
Logs Image Updater
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-image-updater -f
Indicateurs de santé :
- "Checking 5 applications" : Image Updater scrute activement
- "Setting new image to myapp:1.2.3" : Nouvelle image détectée
- "Successfully updated image" : Commit Git réussi
Annotations de Debug
metadata:
annotations:
# Augmenter la fréquence de vérification
argocd-image-updater.argoproj.io/myapp.pull-secret: pullsecret:argocd/registry-creds
# Dry-run : pas de commit Git
argocd-image-updater.argoproj.io/update-strategy: latest
argocd-image-updater.argoproj.io/write-back-method: git:noop
Erreurs Fréquentes
“Could not update image” : - Vérifier credentials registry - Vérifier le nom de l’image (prefix correct)
“Failed to commit” : - Vérifier SSH key a accès write - Vérifier protection de branche
“No new image found” :
- Vérifier le tag pattern (allow-tags)
- Vérifier l’image existe dans le registry
Sécurité
Principe du Moindre Privilège
Image Updater a besoin : - Lecture registry Docker - Écriture Git (uniquement manifests repo) - Lecture Kubernetes (Applications ArgoCD)
Image Updater N’A PAS besoin : - Accès au cluster Kubernetes des apps - Accès aux secrets applicatifs
Git Signing (Recommandé)
Signer les commits Image Updater pour traçabilité.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-image-updater-config
namespace: argocd
data:
git.commit-sign-key: /path/to/gpg-key
Registry Privé avec HTTPS
Toujours utiliser HTTPS pour le registry.
registries:
- name: Harbor
prefix: harbor.mycompany.com
api_url: https://harbor.mycompany.com
insecure: no # Forcer HTTPS
credentials: secret:argocd/harbor-creds
Limites et Alternatives
Limites d’Image Updater
Ne gère pas : - Dépendances entre services (app A doit être déployée avant app B) - Tests post-déploiement (à gérer avec ArgoCD hooks) - Rollback automatique si erreur
Fréquence de scan : - Par défaut : toutes les 2 minutes - Pas de webhook (polling uniquement)
Alternative : Flux Image Automation
Si vous utilisez Flux au lieu d’ArgoCD :
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
name: myapp
spec:
interval: 1m
sourceRef:
kind: GitRepository
name: manifests
git:
checkout:
ref:
branch: main
commit:
author:
email: fluxcdbot@example.com
name: fluxcdbot
push:
branch: main
update:
path: ./production
strategy: Setters
Concept identique, implémentation différente.
Bonnes Pratiques
1. Séparer Staging et Production
manifests/
├── staging/
│ ├── deployment.yaml # image: myapp:latest
│ └── argocd-app.yaml # update-strategy: latest
└── production/
├── deployment.yaml # image: myapp:1.2.3
└── argocd-app.yaml # update-strategy: semver
2. Utiliser Semver en Production
Toujours tagger vos releases avec semver : v1.2.3.
# CI pipeline
git tag v1.2.3
docker build -t myapp:1.2.3 .
docker push myapp:1.2.3
3. Limiter les Patterns de Tags
# Production : versions stables uniquement
argocd-image-updater.argoproj.io/app.allow-tags: "regexp:^[0-9]+\\.[0-9]+\\.[0-9]+$"
# Staging : pas de "latest" ni "dev"
argocd-image-updater.argoproj.io/app.ignore-tags: "latest, dev"
4. Git Commit Messages Clairs
data:
git.commit-message-template: |
build: update {{.AppName}} image to {{.NewTag}}
Updated by ArgoCD Image Updater
App: {{.AppName}}
Image: {{.Image}}
Old tag: {{.OldTag}}
New tag: {{.NewTag}}
5. Monitoring avec Prometheus
Image Updater expose des métriques Prometheus :
# ServiceMonitor pour Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-image-updater
namespace: argocd
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-image-updater
endpoints:
- port: metrics
Métriques clés :
- argocd_image_updater_applications_watched : Nombre d’apps surveillées
- argocd_image_updater_images_updated : Images mises à jour
- argocd_image_updater_registry_response_time : Latence registry
Conclusion
ArgoCD Image Updater complète le workflow GitOps en automatisant la mise à jour des images Docker dans vos manifestes Git.
Points clés : - Automatisation complète : De la CI au déploiement sans intervention manuelle - Stratégies flexibles : Latest pour staging, semver pour production - Workflow Git personnalisable : Write-back direct ou branch + PR - Sécurité : Authentification registry, signature Git, moindre privilège
Setup en 3 étapes : 1. Installer Image Updater dans ArgoCD 2. Configurer credentials registry + Git 3. Annoter vos Applications ArgoCD
Workflow recommandé :
- Staging : update-strategy: latest + write-back direct → déploiement immédiat
- Production : update-strategy: semver + branch + PR → revue manuelle
Ce workflow GitOps complet garantit des déploiements rapides en staging pour tester, et contrôlés en production pour la stabilité.
Points clés à retenir
- ✓ Image Updater automatise la mise à jour des images Docker dans Git (élimine l'étape manuelle)
- ✓ Stratégie latest pour staging : déploiement immédiat de chaque build CI
- ✓ Stratégie semver pour production : uniquement versions stables (v1.2.3, pas de beta)
- ✓ Write-back modes : commit direct (staging) vs branch+PR (production avec revue)
- ✓ Setup 3 étapes : install Image Updater, configurer credentials, annoter Applications ArgoCD