Питання 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 — для deadlock’ів, не для залежностей
  • 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 — інструмент боротьби з Deadlock’ами, не з залежностями.
  • 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 перевіряє БД і кеш» (зовнішні залежності → масове вбивство Pod’ів)
  • initialDelaySeconds=5 для Java-додатку (не встигне стартувати)
  • «Liveness = readiness» (різні цілі: liveness → restart, readiness → remove from traffic)
  • «Liveness не потрібна — K8s і так перезапустить» (K8s перезапускає тільки впалий контейнер, не завислий)

Пов’язані теми:

  • [[Що таке readiness probe]] — перевірка готовності до трафіку
  • [[Навіщо потрібні health checks]] — усі три проби разом
  • [[Як організувати rolling update в Kubernetes]] — health checks при деплої