В чем разница между Deployment и StatefulSet в Kubernetes?

«В чем разница между Deployment и StatefulSet в Kubernetes?» — вопрос из категории Kubernetes, который задают на 24% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Kubernetes Deployment и StatefulSet — это контроллеры для управления подами, но предназначены для принципиально разных типов приложений.

  • Deployment — для stateless-приложений (веб-серверы, API, workers). Поды взаимозаменяемы, не имеют устойчивой идентичности или привязанности к хранилищу.

    • Поведение: Создает поды с уникальными хэшированными именами (например, app-5f6d8b9c7). При обновлении (rolling update) старые поды удаляются, новые создаются в произвольном порядке.
    • Использование: Идеален для горизонтального масштабирования и CI/CD.
  • StatefulSet — для stateful-приложений (базы данных, Kafka, Zookeeper, etcd), где важны:

    1. Устойчивые идентификаторы: Поды получают предсказуемые имена (<statefulset-name>-0, -1, -2), которые сохраняются при перезапуске.
    2. Упорядоченное развертывание и масштабирование: Поды создаются и удаляются последовательно (0, 1, 2...). Это важно для формирования кластеров.
    3. Устойчивое хранилище: Использует volumeClaimTemplates для создания уникального PersistentVolume для каждого пода. При пересоздании пода он подключается к тому же тому.
    4. Стабильная сетевая идентичность: Каждый под получает стабильное DNS-имя: <pod-name>.<service-name>.<namespace>.svc.cluster.local.

Пример манифеста StatefulSet для базы данных:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgresql
spec:
  serviceName: postgresql-hl # Headless Service для сетевой идентичности
  replicas: 3
  selector:
    matchLabels:
      app: postgresql
  template:
    metadata:
      labels:
        app: postgresql
    spec:
      containers:
      - name: postgresql
        image: postgres:14
        env:
        - name: POSTGRES_PASSWORD
          valueFrom: { secretKeyRef: { name: postgres-secret, key: password } }
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates: # Шаблон для создания PVC для каждого пода
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi

Итог: Используйте Deployment для всего, что не требует устойчивого состояния. Используйте StatefulSet для любых приложений, которым нужны гарантии порядка, уникальные тома или стабильные сетевые идентификаторы.