Ответ
В 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-приложения.