Ответ
В Kubernetes основная ответственность за перезапуск контейнеров лежит на kubelet (на каждом узле) и контроллерах (например, Deployment). Вот как я настраиваю отказоустойчивость приложений.
1. Базовая политика перезапуска в Pod:
В спецификации Pod можно задать restartPolicy для контейнеров. Для рабочих нагрузок всегда используется Always.
spec:
containers:
- name: app
image: myapp:latest
restartPolicy: Always
Однако, для долгоживущих приложений я редко описываю Pod'ы напрямую, а использую контроллеры.
2. Использование контроллеров для самовосстановления:
- Deployment: Основной объект для stateless-приложений. Если Pod падает, ReplicaSet (часть Deployment) немедленно создаёт новый, чтобы поддерживать заданное количество реплик (
replicas).apiVersion: apps/v1 kind: Deployment metadata: name: app-deployment spec: replicas: 3 selector: matchLabels: app: myapp template: spec: containers: - name: app image: myapp:stable
3. Пробы жизнеспособности (Liveness Probes): Ключевой механизм для обнаружения "зависших" приложений. Kubelet периодически выполняет проверку и перезапускает контейнер, если проба fails.
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30 # Даём приложению время на старт
periodSeconds: 10
4. Пробы готовности (Readiness Probes): Отличаются от liveness. Если проба готовности fails, Pod исключается из балансировщика нагрузки Service, но не перезапускается. Это позволяет контейнеру восстановиться без потери трафика.
5. Мониторинг и алертинг:
Настраиваю Prometheus и Alertmanager для отслеживания частых перезапусков Pod'ов (метрика kube_pod_container_status_restarts_total). Частые рестарты — сигнал о проблеме в приложении или некорректных настройках проб.
Важно: Для stateful-приложений (StatefulSet) перезапуск контейнера в том же Pod'е обычно безопасен, так как том (volume) сохраняется. Полная гибель узла требует более сложных процедур восстановления, заложенных в логику самого Stateful-приложения.
Ответ 18+ 🔞
Давай разберём эту тему, а то тут некоторые думают, что кубер сам всё починит, как волшебная таблетка. Э сабака сука, нет, конечно.
Смотри, главный по базару на каждой ноде — это kubelet. Этот чувак следит за контейнерами в подах, как ястреб. Если контейнер вдруг накрылся медным тазом, kubelet его перезапускает. Но это только первая линия, базовый уровень, понимаешь?
1. Базовая настройка в самом Pod: restartPolicy
В манифесте пода есть такая штука — политика перезапуска. Для нормальных сервисов всегда ставь Always. Но честно? Я редко когда пишу голые Pod'ы в продакшене, это как ходить по охуенно тонкому льду. Только для каких-нибудь одноразовых задач.
spec:
containers:
- name: app
image: myapp:latest
restartPolicy: Always # Вот это самое оно
2. Контроллеры — наше всё. Особенно Deployment. Вот где начинается магия. Ты создаёшь Deployment, а он за тебя создаёт ReplicaSet, который уже плодит поды. Если один под сдох, ReplicaSet тут же видит, что реплик стало меньше, и создаёт новый, чтобы достичь нужного числа. Автоматически, блядь! Красота.
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3 # Хочешь три копии приложения? Будет три, ёпта!
selector:
matchLabels:
app: myapp
template:
spec:
containers:
- name: app
image: myapp:stable
Вот это и есть основа отказоустойчивости. Упала одна реплика — остальные две работают, а третью уже поднимают.
3. Liveness Probe — чтобы убить зависшее приложение.
А вот это, чувак, критически важная вещь. Без неё твоё приложение может лежать с пустыми глазами, не отвечать, но формально быть «живым». Kubelet будет тупо смотреть и ничего не делать. Нахуй так надо?
Ты настраивае пробу (чаще всего HTTP запрос на /health), и если она начинает фейлиться, kubelet без лишних слов прибивает контейнер и запускает новый. Жестко, но эффективно.
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30 # Даём время на старт, а то убьёт на взлёте!
periodSeconds: 10
4. Readiness Probe — чтобы не совать трафик в сдохший под. Важно не путать с liveness! Если readiness проба падает, под НЕ ПЕРЕЗАПУСКАЕТСЯ. Его просто выкидывают из балансировки Service. Трафик на него перестаёт идти, и у него есть шанс прийти в себя без давления. Если не пришёл — тогда уже liveness его добьёт. Две эти пробы работают в паре, как хитрая жопа.
5. Мониторинг. Без него ты слепой.
Настроил пробы, запустил деплоймент и расслабился? Какого хуя! Надо следить за метриками. Самая простая — kube_pod_container_status_restarts_total. Если видишь, что какой-то под перезапускается каждые пять минут — это пиздец, а не отказоустойчивость. Значит, проблема либо в кривом приложении, либо ты так настроил пробы, что они заебали здоровый сервис. Поднимаешь алерт в Alertmanager и идёшь разбираться.
И последнее, про StatefulSet. Для stateful-приложений (базы данных всякие) перезапуск контейнера в рамках одного пода — обычно ок, потому что том с данными остаётся. Но если вся нода легла, тут уже впендюрить новую ноду и примаунтить том — это история посерьёзнее, её надо в логике самого приложения прорабатывать.
Короче, суть в том, чтобы не надеяться на авось, а настроить эту связку: контроллеры + пробы + мониторинг. Тогда будет тебе и хиросима, и нигерсраки в одном флаконе, то есть отказоустойчивость.