Что такое liveness probe?
Liveness probe -- K8s периодически (каждые N секунд) проверяет, жив ли контейнер. Если probe fails -- контейнер перезапускается.
Junior уровень
Простое объяснение
Liveness Probe (Проба живучести) — это проверка, которую Kubernetes выполняет, чтобы убедиться, что приложение внутри контейнера работает нормально. Если проверка провалилась — K8s перезапускает контейнер.
Liveness probe – K8s периодически (каждые N секунд) проверяет, жив ли контейнер. Если probe fails – контейнер перезапускается.
Простая аналогия
Liveness Probe — как будильник, который проверяет, что вы проснулись. Если вы не отвечаете — кто-то приходит и будит вас снова (перезапускает).
Зачем это нужно?
Приложение может “зависнуть” — процесс работает, но не отвечает на запросы. Без Liveness Probe K8s будет считать Pod здоровым, хотя он бесполезен.
Типы проверок
1. HTTP GET — K8s стучится на URL, ждёт 200 OK:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
2. TCP Socket — проверяет, открыт ли порт:
livenessProbe:
tcpSocket:
port: 8080
3. Command (exec) — выполняет команду в контейнере:
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
Ключевые параметры
| Параметр | Что делает |
|---|---|
initialDelaySeconds |
Сколько ждать перед первой проверкой |
periodSeconds |
Как часто проверять |
failureThreshold |
Сколько провалов подряд до перезапуска |
timeoutSeconds |
Сколько ждать ответа |
Пример для Java-приложения
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60 # Java долго стартует
periodSeconds: 10
failureThreshold: 3
timeoutSeconds: 5
Что запомнить Junior-разработчику
- Liveness Probe проверяет, живо ли приложение
- При провале — контейнер перезапускается
- Не проверяйте внешние зависимости (БД) в liveness
- Для Java давайте большое initialDelaySeconds
- Spring Boot Actuator:
/actuator/health/liveness
Middle уровень
Когда Liveness Probe нужна?
- Deadlock detection — приложение зависло из-за блокировки потоков
- Утечка ресурсов — приложение деградировало и не восстанавливается
- Внутренние ошибки — критическая ошибка, после которой приложение не работает
Типы проверок: когда что использовать
| Тип | Когда использовать |
|---|---|
| httpGet | Web-приложения с HTTP endpoint |
| tcpSocket | Когда нет HTTP (БД, брокеры) |
| exec | Специфичные проверки внутри контейнера |
| grpc | gRPC сервисы (K8s 1.24+) |
Опасности неправильной настройки
Death Spiral (Спираль смерти):
- Приложение тормозит из-за высокой нагрузки
- Liveness Probe имеет короткий таймаут
- K8s убивает перегруженные Pod’ы
- Новые Pod’ы не успевают отвечать и тоже убиваются
- Система падает полностью
Решение:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 60
periodSeconds: 15
failureThreshold: 5 # Больше попыток
timeoutSeconds: 10 # Больше времени
// ⚠️ Агрессивные таймауты: initialDelaySeconds=5, periodSeconds=3, failureThreshold=1 // Приложение может не успеть стартовать → бесконечные перезапуски. // Для Java-приложений: initialDelaySeconds=60-120, periodSeconds=10.
Что НЕЛЬЗЯ проверять в Liveness
- БД — если БД упала, liveness убьёт все Pod’ы (хотя приложение исправно)
- Внешние API — временные проблемы не должны убивать Pod
- Кэш — кэш может быть временно недоступен
Liveness должна проверять только внутреннее состояние процесса.
Spring Boot Actuator
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
Spring Boot автоматически определяет liveness/readiness состояния.
Что запомнить Middle-разработчику
- Liveness Probe — для deadlocks, не для зависимостей
- Death Spiral — реальная опасность при агрессивных настройках
- Проверяйте только внутреннее состояние, не внешние сервисы
- Spring Boot:
/actuator/health/liveness— стандарт - failureThreshold и timeoutSeconds — буфер против ложных срабатываний
Senior уровень
Liveness Probe как механизм self-healing
Liveness Probe — это не просто “пинг”, а инструмент управления жизненным циклом приложения, который может как спасти систему, так и убить её.
Архитектура: как K8s выполняет Probe
kubelet (на Node):
every periodSeconds:
1. Wait initialDelaySeconds после старта
2. Execute probe (HTTP/TCP/exec/gRPC)
3. Если success → reset failure count
4. Если fail → increment failure count
5. Если failures >= failureThreshold → kill container
6. Container restart по restartPolicy
Death Spiral: детальный анализ
Timeline:
T+0: Нагрузка выросла в 10x
T+5: Pod'ы замедлились, response time > timeout
T+10: Liveness probe timeout → failure 1
T+20: Liveness probe timeout → failure 2
T+30: Liveness probe timeout → failure 3 → KILL
T+31: K8s перезапускает Pod
T+32: Pod ещё не прогрелся (JIT warmup)
T+42: Liveness probe снова fail → KILL
... бесконечный цикл
Предотвращение:
- Startup Probe для warmup:
startupProbe: httpGet: path: /actuator/health/liveness port: 8080 periodSeconds: 10 failureThreshold: 30 # 5 минут на старт - Агрессивные thresholds:
livenessProbe: initialDelaySeconds: 120 periodSeconds: 20 failureThreshold: 6 # 2 минуты до убийства timeoutSeconds: 15 - Отделение liveness от readiness:
```yaml
Liveness: только внутреннее состояние
livenessProbe: httpGet: path: /actuator/health/liveness port: 8080
Readiness: зависимости
readinessProbe: httpGet: path: /actuator/health/readiness port: 8080
### Java-специфика
**JVM Warmup:**
- JIT компиляция происходит "на лету"
- Первые запросы медленнее
- Liveness Probe может убить Pod до warmup
**Решение:**
- Startup Probe с большим timeout
- initialDelaySeconds >= время warmup (2-3 мин для Spring Boot)
**G1 GC и Stop-the-World:**
- Во время full GC JVM не отвечает
- Liveness Probe может интерпретировать как смерть
- timeoutSeconds должен быть > max GC pause
**Thread Deadlock Detection:**
```java
// Custom health endpoint
@GetMapping("/health/liveness")
public ResponseEntity<String> liveness() {
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long[] deadlockedThreads = bean.findDeadlockedThreads();
if (deadlockedThreads != null) {
return ResponseEntity.status(500).body("Deadlock detected");
}
return ResponseEntity.ok("OK");
}
Когда НЕ использовать Liveness Probe
- Stateful приложения с риском повреждения данных — перезапуск может усугубить
- Приложения с долгим graceful shutdown — K8s ждёт terminationGracePeriodSeconds
- Если restart дороже, чем downtime — иногда лучше manual intervention
Liveness probe НЕ говорит, готов ли Pod принимать трафик. Он только говорит, жив ли процесс. Для готовности – readiness probe.
gRPC Health Checking (K8s 1.24+)
livenessProbe:
grpc:
port: 9090
service: "grpc.health.v1.Health"
Стандартный протокол для gRPC сервисов.
Anti-patterns
ПЛОХО:
# Проверяет БД в liveness
livenessProbe:
httpGet:
path: /health?check=db,cache,api # ✗
ХОРОШО:
# Liveness: только процесс
livenessProbe:
httpGet:
path: /actuator/health/liveness
# Readiness: зависимости
readinessProbe:
httpGet:
path: /actuator/health/readiness
Резюме для Senior
- Liveness Probe — инструмент борьбы с Deadlocks, не с зависимостями.
- Death Spiral — реальная угроза при агрессивных настройках.
- Startup Probe для Java: защищает во время warmup.
- Timeout > max GC pause, иначе full GC = false positive kill.
- Разделяйте liveness (внутреннее состояние) и readiness (зависимости).
- Custom health endpoint для deadlock detection в Java.
- Liveness Probe может убить систему — настраивайте с осторожностью.
🎯 Шпаргалка для интервью
Обязательно знать:
- Liveness Probe проверяет «живо ли приложение»; при провале — перезапуск контейнера
- Типы: HTTP GET, TCP Socket, exec Command, gRPC (K8s 1.24+)
- Death Spiral — реальная угроза при агрессивных настройках (short timeout → kill → warmup → kill)
- Liveness НЕ должна проверять внешние зависимости (БД, API) — только внутреннее состояние
- Для Java: startupProbe защищает во время JIT warmup, timeout > max GC pause
- Spring Boot Actuator:
/actuator/health/liveness— стандартный endpoint - Разделяйте liveness (процесс жив) и readiness (готов к трафику)
Частые уточняющие вопросы:
- «Почему нельзя проверять БД в liveness?» — Если БД упала, liveness убьёт все Pod’ы; БД не восстановится
- «Death Spiral — что это?» — Агрессивные таймауты → kill → warmup → снова kill → бесконечный цикл
- «Зачем startupProbe для Java?» — JVM долго стартует; без startupProbe нужен огромный initialDelaySeconds
- «G1 GC и liveness?» — Full GC вызывает stop-the-world; timeout должен быть > max GC pause
Красные флаги (НЕ говорить):
- «Liveness проверяет БД и кэш» (внешние зависимости → массовый kill Pod’ов)
initialDelaySeconds=5для Java-приложения (не успеет стартовать)- «Liveness = readiness» (разные цели: liveness → restart, readiness → remove from traffic)
- «Liveness не нужна — K8s и так перезапустит» (K8s перезапускает только упавший контейнер, не зависший)
Связанные темы:
- [[Что такое readiness probe]] — проверка готовности к трафику
- [[Зачем нужны health checks]] — все три пробы вместе
- [[Как организовать rolling update в Kubernetes]] — health checks при деплое