Работали ли вы с StatefulSet в Kubernetes?

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

Ответ

Да, я использовал StatefulSet для развертывания stateful-приложений, таких как базы данных (PostgreSQL, MongoDB) и брокеры сообщений (Kafka, RabbitMQ).

Основные особенности, с которыми я работал:

  • Устойчивые идентификаторы Pod: Каждый Pod получает стабильное имя вида <statefulset-name>-<ordinal> (например, postgresql-0, postgresql-1), которое сохраняется при перезапусках.
  • Упорядоченное развертывание и масштабирование: Pod'ы создаются и удаляются в строгом порядке, что критично для инициализации кластеров (например, master-узел должен запуститься первым).
  • Устойчивое хранилище: Использование volumeClaimTemplates гарантирует, что каждый Pod получит свой уникальный PersistentVolume, который следует за Pod'ом при ресхедулинге.
  • Стабильный сетевой идентификатор: Headless Service (clusterIP: None) предоставляет стабильные DNS-имена для каждого Pod'а, что необходимо для формирования кластера.

Пример манифеста для развертывания PostgreSQL с репликацией:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgresql
spec:
  serviceName: postgresql-hl
  replicas: 3
  selector:
    matchLabels:
      app: postgresql
  template:
    metadata:
      labels:
        app: postgresql
    spec:
      containers:
      - name: postgresql
        image: postgres:15
        env:
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgres-secret
              key: password
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "gp3"
      resources:
        requests:
          storage: 20Gi
---
apiVersion: v1
kind: Service
metadata:
  name: postgresql-hl
spec:
  clusterIP: None
  selector:
    app: postgresql

На практике важно правильно настраивать storageClassName, политики ретраев (podManagementPolicy) и учитывать сложности с резервным копированием распределенного состояния.