Короткий ответ
При удалении Pod Kubernetes параллельно отправляет контейнеру сигнал SIGTERM и начинает исключать под из endpoints Service; у приложения есть время до истечения terminationGracePeriodSeconds (по умолчанию 30 секунд), чтобы корректно завершить текущие запросы и закрыть соединения, после чего, если процесс ещё жив, отправляется SIGKILL.
Как это работает подробнее
удаление из списка endpoints Service и отправка SIGTERM контейнеру происходят практически одновременно, но не атомарно — из-за распределённой природы системы (kube-proxy на разных узлах, разная задержка синхронизации) часть входящих соединений может прийти на под уже после получения им SIGTERM, но до того, как все узлы обновили свои правила маршрутизации. Поэтому приложению недостаточно просто мгновенно завершиться по SIGTERM — ему нужно продолжать обрабатывать уже начатые запросы (и желательно ещё немного новых) в течение короткого окна.
Пример кода
spec:
terminationGracePeriodSeconds: 60
containers:
- name: app
image: myapp:1.0
lifecycle:
preStop:
exec: { command: ["sh", "-c", "sleep 5"] }Что использовать на практике
- Практика. типичная правильная стратегия — по получении SIGTERM сразу перестать сообщать о готовности на readiness-эндпоинте (если он не завязан на то же самое), продолжить обработку уже принятых соединений, отклонять или закрывать новые медленно (не разрывая их грубо), и завершиться явно до истечения
terminationGracePeriodSeconds, не дожидаясь принудительного SIGKILL. Для приложений с длительными запросами стоит явно увеличитьterminationGracePeriodSecondsотносительно значений по умолчанию.
Подводные камни
- Риски. игнорировать SIGTERM в коде приложения и полагаться только на SIGKILL по истечении grace period — это обрывает соединения резко и может приводить к ошибкам на стороне клиента; задавать слишком короткий
terminationGracePeriodSecondsдля сервиса с долгими запросами (например, стриминг или батч-обработка), из-за чего корректные запросы прерываются принудительно ещё до завершения.