Вопрос 17 · Раздел 14

Что такое liveness probe?

Liveness probe -- K8s периодически (каждые N секунд) проверяет, жив ли контейнер. Если probe fails -- контейнер перезапускается.

Версии по языкам: English Russian Ukrainian

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 нужна?

  1. Deadlock detection — приложение зависло из-за блокировки потоков
  2. Утечка ресурсов — приложение деградировало и не восстанавливается
  3. Внутренние ошибки — критическая ошибка, после которой приложение не работает

Типы проверок: когда что использовать

Тип Когда использовать
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
... бесконечный цикл

Предотвращение:

  1. Startup Probe для warmup:
    startupProbe:
      httpGet:
     path: /actuator/health/liveness
     port: 8080
      periodSeconds: 10
      failureThreshold: 30   # 5 минут на старт
    
  2. Агрессивные thresholds:
    livenessProbe:
      initialDelaySeconds: 120
      periodSeconds: 20
      failureThreshold: 6     # 2 минуты до убийства
      timeoutSeconds: 15
    
  3. Отделение 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

  1. Stateful приложения с риском повреждения данных — перезапуск может усугубить
  2. Приложения с долгим graceful shutdown — K8s ждёт terminationGracePeriodSeconds
  3. Если 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 при деплое