Was GitOps tatsächlich bedeutet
GitOps ist ein Betriebs-Framework, bei dem Git die einzige Quelle der Wahrheit für Ihre Infrastruktur- und Anwendungskonfiguration darstellt. Statt kubectl apply manuell auszuführen oder imperative Skripte anzustoßen, deklarieren Sie den gewünschten Zustand in Git und lassen einen Operator ihn automatisch abgleichen.
Die Kernprinzipien sind klar:
- Deklarative Konfiguration. Alles wird als Code in Git beschrieben.
- Versionskontrolliert. Jede Änderung läuft über einen Pull Request mit Review.
- Automatisierte Reconciliation. Ein Agent stellt kontinuierlich sicher, dass der Live-Zustand dem Soll-Zustand entspricht.
- Self-Healing. Abweichungen vom Soll-Zustand werden automatisch erkannt und korrigiert.
ArgoCD ist der am weitesten verbreitete GitOps-Operator für Kubernetes. In diesem Leitfaden gehen wir eine vollständige Implementierung von Grund auf durch.
ArgoCD installieren
Deployen Sie ArgoCD mit den offiziellen Manifests oder per Helm in Ihren Cluster:
# Option 1: Official manifests
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Option 2: Helm (recommended for production)
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd \
--namespace argocd \
--create-namespace \
--values argocd-values.yaml
Produktions-Helm-Values:
# argocd-values.yaml
server:
replicas: 2
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 5
ingress:
enabled: true
ingressClassName: nginx
hosts:
- argocd.example.com
tls:
- secretName: argocd-tls
hosts:
- argocd.example.com
controller:
replicas: 2
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 1Gi
repoServer:
replicas: 2
resources:
requests:
memory: 256Mi
cpu: 100m
redis-ha:
enabled: true
configs:
params:
server.insecure: false
application.instanceLabelKey: argocd.argoproj.io/instance
Rufen Sie das initiale Admin-Passwort ab:
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
Repository-Struktur für GitOps
Wir empfehlen, Anwendungs-Quellcode von Deployment-Manifesten zu trennen. Dieses Pattern skaliert:
# Application repo (app developers own this)
my-api/
├── src/
├── Dockerfile
├── .github/workflows/build.yml
└── ...
# Deployment repo (platform team + app developers)
k8s-deployments/
├── apps/
│ ├── my-api/
│ │ ├── base/
│ │ │ ├── deployment.yaml
│ │ │ ├── service.yaml
│ │ │ ├── hpa.yaml
│ │ │ └── kustomization.yaml
│ │ └── overlays/
│ │ ├── dev/
│ │ │ ├── kustomization.yaml
│ │ │ └── patch-replicas.yaml
│ │ ├── staging/
│ │ └── production/
│ └── another-service/
├── infrastructure/
│ ├── cert-manager/
│ ├── ingress-nginx/
│ └── monitoring/
└── projects/
└── platform.yaml
Kustomize-Base und -Overlays
Die Base enthält Ihre Default-Manifests:
# apps/my-api/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-api
spec:
replicas: 2
selector:
matchLabels:
app: my-api
template:
metadata:
labels:
app: my-api
spec:
containers:
- name: my-api
image: myregistry.com/my-api:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /readyz
port: 8080
Environment-Overlays passen spezifische Werte an:
# apps/my-api/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
resources:
- ../../base
patches:
- path: patch-replicas.yaml
images:
- name: myregistry.com/my-api
newTag: v1.4.2
# apps/my-api/overlays/production/patch-replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-api
spec:
replicas: 5
ArgoCD-Applications erstellen
Definieren Sie Ihre Applikationen als Kubernetes-Ressourcen (das „App of Apps"-Pattern):
# projects/platform.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: platform
namespace: argocd
spec:
description: Platform services
sourceRepos:
- "https://github.com/mycompany/k8s-deployments.git"
destinations:
- namespace: "*"
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: "*"
kind: "*"
# apps/my-api/argocd-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-api-production
namespace: argocd
labels:
app.kubernetes.io/part-of: platform
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: platform
source:
repoURL: https://github.com/mycompany/k8s-deployments.git
targetRevision: main
path: apps/my-api/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
retry:
limit: 3
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Wichtige Einstellungen erläutert:
selfHeal: true-- ArgoCD setzt manuelle Änderungen perkubectlzurück. Damit wird Git als einzige Quelle der Wahrheit erzwungen.prune: true-- aus Git gelöschte Ressourcen werden aus dem Cluster entfernt.PruneLast: true-- Löschungen erfolgen, nachdem alle anderen Sync-Operationen abgeschlossen sind.
Integration der CI/CD-Pipeline
Ihre CI-Pipeline baut und pusht Images. Anschließend aktualisiert sie das Deployment-Repo, um ArgoCD anzustoßen:
# .github/workflows/build.yml (in the application repo)
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.meta.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Build and push image
uses: docker/build-push-action@v5
with:
push: true
tags: myregistry.com/my-api:${{ github.sha }}
- name: Update deployment manifest
run: |
git clone https://x-access-token:${{ secrets.DEPLOY_TOKEN }}@github.com/mycompany/k8s-deployments.git
cd k8s-deployments
# Update the image tag in kustomization
cd apps/my-api/overlays/production
kustomize edit set image myregistry.com/my-api:${{ github.sha }}
git config user.name "github-actions"
git config user.email "[email protected]"
git add .
git commit -m "deploy: my-api ${{ github.sha }}"
git push
ArgoCD erkennt den Commit, vergleicht die gerenderten Manifests mit dem Live-Zustand und führt automatisch einen Sync durch.
Progressive Delivery mit Argo Rollouts
Für Produktionsumgebungen ersetzen Sie Standard-Deployments durch Argo Rollouts für Canary- oder Blue-Green-Deployments:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-api
namespace: production
spec:
replicas: 5
selector:
matchLabels:
app: my-api
template:
metadata:
labels:
app: my-api
spec:
containers:
- name: my-api
image: myregistry.com/my-api:v1.4.2
ports:
- containerPort: 8080
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 5m }
- setWeight: 30
- pause: { duration: 5m }
- setWeight: 60
- pause: { duration: 5m }
analysis:
templates:
- templateName: success-rate
startingStep: 1
canaryService: my-api-canary
stableService: my-api-stable
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
spec:
metrics:
- name: success-rate
interval: 60s
successCondition: result[0] > 0.95
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{service="my-api",status!~"5.."}[5m]))
/
sum(rate(http_requests_total{service="my-api"}[5m]))
Diese Konfiguration schiebt den Traffic progressiv von 10 % auf 30 %, auf 60 % und schließlich auf 100 %, mit automatischem Rollback, sobald die Success Rate unter 95 % fällt.
Multi-Cluster-Management
ArgoCD kann mehrere Cluster von einer zentralen Control Plane aus verwalten:
# Add a remote cluster
argocd cluster add my-staging-cluster --name staging
# Create an application targeting the remote cluster
argocd app create my-api-staging \
--repo https://github.com/mycompany/k8s-deployments.git \
--path apps/my-api/overlays/staging \
--dest-server https://staging-api.example.com \
--dest-namespace staging
Um viele Applikationen über Cluster hinweg zu verwalten, nutzen Sie ApplicationSets:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-api
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: production
url: https://kubernetes.default.svc
- cluster: staging
url: https://staging-api.example.com
template:
metadata:
name: "my-api-{{cluster}}"
spec:
project: platform
source:
repoURL: https://github.com/mycompany/k8s-deployments.git
targetRevision: main
path: "apps/my-api/overlays/{{cluster}}"
destination:
server: "{{url}}"
namespace: "{{cluster}}"
Best Practices für den Betrieb
- Nutzen Sie Projects, um RBAC zu erzwingen. Beschränken Sie, in welche Repos und Namespaces jedes Team deployen darf.
- Aktivieren Sie Notifications. ArgoCD hat einen eingebauten Notification Controller, der Slack-Nachrichten, GitHub-Status-Updates und Webhook-Aufrufe bei Sync-Ereignissen versenden kann.
- Monitoren Sie ArgoCD selbst. Es exponiert Prometheus-Metriken unter
/metrics. Alarmieren Sie bei Sync-Fehlern und hohen Reconciliation-Zeiten. - Setzen Sie Resource Limits für ArgoCD-Komponenten. Gerade der repo-server kann beim Rendern großer Manifests erheblich Speicher verbrauchen.
- Nutzen Sie Sync-Windows, um Deployments während Wartungsfenstern oder außerhalb der Geschäftszeiten zu verhindern.
Fazit
GitOps mit ArgoCD verwandelt Kubernetes-Deployments von einem fehleranfälligen manuellen Prozess in ein automatisiertes, auditierbares und selbstheilendes System. Die Kombination aus deklarativer Konfiguration, automatisierter Reconciliation und Progressive Delivery gibt Teams das Vertrauen, häufig zu deployen – ohne das Risiko.
Bei DevOpsVibe setzen wir GitOps-Pipelines um, die Teams von manuellen Deployments zu vollständig automatisierter Multi-Cluster-Delivery führen. Ob Sie GitOps erstmals einführen oder ein bestehendes Setup skalieren – wir helfen Ihnen, schneller ans Ziel zu kommen. Sprechen Sie uns an, wir unterstützen Sie gerne.