Короткий ответ
StatefulSet даёт каждому Pod устойчивый порядковый номер и имя (например, db-0, db-1), сохраняет привязку к своему персистентному хранилищу между перезапусками и управляет запуском/остановкой в строгом порядке, тогда как Deployment создаёт взаимозаменяемые Pod со случайными именами.
Как это работает подробнее
StatefulSet использует шаблон имени <имя>-<порядковый номер> и, при указании volumeClaimTemplates, создаёт отдельный PersistentVolumeClaim для каждого Pod, который сохраняется даже при удалении и пересоздании конкретного Pod с тем же номером. Это нужно приложениям, где порядок запуска или устойчивость идентичности и данных имеют значение (базы данных, очереди сообщений с кворумом).
Пример кода
manifest.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata: { name: db }
spec:
serviceName: db
replicas: 3
selector: { matchLabels: { app: db } }
template:
metadata: { labels: { app: db } }
spec:
containers:
- name: db
image: postgres:16
volumeClaimTemplates:
- metadata: { name: data }
spec:
accessModes: ["ReadWriteOnce"]
resources: { requests: { storage: 10Gi } }Что использовать на практике
- Практика. StatefulSet обычно используют вместе с headless Service (
clusterIP: None), что даёт каждому Pod собственное DNS-имя видаdb-0.db.namespace.svc.cluster.localдля прямой адресации конкретного экземпляра — это важно для кластерных СУБД, где роли узлов (primary/replica) привязаны к конкретному инстансу.
Подводные камни
- Риски. использовать Deployment для кластеризуемой базы данных, ожидая, что каждый под сохранит "свои" данные при пересоздании — у Deployment нет устойчивой привязки тома к конкретной реплике; разворачивать в Kubernetes сложную stateful-систему без понимания, что это требует дополнительной экспертизы по сравнению с управляемым внешним сервисом базы данных.