Короткий ответ
Скорее всего новый под не проходит readinessProbe и поэтому никогда не становится Ready, из-за чего Kubernetes не продолжает заменять оставшиеся старые поды — нужно посмотреть `kubectl describe pod` на новый под, проверить `Events` (например, `Readiness probe failed: HTTP probe failed with statuscode: 500`) и логи приложения, чтобы понять, что именно не проходит проверку, затем либо исправить код/конфигурацию, либо явно откатить обновление.
Как это работает подробнее
rolling update продолжает заменять старые поды новыми только после того, как ранее созданные новые поды подтвердят готовность через readinessProbe; если новый под навсегда остаётся NotReady (например, из-за недоступной зависимости при старте, неверного пути health check endpoint или слишком строгого таймаута пробы), Deployment «застревает», не превышая настроенный `maxUnavailable`, и старые поды продолжают обслуживать трафик — это защитный механизм, не баг.
Пример кода
$ kubectl get pods
myapp-v2-xyz 0/1 Running 0 6m <- new, not Ready
myapp-v1-abc 1/1 Running 0 2h <- old, still serving traffic
$ kubectl describe pod myapp-v2-xyz
Warning Unhealthy Readiness probe failed: HTTP probe failed with statuscode: 500Что использовать на практике
- На практике. диагностику начинают с `kubectl get pods` (статус `Running` но `0/1 Ready`), затем `kubectl describe pod ` для событий пробы и `kubectl logs ` для прикладных ошибок. Частая причина — миграция БД ещё не применена, а новый код уже ожидает новую схему, или health check endpoint изменил путь/порт в новой версии без согласования с манифестом.
- Пример. Ожидаемое поведение после исправления (например, добавления недостающей переменной окружения, которую требует health check): новый под переходит в `1/1 Ready`, после чего rollout автоматически продолжает замену оставшихся старых подов до полного завершения.
Подводные камни
- Частые ошибки. увеличивают `initialDelaySeconds` пробы «на всякий случай», не выяснив реальную причину сбоя, что просто откладывает обнаружение проблемы; вручную удаляют зависший под, ожидая, что это поможет — Kubernetes просто создаст новый под с той же проблемой.