Ответ
StatefulSet — это сложный ресурс для stateful-приложений (базы данных, очереди). Вот ошибки, которые я научился избегать на практике:
-
Отсутствие Headless Service: StatefulSet полагается на headless-сервис (
clusterIP: None) для создания стабильных DNS-записей вида<pod-name>.<svc-name>.<namespace>.svc.cluster.local. Без него pods не смогут находить друг друга по стабильным именам.# Обязательный сервис для StatefulSet apiVersion: v1 kind: Service metadata: name: cassandra-svc spec: clusterIP: None # Это headless-сервис selector: app: cassandra -
Некорректный
volumeClaimTemplate: Самая критичная часть. Ошибка вstorageClassNameилиaccessModes(например,ReadWriteOnceдля пода, которому нужно общее хранилище) приведёт к тому, что поды не запустятся. В моём проекте с Cassandra мы использовали fast SSD.volumeClaimTemplates: - metadata: name: cassandra-data spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "fast-ssd" resources: requests: storage: 100Gi -
Игнорирование
podManagementPolicy: По умолчанию используетсяOrderedReady— поды создаются и удаляются по одному в строгом порядке. Для приложений, которые могут запускаться параллельно (например, некоторые кэши), это излишне медленно. Можно установитьParallel.apiVersion: apps/v1 kind: StatefulSet spec: podManagementPolicy: Parallel # Ускоряет развёртывание -
Забыть про
terminationGracePeriodSeconds: Stateful-приложениям (как PostgreSQL или Kafka) нужно время для graceful shutdown — завершить транзакции, слить данные на диск. Слишком маленький grace period может привести к повреждению данных.spec: template: spec: terminationGracePeriodSeconds: 300 # 5 минут на graceful shutdown -
Предположение, что все поды всегда доступны: Приложения в StatefulSet должны быть спроектированы с учётом того, что реплики могут быть недоступны (например, во время обновления). Жёсткие зависимости в коде приложения (ожидание, что pod-0 всегда онлайн) приведут к сбоям.