Loading...
Alle Artikel
CI/CD · 6 min read

GitOps mit ArgoCD: Ein vollständiger Implementierungs-Leitfaden

Schritt-für-Schritt-Anleitung zur Umsetzung von GitOps mit ArgoCD – von der Installation bis zu fortgeschrittenen Deployment-Strategien wie Canary-Releases und Multi-Cluster-Management.

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 per kubectl zurü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.

abgelegt unter
gitopsargocdargocdkuberneteskubernetescicddeploymentautomation
mit uns arbeiten

Soll unser Team Ihrer Infrastruktur helfen?

talk to an engineerFree 30-min discovery callBook
close