Zum Inhalt

Deployment vs. StatefulSet

ohMyHelm unterstützt sowohl Deployments als auch StatefulSets. Diese Seite erklärt die Unterschiede und wann welcher Typ verwendet werden sollte.

Übersicht

Eigenschaft Deployment StatefulSet
Pod-Identität Austauschbar Stabil und eindeutig
Pod-Namen Zufällig (z.B. app-abc123) Geordnet (z.B. app-0, app-1)
Persistent Storage Shared Volume Individuelle PVCs pro Pod
Skalierung Parallel Sequenziell
Updates Rolling Update (parallel) Rolling Update (sequenziell)
Netzwerk Gemeinsamer Service Headless Service mit DNS pro Pod

Deployment (Standard)

Deployments sind für stateless Anwendungen gedacht, bei denen Pods austauschbar sind.

Konfiguration

chart:
  enabled: true
  statefulset: false  # Standard-Wert

  container:
    image: myapp/api:latest
    ports:
      - name: http
        containerPort: 8080

Mit Volumes

chart:
  statefulset: false

  container:
    image: myapp/api:latest
    volumeMounts:
      - name: config
        mountPath: /etc/config
      - name: cache
        mountPath: /cache

  deploymentVolume:
    volumes:
      - name: config
        configMap:
          name: app-config
      - name: cache
        emptyDir: {}

Anwendungsfälle für Deployments

  • Stateless APIs - REST/GraphQL APIs
  • Web-Frontend - React, Vue, Angular Apps
  • Worker-Prozesse - Message Queue Consumer
  • Microservices - Alle Instanzen sind identisch

StatefulSet

StatefulSets sind für stateful Anwendungen gedacht, die stabile Identitäten und persistenten Storage benötigen.

Konfiguration

chart:
  enabled: true
  statefulset: true

  container:
    image: postgres:14
    ports:
      - name: postgres
        containerPort: 5432

Mit Persistent Volumes

chart:
  statefulset: true

  container:
    image: postgres:14
    volumeMounts:
      - name: data
        mountPath: /var/lib/postgresql/data

  statefulsetVolume:
    volumeMounts:
      - name: data
        mountPath: /var/lib/postgresql/data

    volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes:
            - ReadWriteOnce
          storageClassName: fast-ssd
          resources:
            requests:
              storage: 50Gi

    volumes:
      - name: config
        configMap:
          name: postgres-config

Anwendungsfälle für StatefulSets

  • Datenbanken - PostgreSQL, MySQL, MongoDB
  • Message Queues - Kafka, RabbitMQ
  • Distributed Systems - Elasticsearch, Cassandra, Zookeeper
  • Caching - Redis Cluster
  • Anwendungen mit lokalem State - Prometheus, Grafana

Vollständige Beispiele

Stateless API (Deployment)

chart:
  enabled: true
  fullnameOverride: "my-api"
  replicaCount: 3
  statefulset: false

  container:
    image: myapp/api:v1.0.0
    ports:
      - name: http
        containerPort: 8080
    livenessProbe:
      httpGet:
        path: /health
        port: http
    readinessProbe:
      httpGet:
        path: /ready
        port: http

  service:
    type: ClusterIP
    ports:
      - port: 80
        targetPort: http

  autoscaling:
    enabled: true
    minReplicas: 3
    maxReplicas: 10
    targetCPUUtilizationPercentage: 80

  deploymentVolume:
    volumes:
      - name: tmp
        emptyDir: {}

PostgreSQL Datenbank (StatefulSet)

chart:
  enabled: true
  fullnameOverride: "my-postgres"
  replicaCount: 1
  statefulset: true

  container:
    image: postgres:14
    ports:
      - name: postgres
        containerPort: 5432
    env:
      - name: POSTGRES_DB
        value: myapp
      - name: POSTGRES_USER
        valueFrom:
          secretKeyRef:
            name: postgres-credentials
            key: username
      - name: POSTGRES_PASSWORD
        valueFrom:
          secretKeyRef:
            name: postgres-credentials
            key: password
      - name: PGDATA
        value: /var/lib/postgresql/data/pgdata
    livenessProbe:
      exec:
        command:
          - pg_isready
          - -U
          - postgres
      initialDelaySeconds: 30
      periodSeconds: 10

  service:
    type: ClusterIP
    ports:
      - port: 5432
        targetPort: postgres

  statefulsetVolume:
    volumeMounts:
      - name: data
        mountPath: /var/lib/postgresql/data

    volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes:
            - ReadWriteOnce
          storageClassName: fast-ssd
          resources:
            requests:
              storage: 100Gi

Redis Cluster (StatefulSet)

chart:
  enabled: true
  fullnameOverride: "redis"
  replicaCount: 3
  statefulset: true

  container:
    image: redis:7
    ports:
      - name: redis
        containerPort: 6379
    command:
      - redis-server
      - /etc/redis/redis.conf

  statefulsetVolume:
    volumeMounts:
      - name: data
        mountPath: /data
      - name: config
        mountPath: /etc/redis

    volumeClaimTemplates:
      - metadata:
          name: data
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 10Gi

    volumes:
      - name: config
        configMap:
          name: redis-config

Entscheidungshilfe

graph TD
    A[Braucht meine App persistenten Storage?] -->|Nein| B[Deployment]
    A -->|Ja| C[Braucht jeder Pod eigenen Storage?]
    C -->|Nein| D[Deployment mit Shared PVC]
    C -->|Ja| E[Brauchen Pods stabile Identitäten?]
    E -->|Nein| D
    E -->|Ja| F[StatefulSet]

Best Practices

  1. Deployment als Standard - Verwenden Sie StatefulSets nur wenn wirklich nötig
  2. StatefulSets für Datenbanken - Datenbanken benötigen fast immer StatefulSets
  3. Backup-Strategie - StatefulSet-Volumes brauchen eine Backup-Strategie
  4. Pod Disruption Budgets - Setzen Sie PDBs für StatefulSets um Verfügbarkeit zu gewährleisten
  5. Headless Service - StatefulSets benötigen oft einen Headless Service für Pod-DNS

Siehe auch