GitOps met ArgoCD: declaratieve implementatie en progressieve implementatie
GitOps is het paradigma dat Git transformeert van een coderepository naar enige bron van waarheid voor de status van uw Kubernetes-cluster. Het idee is simpel maar krachtig: alles wordt ingezet in het cluster moet worden beschreven in YAML-manifesten waarvan een versie is gemaakt in Git. Een agent in het cluster (ArgoCD) observeert de repository en zorgt ervoor dat de werkelijke toestand van het cluster altijd convergeert met de gewenste status in Git. Als iemand handmatig een hotfix rechtstreeks met kubectl, ArgoCD detecteert het en annuleert het automatisch.
In dit artikel zullen we zien hoe u dit kunt configureren ArgoCD vanaf nul, implementeren het patroon App der apps tientallen aanvragen declaratief beheren, gebruik ApplicatieSet voor multi-cluster en multi-omgeving, en integreren Argo-uitrol voor kanarie-implementatie en blauwgroen zonder downtime.
Wat je gaat leren
- Installatie en configuratie van ArgoCD met Helm
- Maak een applicatie ArgoCD voor implementatie gesynchroniseerd met Git
- App of Apps-patroon om veel applicaties te beheren
- ApplicationSet: geautomatiseerde implementatie in meerdere clusters en meerdere omgevingen
- Synchronisatiebeleid: geautomatiseerde synchronisatie, zelfherstel, snoeien
- Argo Rollouts: kanarie met statistische analyse, blauw-groen, verkeerssplitsing
- ArgoCD RBAC voor omgevingen met meerdere teams
- Slack/Teams-meldingen over implementatiegebeurtenissen
ArgoCD-installatie
# Installa ArgoCD con Helm (raccomandato per produzione)
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd \
--namespace argocd \
--create-namespace \
--version 7.6.0 \
--set global.domain=argocd.company.com \
--set server.ingress.enabled=true \
--set server.ingress.ingressClassName=nginx \
--set configs.params."server.insecure"=true \
--set dex.enabled=false # disabilita se non usi SSO
# Ottieni la password admin iniziale
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
# Accedi con ArgoCD CLI
argocd login argocd.company.com
argocd account update-password
# Verifica stato
argocd version
kubectl get pods -n argocd
Eerste toepassing ArgoCD
Una Sollicitatie ArgoCD is de belangrijkste bron: bepaalt waar vandaan haal de manifesten op (bron) en waar u ze kunt inzetten (bestemming):
# application-api-service.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: api-service-production
namespace: argocd
labels:
team: team-alpha
environment: production
finalizers:
- resources-finalizer.argocd.argoproj.io # elimina risorse K8s quando Application viene eliminata
spec:
project: team-alpha # ArgoCD Project per RBAC
source:
repoURL: https://github.com/company/k8s-manifests
targetRevision: main # branch/tag/commit SHA
path: apps/api-service/production # path nel repo
destination:
server: https://kubernetes.default.svc # cluster locale
namespace: team-alpha-production
syncPolicy:
automated:
prune: true # elimina risorse non piu presenti in Git
selfHeal: true # ripristina modifiche manuali non autorizzate
syncOptions:
- CreateNamespace=true # crea namespace se non esiste
- PrunePropagationPolicy=foreground
- ApplyOutOfSyncOnly=true # applica solo le risorse cambiate
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
# Ignorare alcune differenze (es. annotation aggiunte dal cluster)
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # ignora modifiche manuali al numero di repliche
Structuur van de Git Repository voor GitOps
De structuur van de GitOps-repository heeft een directe invloed op de onderhoudbaarheid. Het meeste patroon gemeenschappelijk en scheid de repository van de applicatiecode van de K8s-manifestrepository:
# Struttura raccomandata del repo k8s-manifests:
k8s-manifests/
├── apps/ # manifest applicazioni
│ ├── api-service/
│ │ ├── base/ # Kustomize base
│ │ │ ├── deployment.yaml
│ │ │ ├── service.yaml
│ │ │ └── kustomization.yaml
│ │ ├── dev/
│ │ │ ├── kustomization.yaml # overlays per dev
│ │ │ └── resources-patch.yaml
│ │ ├── staging/
│ │ │ └── kustomization.yaml
│ │ └── production/
│ │ ├── kustomization.yaml
│ │ └── hpa.yaml
│ └── worker-service/
│ └── ...
├── platform/ # risorse platform (ingress, cert-manager, etc.)
│ ├── ingress-nginx/
│ ├── cert-manager/
│ └── monitoring/
└── argocd/ # App of Apps: Application resources
├── root-app.yaml # App of Apps root
├── team-alpha.yaml
└── platform.yaml
# Kustomize base per api-service
# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
commonLabels:
app: api-service
managed-by: argocd
# production/kustomization.yaml - overlay con 3 repliche
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../base
replicas:
- name: api-service
count: 3
images:
- name: company.registry.io/api-service
newTag: "v2.5.1" # aggiornato dalla CI/CD pipeline
patchesStrategicMerge:
- resources-patch.yaml
App van Apps-patroon
Met App of Apps beheert één enkele ArgoCD-applicatie (de "root-app") alles andere ArgoCD-toepassingen. Het is het meest schaalbare patroon voor clusters met veel applicaties:
# argocd/root-app.yaml - la App of Apps root
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/company/k8s-manifests
targetRevision: main
path: argocd/ # questa cartella contiene le Application resources
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
---
# argocd/team-alpha.yaml - Application che punta agli overlay di team-alpha
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: team-alpha-production
namespace: argocd
spec:
project: team-alpha
source:
repoURL: https://github.com/company/k8s-manifests
targetRevision: main
path: apps/api-service/production
kustomize:
images:
- company.registry.io/api-service:v2.5.1 # aggiornato dalla CI
destination:
server: https://kubernetes.default.svc
namespace: team-alpha-production
syncPolicy:
automated:
prune: true
selfHeal: true
ApplicationSet: Multicluster en Multi-omgeving
ApplicatieSet genereert automatisch meerdere ArgoCD-applicaties uit één sjabloon. Ideaal voor het inzetten van dezelfde applicatie op veel clusters of omgevingen:
# applicationset-multi-env.yaml
# Deploy api-service su dev, staging e production dallo stesso template
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: api-service-all-envs
namespace: argocd
spec:
generators:
- list:
elements:
- environment: dev
namespace: team-alpha-dev
replicaCount: "1"
imageTag: "latest"
cluster: in-cluster
- environment: staging
namespace: team-alpha-staging
replicaCount: "2"
imageTag: "v2.5.0"
cluster: in-cluster
- environment: production
namespace: team-alpha-production
replicaCount: "5"
imageTag: "v2.4.9" # production usa tag stabile
cluster: production-cluster
template:
metadata:
name: 'api-service-{{environment}}'
labels:
environment: '{{environment}}'
spec:
project: team-alpha
source:
repoURL: https://github.com/company/k8s-manifests
targetRevision: main
path: 'apps/api-service/{{environment}}'
kustomize:
images:
- 'company.registry.io/api-service:{{imageTag}}'
destination:
server: '{{cluster}}'
namespace: '{{namespace}}'
syncPolicy:
automated:
prune: true
selfHeal: '{{eq environment "production" | not}}' # no selfHeal in prod
Argo-uitrol: Canarische implementatie en blauwgroen
Argo Rollouts breidt Kubernetes uit met geavanceerde implementatiestrategieën: kanarie met analytics statistieken, blauw-groen met handmatig of automatisch schakelen, verkeerssplitsing met Istio of NGINX-invoer:
# Installa Argo Rollouts
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts \
-f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
# Installa plugin kubectl
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
chmod +x kubectl-argo-rollouts-linux-amd64
sudo mv kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
Canary-implementatie met automatische analyse
# rollout-canary.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api-service
namespace: team-alpha-production
spec:
replicas: 10
selector:
matchLabels:
app: api-service
template:
metadata:
labels:
app: api-service
spec:
containers:
- name: api
image: company.registry.io/api-service:v2.5.1
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
strategy:
canary:
# Step 1: 10% traffico alla nuova versione
# Step 2: analisi automatica per 5 minuti
# Step 3: se ok, vai al 30% poi 100%
steps:
- setWeight: 10 # 10% traffico al canary
- analysis: # analisi automatica
templates:
- templateName: success-rate
args:
- name: service-name
value: api-service
- pause: {duration: 5m}
- setWeight: 30
- pause: {duration: 5m}
- setWeight: 100
# Canary Service: il nuovo Service per il traffico canary
canaryService: api-service-canary
stableService: api-service-stable
# Traffic routing con NGINX Ingress
trafficRouting:
nginx:
stableIngress: api-service-ingress
---
# AnalysisTemplate: definisce i criteri di successo
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
namespace: team-alpha-production
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 1m
successCondition: result[0] >= 0.95 # 95% di successo richiesto
failureLimit: 3 # fallisce dopo 3 misurazioni consecutive < 95%
provider:
prometheus:
address: http://prometheus.monitoring.svc:9090
query: |
sum(rate(http_requests_total{service="{{args.service-name}}",status=~"2.."}[5m]))
/
sum(rate(http_requests_total{service="{{args.service-name}}"}[5m]))
- name: latency-p99
interval: 1m
successCondition: result[0] < 0.5 # P99 < 500ms
provider:
prometheus:
address: http://prometheus.monitoring.svc:9090
query: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket{service="{{args.service-name}}"}[5m])) by (le)
)
Uitrolbeheer via CLI
# Visualizza stato del rollout in tempo reale
kubectl argo rollouts get rollout api-service -n team-alpha-production --watch
# Promuovi manualmente al prossimo step (se pause)
kubectl argo rollouts promote api-service -n team-alpha-production
# Rollback immediato se qualcosa va storto
kubectl argo rollouts abort api-service -n team-alpha-production
kubectl argo rollouts undo api-service -n team-alpha-production
# Dashboard UI di Argo Rollouts
kubectl argo rollouts dashboard &
# Apri http://localhost:3100
ArgoCD-meldingen voor Slack en Teams
# argocd-notifications-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
template.app-deployed: |
message: |
:rocket: Application *{{.app.metadata.name}}* deployed to *{{.app.spec.destination.namespace}}*
Image: `{{index .app.status.summary.images 0}}`
Sync: {{.app.status.sync.status}}
template.app-health-degraded: |
message: |
:red_circle: Application *{{.app.metadata.name}}* health degraded!
{{range .app.status.conditions}}{{.message}}{{end}}
trigger.on-deployed: |
- description: Application is synced and healthy
send:
- app-deployed
when: app.status.operationState.phase in ['Succeeded'] and
app.health.status == 'Healthy'
trigger.on-health-degraded: |
- description: Application has degraded
send:
- app-health-degraded
when: app.health.status == 'Degraded'
---
# Applica annotazione sull'Application per ricevere notifiche
kubectl annotate app api-service-production \
notifications.argoproj.io/subscribe.on-deployed.slack="deployments-channel" \
-n argocd
GitOps best practices met ArgoCD
Productie GitOps-checklist
- Afzonderlijke opslagplaatsen voor K8s-appcode en manifest: De GitOps-opslagplaats mag geen applicatiecode bevatten. Scheid configuratie van code
- Afbeeldingstag in de GitOps-repository (niet "nieuwste"): Voor reproduceerbaarheid moet de afbeeldingstag SHA- of versiespecifiek zijn, en niet 'nieuwste'
- Verplichte beoordeling voor productie: Voor PR's om de productie te vertakken is ten minste één goedkeuring vereist. ArgoCD mag niet automatisch van toepassing zijn zonder beoordeling in prod
- Geheim met externe geheimenoperator: Maak Secret nooit duidelijk in de GitOps-repository. Gebruik ESO met AWS Secrets Manager of Vault
- Zelfherstel in ontwikkelaar, handleiding in productie: Automatische zelfherstel is handig bij ontwikkeling/staging, maar riskant bij productie (kan urgente hotfixes annuleren)
- Gebruik Kustomize of Helm, niet onbewerkte YAML: Met sjablonen kunt u overlays per omgeving hergebruiken, waardoor duplicatie wordt vermeden
Conclusies en volgende stappen
ArgoCD transformeert de implementatie van Kubernetes van een handmatige en risicovolle operatie naar een proces geautomatiseerd, controleerbaar en omkeerbaar. De combinatie van App of Apps voor beheer clusterbrede declaratieve en Argo Rollouts voor progressieve canary-implementaties creëren een leveringspijplijn die snelheid en veiligheid in evenwicht brengt.
De volgende natuurlijke stap na GitOps is waarneembaarheid: zonder statistieken en loggen niet je kunt weten of je kanarie succes heeft of regressies introduceert. Het artikel 11 van deze serie – Prometheus, Grafana en OpenTelemetry – maakt het plaatje compleet.
Aankomende artikelen in de Kubernetes at Scale-serie
Gerelateerde serie
- DevSecOps — GitOps + beveiligingsscans in de pijplijn
- Platformtechniek — ArgoCD als onderdeel van het IDP
- Terraform en infrastructuur als code — clusterinrichting vóór GitOps







