Что такое StatefulSet и чем он отличается от Deployment?
Что такое StatefulSet
StatefulSet — это контроллер в Kubernetes для управления набором Pod’ов, которым нужна устойчивая идентичность и/или персистентное локальное хранилище. В отличие от Deployment/ReplicaSet, где реплики взаимозаменяемы, Pod’ы в StatefulSet обладают стабильными именами, стабильными сетевыми идентификаторами и (опционально) собственными PVC, привязанными к конкретному индексу (ordinal).
Ключевые гарантии StatefulSet
-
Стабильные имена Pod: Pod получают имена в виде <statefulset-name>-<ordinal> (например web-0, web-1), и этот формат сохраняется при перезапусках/пересозданиях.
-
Стабильные сетевые идентификаторы: при использовании headless Service у каждого Pod предсказуемый DNS-имя podname.servicename.namespace.svc.cluster.local.
-
Стабильное хранилище: при volumeClaimTemplates каждому Pod создаётся свой PVC (например data-web-0), который остаётся привязанным к этому ordinal и не переиспользуется для других Pod.
-
Упорядоченные операции: по умолчанию Pod создаются, обновляются и удаляются в порядке ordinal (OrderedReady) — контроллер дождётся, пока web-0 станет Ready, прежде чем создать web-1. Есть опция Parallel для параллельного управления.
Основные параметры и поведение
-
serviceName обычно указывает на headless Service (без ClusterIP) для DNS-based discovery.
-
volumeClaimTemplates — шаблоны PVC; Kubernetes автоматически создаёт PVC для каждого Pod-индекса.
-
podManagementPolicy: OrderedReady (дефолт) или Parallel.
-
updateStrategy: RollingUpdate (по-умолчанию) или OnDelete. RollingUpdate в StatefulSet обновляет Pod’ы по одному в порядке ordinals и ждёт readiness. Есть опция partition для частичного обновления (canary-like).
Пример (упрощённо)
apiVersion: apps/v1
kind: StatefulSet
metadata: { name: web }
spec:
serviceName: "web-headless"
replicas: 3
selector:
matchLabels: { app: web }
template:
metadata: { labels: { app: web } }
spec:
containers:
\- name: nginx
image: nginx
volumeMounts:
\- name: data
mountPath: /var/www
volumeClaimTemplates:
\- metadata: { name: data }
spec:
accessModes: \["ReadWriteOnce"\]
resources: { requests: { storage: 5Gi } }
В результате для web-0 будет PVC data-web-0, для web-1 — data-web-1 и т.д.
В чём ключевые отличия от Deployment
-
Идентичность vs взаимозаменяемость: Deployment создаёт взаимозаменяемые Pod’ы (stateless), StatefulSet — POD’ы с уникальной идентичностью.
-
Стабильность хранилища: StatefulSet умеет автоматически создавать per-pod PVC через volumeClaimTemplates. Deployment обычно использует общие PVC или динамическое PV, но не создаёт уникальные PVC для каждой реплики.
-
Порядок создания/удаления/обновления: Deployment —/не гарантирует/ упорядоченности, заменяет реплики по стратегии rolling, ориентируясь на ReplicaSet; StatefulSet по умолчанию делает это последовательно (ordinal).
-
Сетевые имена и discovery: StatefulSet интегрируется с headless Service для стабильных DNS-имён; у Deployment нет встроенной стабильной сетевой идентичности для каждого пода.
-
Сценарии использования: StatefulSet — для баз данных и кластерных систем (Cassandra, Zookeeper, CockroachDB, MySQL cluster и т.п.), где важны persistent storage и фиксированные идентификаторы; Deployment — для типичных stateless-сервисов (web, api).
-
Удаление и сохранность PVC: PVC, созданные volumeClaimTemplates, обычно не удаляются автоматически при удалении StatefulSet — это сделано, чтобы не терять данные; у Deployment такого поведения по умолчанию нет, потому что обычно используются другие подходы к хранению.
-
Поддержка масштабирования: при scale up/scale down StatefulSet создаёт/удаляет Pod’ы в конце (по высшему ordinal), Deployment просто поддерживает желаемое число реплик без порядка.
Когда использовать StatefulSet
-
Нужна стабильная сеть/идентичность пода (stateful clustering).
-
Требуются отдельные per-pod persistent volumes.
-
Нужен упорядоченный старт/остановка/обновление Pod’ов.