GitOps veranderde hoe ik over deployments denk. In plaats van commando’s tegen een cluster uitvoeren, push ik naar Git en kijk ik hoe het cluster convergeert naar de gewenste staat. Het klinkt simpel, maar de implicaties zijn diepgaand.
ArgoCD is mijn tool of choice voor GitOps. Laat me je laten zien waarom, en hoe je ermee begint.
Waarom GitOps? De Filosofie Eerst
Voordat we in ArgoCD duiken, laten we begrijpen waarom GitOps ertoe doet.
Traditionele deployment:
Developer → kubectl apply → Cluster
Het probleem: Wat is gedeployed? Je moet het cluster queryen. Configuration drift gebeurt stilletjes. Rollbacks zijn handmatig en foutgevoelig. Er is geen audit trail behalve “iemand heeft kubectl gerund.”
GitOps deployment:
Developer → Git Push → ArgoCD → Cluster
Het verschil: Git is de source of truth. Wat in Git staat is wat in het cluster staat. Altijd. Als iemand handmatig iets verandert, draait ArgoCD het terug. Als je wilt weten wat gedeployed is, check Git. Als je wilt rollbacken, revert de commit.
Dit past bij mijn kernfilosofie: systemen moeten expliciet en begrijpbaar zijn. Imperatieve commando’s zijn vluchtig. Declaratieve staat in Git is permanent en auditeerbaar.
ArgoCD Installeren
Laten we ArgoCD draaien. Ik gebruik eerst een simpele installatie, dan leg ik de onderdelen uit.
# Maak namespace
kubectl create namespace argocd
# Installeer ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Wacht tot pods ready zijn
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s
Dat is het. ArgoCD draait nu. Laten we het benaderen:
# Haal het initiële admin wachtwoord op
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# Port-forward de UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Open https://localhost:8080, login als 'admin' met het wachtwoord hierboven
De Kernconcepten
ArgoCD heeft een paar key concepts om te begrijpen:
Application
Een Application is de fundamentele unit in ArgoCD. Het definieert:
- Source: Waar je manifests leven (Git repo, Helm chart, Kustomize)
- Destination: Naar welk cluster en namespace te deployen
- Sync Policy: Hoe om te gaan met verschillen tussen Git en cluster
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourorg/yourrepo.git
targetRevision: main
path: manifests/my-app
destination:
server: https://kubernetes.default.svc
namespace: my-app
syncPolicy:
automated:
prune: true
selfHeal: true
Project
Een Project groepeert applicaties en definieert access controls. Het default project staat alles toe, maar in productie wil je restricties.
Sync
Sync is het proces van het cluster laten matchen met Git. Het kan zijn:
- Handmatig: Je klikt op een knop
- Automated: ArgoCD doet het wanneer Git verandert
- Self-healing: ArgoCD draait handmatige cluster wijzigingen terug
Je Eerste Deployment
Laten we iets echts deployen. Ik maak een simpele nginx deployment beheerd door ArgoCD.
Stap 1: Maak een Git Repository
Maak een nieuwe repo (of gebruik een bestaande) met deze structuur:
my-gitops-repo/
└── apps/
└── nginx/
├── deployment.yaml
├── service.yaml
└── kustomization.yaml
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
Commit en push dit naar je repo.
Stap 2: Maak de ArgoCD Application
# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/YOURUSER/my-gitops-repo.git
targetRevision: main
path: apps/nginx
destination:
server: https://kubernetes.default.svc
namespace: nginx
syncPolicy:
syncOptions:
- CreateNamespace=true
automated:
prune: true
selfHeal: true
Apply het:
kubectl apply -f argocd-application.yaml
Stap 3: Kijk naar de Magie
Open de ArgoCD UI. Je ziet je applicatie verschijnen. Als je automated sync hebt ingeschakeld, deployt het direct. Anders klik je op “Sync.”
flowchart LR
subgraph dashboard["ArgoCD Dashboard - nginx"]
direction LR
DEP["Deployment<br/>nginx"] --> RS["ReplicaSet<br/>nginx"]
RS --> POD["Pod x2<br/>nginx"]
DEP --> SVC["Service<br/>nginx"]
end
ArgoCD toont de resource tree, health status, en sync status. Het is direct duidelijk wat gedeployed is.
De GitOps Workflow
Nu komt het mooie deel. Wil je iets veranderen?
- Edit in Git: Verander
replicas: 2naarreplicas: 3in deployment.yaml - Commit en push
- ArgoCD detecteert de wijziging (binnen 3 minuten standaard, of direct met webhooks)
- Cluster update automatisch
Geen kubectl. Geen scripts. Geen “heb ik dat commando gerund?” Git is de waarheid.
Rollback? Gewoon Reverten
Iets kapot? Revert de commit in Git. ArgoCD synct. Klaar.
git revert HEAD
git push
# ArgoCD rollbackt automatisch het cluster
De cluster staat is nu auditeerbaar via git log:
git log --oneline apps/nginx/
# a1b2c3d Scale nginx to 3 replicas
# d4e5f6g Initial nginx deployment
Self-Healing in Actie
Schakel selfHeal: true in en probeer dit:
# Handmatig de deployment schalen
kubectl scale deployment nginx -n nginx --replicas=5
# Wacht even...
kubectl get deployment nginx -n nginx
# NAME READY UP-TO-DATE AVAILABLE
# nginx 3/3 3 3
ArgoCD merkte de drift op en draaide het terug. Het cluster matcht altijd Git.
Dit voorkomt configuration drift — een van de meest verraderlijke problemen in infrastructuur. Geen “iemand heeft die instelling vorig jaar veranderd en niemand weet waarom” meer.
Sync Policies Uitgelegd
De sync policy bepaalt hoe ArgoCD zich gedraagt:
syncPolicy:
automated:
prune: true # Verwijder resources die uit Git verwijderd zijn
selfHeal: true # Draai handmatige wijzigingen terug
allowEmpty: false # Sync niet als source leeg is
syncOptions:
- CreateNamespace=true
- PruneLast=true # Prune na andere syncs
- ApplyOutOfSyncOnly=true # Alleen gewijzigde resources applyen
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Mijn aanbeveling: Begin met automated sync, prune, en selfHeal allemaal ingeschakeld. Dit geeft je de volledige GitOps ervaring. Je kunt altijd uitschakelen voor specifieke applicaties die speciale handling nodig hebben.
Private Repositories
De meeste echte repos zijn private. ArgoCD heeft credentials nodig:
# Met de CLI
argocd repo add https://github.com/yourorg/private-repo.git \
--username git \
--password ghp_yourtoken
# Of als Kubernetes secret
kubectl create secret generic private-repo \
-n argocd \
--from-literal=url=https://github.com/yourorg/private-repo.git \
--from-literal=username=git \
--from-literal=password=ghp_yourtoken
kubectl label secret private-repo -n argocd \
argocd.argoproj.io/secret-type=repository
Voor SSH:
argocd repo add git@github.com:yourorg/private-repo.git \
--ssh-private-key-path ~/.ssh/id_rsa
Helm en Kustomize
ArgoCD ondersteunt native Helm en Kustomize.
Helm Charts
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prometheus
namespace: argocd
spec:
source:
repoURL: https://prometheus-community.github.io/helm-charts
chart: prometheus
targetRevision: 25.0.0
helm:
values: |
server:
persistentVolume:
enabled: true
size: 10Gi
destination:
server: https://kubernetes.default.svc
namespace: monitoring
Kustomize Overlays
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-production
spec:
source:
repoURL: https://github.com/yourorg/yourrepo.git
path: apps/my-app/overlays/production
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: production
ArgoCD detecteert kustomization.yaml en past het automatisch toe.
Veelvoorkomende Fouten om te Vermijden
Fout 1: Prune Niet Inschakelen
Zonder prune: true verwijdert ArgoCD geen resources die je uit Git verwijdert. Je eindigt met orphaned resources.
Fout 2: Secrets in Git Zetten
Commit nooit plain secrets naar Git. Gebruik:
- Sealed Secrets
- External Secrets Operator met Vault
- SOPS encrypted secrets
Fout 3: Handmatige Wijzigingen “Alleen Deze Keer”
Het moment dat je handmatig iets verandert, heb je drift geïntroduceerd. Of update Git of schakel selfHeal in om je wijziging terug te draaien.
Fout 4: Enkele Monolithische Application
Eén grote Application met alles is moeilijk te beheren. Splits in meerdere applications per service of team.
Wat Volgt?
Dit is nog maar het begin. ArgoCD heeft veel meer:
- App-of-Apps pattern: Beheer applicaties met applicaties
- Drift detection: Monitor op ongeautoriseerde wijzigingen
- Disaster recovery: Herbouw clusters vanuit Git
- ApplicationSets: Genereer applicaties dynamisch
- Notifications: Slack/email bij sync events
Mijn Aanbeveling
- Begin met één applicatie. Raak vertrouwd met de workflow.
- Schakel automated sync + selfHeal in. Ervaar het volledige GitOps voordeel.
- Gebruik een dedicated gitops repo. Scheid infrastructuur van applicatie code.
- Stel webhooks in. Snellere sync dan polling.
- Vecht er niet tegen. Als je handmatige controle wilt, vraag jezelf waarom.
GitOps is niet alleen een deployment methode. Het is een mindset shift. Als je eenmaal “Git is waarheid” ervaart, wil je niet meer terug naar imperatieve commando’s en configuration drift.
