В конфигурации StatefulSet реплика с индексом 0 не становится Ready, поэтому остальные реплики не появляются. Как параметр управления подами объясняет это поведение?
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: worker
spec:
serviceName: worker
replicas: 3
podManagementPolicy: OrderedReady
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
spec:
containers:
- name: worker
image: example/worker:1.0
readinessProbe:
httpGet:
path: /ready
port: 8080
Параметр podManagementPolicy: OrderedReady заставляет StatefulSet создавать реплики последовательно: сначала worker-0, затем worker-1 и worker-2. Пока worker-0 не перейдёт в состояние Ready, контроллер не создаст следующую реплику.
Если реплики независимы и не требуют запуска в порядке индексов, можно использовать podManagementPolicy: Parallel. Это разрешит создавать и удалять поды без ожидания готовности предыдущих, но не изменит порядок обновления StatefulSet.
Обычный Deployment ориентирован на взаимозаменяемые экземпляры приложения. Для баз данных, очередей и других распределённых систем этого часто недостаточно: экземплярам могут требоваться стабильные имена, порядковые идентификаторы и предсказуемый запуск.
StatefulSet появился как контроллер для таких рабочих нагрузок. Последовательный режим по умолчанию помогает системам, где следующий узел должен подключаться после инициализации предыдущего или где одновременный запуск создаёт риск конкуренции за лидерство и данные.
В приведённой конфигурации readiness-проба проверяет, готов ли конкретный процесс принимать работу. Если worker-0 завис на миграции, ждёт восстановления зависимости или неправильно настроен, его состояние останется неготовым.
При OrderedReady это блокирует создание worker-1 и worker-2. Следствием может стать длительный неполный запуск кластера, хотя ресурсов на узлах достаточно. Увеличение числа реплик не поможет, потому что ограничение задаётся политикой управления, а не планировщиком ресурсов.
Контроллер StatefulSet создаёт поды с порядковыми именами и отслеживает их состояние. В режиме OrderedReady он ждёт, пока предыдущий под станет готовым, прежде чем перейти к следующему. Это обеспечивает детерминированный запуск, но превращает проблему одной реплики в блокировку всей цепочки.
В режиме Parallel контроллер не ждёт готовности пода с меньшим индексом при создании остальных реплик. Минимальная конфигурация выглядит так:
Переключение на Parallel оправдано, когда экземпляры не зависят друг от друга при старте. Цена решения — отказ от встроенной последовательности: приложение само должно корректно обрабатывать одновременную инициализацию, выбор лидера, миграции и конкуренцию за общие ресурсы.
Важно не путать управление жизненным циклом подов с обновлением образа. podManagementPolicy определяет главным образом порядок создания и удаления подов; стратегия RollingUpdate StatefulSet имеет отдельные правила и обычно обновляет реплики в обратном порядковом направлении.
Readiness-проба также не запускает и не перезапускает контейнер. Она только сообщает, можно ли направлять на под трафик и считать ли его готовым для зависимостей StatefulSet. Для поиска причины нужно отдельно проверять логи, события пода, состояние зависимостей и корректность самой пробы.
В кластере разворачивался пул обработчиков, где каждый экземпляр имел собственный идентификатор, но не зависел от готовности соседей. Первый вариант использовал OrderedReady: один повреждённый конфигурационный файл в worker-0 остановил запуск всех остальных экземпляров.
Рассматривались три варианта. Deployment дал бы параллельный запуск, но убрал бы стабильные имена StatefulSet. Сохранение OrderedReady обеспечило бы безопасную последовательность, однако требовало бы исправить первый экземпляр и оставляло бы ту же точку блокировки. Переход на Parallel сохранил идентичность StatefulSet и снял ненужную зависимость между репликами.
Выбрали Parallel, а инициализацию каждого обработчика сделали идемпотентной. В результате отказ одной реплики больше не задерживал запуск остальных, а мониторинг readiness отдельно показывал неисправный экземпляр.
Parallel, что все поды обязательно запустятся одновременно?Нет. Parallel снимает требование последовательной готовности, но не отменяет работу планировщика Kubernetes. Поды могут запускаться с задержкой из-за нехватки ресурсов, ограничений размещения, проблем с образом, томом или сетью.
OrderedReady для реплик, которым не нужен порядок запуска?Любая проблема ранней реплики может заблокировать всю последующую цепочку. Это повышает время масштабирования и восстановления, усложняет диагностику и создаёт ложное впечатление нехватки ресурсов.
OrderedReady, что приложение внутри пода полностью инициализировано?Нет. StatefulSet ориентируется на состояние Ready, которое определяется readiness-пробой и условиями Kubernetes. Если проба слишком поверхностная, под может считаться готовым до завершения внутренней инициализации; если она чрезмерно строгая или неверно настроена, запуск следующих реплик будет необоснованно заблокирован.