← Back to notes

Probes: liveness,
readiness, startup


Контейнер в состоянии Running не означает, что приложение работает корректно: процесс может зависнуть, не завершить инициализацию или потерять соединение с БД. Probes дают kubelet сигнал о реальном состоянии приложения.

[source: kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes]

Три типа проб

livenessProbe

Проверяет, жив ли процесс. Если проверка проваливается — kubelet перезапускает контейнер. Применяется, когда приложение может зависнуть (deadlock, бесконечный цикл), но процесс продолжает работать.

spec:
  containers:
    - name: app
      image: myapp:1.0
      livenessProbe:
        httpGet:
          path: /healthz
          port: 8080
        initialDelaySeconds: 10
        periodSeconds: 15
        timeoutSeconds: 3
        failureThreshold: 3

readinessProbe

Проверяет, готово ли приложение принимать трафик. При провале Pod убирается из EndpointSlice Service (трафик перестаёт поступать), контейнер не перезапускается. Применяется при загрузке кеша, прогреве соединений, инициализации данных.

spec:
  containers:
    - name: app
      image: myapp:1.0
      readinessProbe:
        httpGet:
          path: /ready
          port: 8080
        initialDelaySeconds: 5
        periodSeconds: 10
        timeoutSeconds: 2
        failureThreshold: 3
        successThreshold: 1

startupProbe

Проверяет, завершился ли запуск. Пока startupProbe не пройдёт — livenessProbe и readinessProbe не запускаются. Для приложений с долгой инициализацией: загрузка ML-моделей, прогрев кеша, миграции при старте.

spec:
  containers:
    - name: app
      image: myapp:1.0
      startupProbe:
        httpGet:
          path: /healthz
          port: 8080
        periodSeconds: 10
        failureThreshold: 30    # 30 × 10 = 300 секунд максимум на запуск
      livenessProbe:
        httpGet:
          path: /healthz
          port: 8080
        periodSeconds: 15
        timeoutSeconds: 3
        failureThreshold: 3

Без startupProbe для медленного приложения приходится ставить большой initialDelaySeconds у livenessProbe — это маскирует реальные зависания после старта.

Методы проверки

httpGet

HTTP GET запрос. Успех — код ответа 200–399.

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
    httpHeaders:
      - name: X-Custom-Header
        value: healthcheck

tcpSocket

Проверка TCP-соединения. Успех — порт открыт и принимает соединения.

livenessProbe:
  tcpSocket:
    port: 3306

Подходит для сервисов без HTTP-эндпоинта: базы данных, кеши.

exec

Выполнение команды внутри контейнера. Успех — exit code 0.

livenessProbe:
  exec:
    command:
      - cat
      - /tmp/healthy

grpc

Проверка через gRPC Health Checking Protocol (K8s 1.24+, GA в 1.27):

livenessProbe:
  grpc:
    port: 50051
    service: "grpc.health.v1.Health"

[source: kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-grpc-liveness-probe]

Параметры проб

Полный пример со всеми пробами

apiVersion: v1
kind: Pod
metadata:
  name: robust-app
spec:
  containers:
    - name: app
      image: myapp:1.0
      ports:
        - containerPort: 8080
      startupProbe:
        httpGet:
          path: /healthz
          port: 8080
        periodSeconds: 5
        failureThreshold: 60      # до 5 минут на запуск
      livenessProbe:
        httpGet:
          path: /healthz
          port: 8080
        periodSeconds: 15
        timeoutSeconds: 3
        failureThreshold: 3
      readinessProbe:
        httpGet:
          path: /ready
          port: 8080
        periodSeconds: 10
        timeoutSeconds: 2
        failureThreshold: 3
        successThreshold: 1

Сводка: три пробы

Когда использовать

livenessProbe — для приложений, которые могут зависнуть без падения процесса.

readinessProbe — для любого приложения, принимающего трафик. Без неё Pod попадает в EndpointSlice сразу после старта контейнера — пользователи получают 502/503.

startupProbe — для приложений с initialDelaySeconds у livenessProbe > 30 секунд. Заменяет костыль с большим initial delay на явную проверку старта.

/healthz для liveness должен проверять только внутреннее состояние (deadlock, corrupted state). /ready для readiness может проверять внешние зависимости (соединение с БД, наполненность кеша).

Типичные ошибки

livenessProbe проверяет внешние зависимости. Если liveness проверяет подключение к БД — при её недоступности все Pod начнут перезапускаться, усугубляя ситуацию. liveness должна проверять только внутреннее состояние процесса.

failureThreshold = 1 у livenessProbe. Один сетевой сбой или GC-пауза — и контейнер перезапускается. Минимум failureThreshold: 3.

readinessProbe не настроена. Pod сразу получает трафик — пользователи видят ошибки пока приложение инициализируется.

Нет startupProbe у медленного приложения. При initialDelaySeconds: 120 liveness потом проверяет каждые 10-15 секунд — зависание обнаруживается с задержкой.

timeoutSeconds слишком мал. По умолчанию 1 секунда. Если эндпоинт иногда отвечает за 1.5 секунды под нагрузкой — probe ложно фейлит. Ставь 2-3 секунды.

Один эндпоинт для liveness и readiness. Смешивать — значит либо рестартовать при проблемах с БД, либо не убирать из ротации неготовый Pod.

Альтернативы

Readiness на основе метрик Prometheus (lag очереди, error rate) вместо HTTP 200. Требует кастомной логики в приложении.

Lifecycle hooks (postStart, preStop) — дополняют probes: preStop даёт приложению время завершить обработку запросов перед остановкой контейнера.

lifecycle:
  preStop:
    exec:
      command: ["sh", "-c", "sleep 5"]  # дать время на drain соединений

09: Volumes

11: StatefulSet и DaemonSet

Probes: liveness, readiness, startup | Aleksandr Suprun