Health checks: liveness и readiness пробы

Рейтинг: 61% · 6 голосов
Kubernetes для разработчиков: поды, деплойменты, сервисы, ingress, конфиги и отладка. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
anton_k8s
Сообщения: 26
Зарегистрирован: 12 май 2026, 03:23

Health checks: liveness и readiness пробы

Сообщение anton_k8s »

АкадемияKubernetes на практикеГлава 10 из 19
Оглавление курса (19)
  1. Зачем нужен Kubernetes и из чего состоит кластер
  2. Поднимаем локальный кластер: minikube и kind
  3. Поды: базовая единица запуска
  4. Deployment и ReplicaSet: управляем репликами
  5. Service: сетевой доступ к подам
  6. ConfigMap и Secret: выносим конфигурацию
  7. Ingress: пускаем трафик снаружи
  8. Хранилище: Volumes и PersistentVolumeClaim
  9. Namespaces, requests и limits
  10. Health checks: liveness и readiness пробы (вы здесь)
  11. Отладка: почему под не стартует
  12. Helm: пакетный менеджер для Kubernetes
  13. Базовая безопасность: RBAC и доступы
  14. Job и CronJob: разовые и периодические задачи
  15. StatefulSet и DaemonSet: stateful-нагрузки и системные агенты
  16. Стратегии обновления и планирование: rollout и rollback, graceful shutdown, nodeSelector, affinity, taints
  17. Автомасштабирование: HPA по метрикам, обзор VPA и Cluster Autoscaler
  18. Наблюдаемость: логи, метрики, events, обзор Prometheus и Grafana
  19. Безопасность глубже: securityContext, Pod Security Standards, NetworkPolicy, шифрование секретов
Deployment из четвертой главы следит, чтобы реплик было ровно столько, сколько вы попросили. Проблема в том, что по умолчанию Kubernetes считает под здоровым, пока жив процесс в контейнере. Сервис, зависший в дедлоке, с точки зрения kubelet ничем не отличается от рабочего, и трафик на него продолжает идти. Пробы закрывают этот разрыв: они объясняют кластеру, как отличить живое приложение от мертвого и готовое к трафику от еще прогревающегося.

Три вида проб:

livenessProbe отвечает на вопрос "жив ли процесс". Если проверка проваливается несколько раз подряд, kubelet перезапускает контейнер. readinessProbe отвечает на вопрос "готов ли под принимать трафик". Пока она красная, под исключен из эндпоинтов Service (глава 5), но контейнер никто не трогает. startupProbe придумана для медленно стартующих приложений: пока она не пройдет, две остальные пробы не запускаются вовсе.

Механизм проверки у всех трех общий, на выбор: httpGet (запрос на порт контейнера, успех при ответе 200-399), tcpSocket (достаточно открыть соединение), exec (команда внутри контейнера, успех при коде возврата 0) и grpc для сервисов со стандартным grpc.health.v1.Health (стабильно с Kubernetes 1.27).

Подключаем к Deployment:

Код: Выделить всё

apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: orders-api
  template:
    metadata:
      labels:
        app: orders-api
    spec:
      containers:
      - name: app
        image: orders-api:1.8.2
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          periodSeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 2
Параметры: periodSeconds задает частоту опроса, по умолчанию 10 секунд. timeoutSeconds, то есть ожидание ответа, по умолчанию всего 1 секунда, и это частая причина ложных срабатываний. failureThreshold определяет, сколько провалов подряд считать отказом, по умолчанию 3. Есть еще successThreshold (для readiness можно требовать несколько успехов подряд, для liveness и startup он всегда 1) и initialDelaySeconds, пауза перед первой проверкой.

Эндпоинты в примере разные, и это принципиально. /healthz для liveness отвечает только за сам процесс: запрос дошел до обработчика, значит процесс жив. Никаких проверок базы или внешних API там быть не должно. Если liveness ходит в PostgreSQL и база легла, kubelet примется перезапускать все поды по кругу. Базе от этого легче не станет, а у вас вместо одной проблемы будет две. /ready, наоборот, может смотреть глубже: есть ли соединение с базой, прогрет ли кэш, применились ли миграции.

Медленный старт и воркеры без HTTP:

Приложению на JVM или сервису с прогревом кэша за десять секунд не подняться. Для таких случаев startupProbe:

Код: Выделить всё

        startupProbe:
          httpGet:
            path: /healthz
            port: 8080
          periodSeconds: 5
          failureThreshold: 30
Здесь на запуск дается до 150 секунд (30 попыток по 5 секунд). Как только проба прошла, включаются обычные liveness и readiness. Это честнее, чем initialDelaySeconds: 120, потому что быстрый старт не наказывается лишним ожиданием.

У фонового воркера может вообще не быть HTTP порта. Выручает exec и прием с heartbeat файлом: процесс периодически обновляет файл, а проба проверяет его свежесть.

Код: Выделить всё

        livenessProbe:
          exec:
            command: ["sh", "-c", "find /tmp/heartbeat -mmin -1 | grep -q ."]
          periodSeconds: 30
          timeoutSeconds: 5
За пробами удобно следить через события пода:

Код: Выделить всё

kubectl describe pod orders-api-6f7c9d4b58-x2m4p
kubectl get pods -l app=orders-api -w
Провалы liveness видны в Events как Unhealthy, и растет счетчик RESTARTS. Провалы readiness контейнер не трогают, но колонка READY показывает 0/1, и трафик на под не идет.

Типичные грабли:

Внешние зависимости в liveness, про это уже было выше, но наступают на эти грабли постоянно. Дефолтный timeoutSeconds в 1 секунду: под нагрузкой пауза GC или медленный диск съедают ее целиком, и начинаются рестарты на ровном месте, ставьте 3-5 секунд. Один эндпоинт на обе пробы: работает до первого случая, когда под надо вывести из-под трафика, не убивая его. Readiness, завязанная на общую зависимость, способна уронить сервис целиком: база моргнула на десять секунд, все поды разом выпали из эндпоинтов, и пользователи получили полный отказ вместо ошибок на части запросов. И последнее: проба должна быть дешевой. healthz, который дергает три соседних сервиса и пишет подробные логи, при опросе раз в 5 секунд с каждой реплики сам превращается в источник нагрузки.

Итог:

liveness перезапускает зависшее, readiness управляет трафиком, startup дает время на разгон. Liveness смотрит только на сам процесс, readiness может проверять зависимости, но осознанно. Частые рестарты из-за проваленной liveness выглядят в kubectl get pods как CrashLoopBackOff, и в следующей главе про отладку разберем, как отличить такой случай от пода, который не стартует по другим причинам.
👍2 ❤️3 🔥3 😄 🤔1
✔ Лучший ответ сформирован автоматически — patton1941
anton_k8s писал(а):Никаких проверок базы или внешних API там быть не должно а как тогда поймать деградацию? у нас liveness как раз пингует постгрес, живем так года полтора и вроде норм. получается правильный путь это алерты из прометеуса, а кубер пусть смотрит только за процессом? страшновато убирать, вдруг зависшие коннекты к базе перестанем ловить
Перейти к ответу →
Аватара пользователя
patton1941
Сообщения: 1
Зарегистрирован: 24 май 2026, 01:12

Re: Health checks: liveness и readiness пробы

Сообщение patton1941 »

✔ Лучший ответ — сформирован автоматически
anton_k8s писал(а):Никаких проверок базы или внешних API там быть не должно
а как тогда поймать деградацию? у нас liveness как раз пингует постгрес, живем так года полтора и вроде норм. получается правильный путь это алерты из прометеуса, а кубер пусть смотрит только за процессом? страшновато убирать, вдруг зависшие коннекты к базе перестанем ловить
👍2 ❤️1 🔥 😄 🤔
Аватара пользователя
chimps
Сообщения: 1
Зарегистрирован: 14 май 2026, 05:31

Re: Health checks: liveness и readiness пробы

Сообщение chimps »

для спринговиков подсказка: в boot начиная с 2.3 есть готовые /actuator/health/liveness и /actuator/health/readiness, в кубере они включаются сами, локально через management.endpoint.health.probes.enabled=true. месяц назад выкинул самописный healthz в пользу этих, полет нормальный
👍 ❤️1 🔥 😄 🤔
Аватара пользователя
Martti
Сообщения: 1
Зарегистрирован: 21 май 2026, 13:56

Re: Health checks: liveness и readiness пробы

Сообщение Martti »

а если у меня gunicorn с парой sync воркеров? во время долгого запроса он на healthz не ответит, и кубер его прибьет получается. повышать failureThreshold или это лечится только переходом на gthread/async?
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
machismo
Сообщения: 2
Зарегистрирован: 22 май 2026, 19:35

Re: Health checks: liveness и readiness пробы

Сообщение machismo »

спасибо за трюк с heartbeat файлом. селери воркеры у нас висли молча по ночам, до утра никто не замечал. прикрутил такую пробу, за две недели два честных авторестарта вместо утреннего разбора полетов руками
👍 ❤️1 🔥2 😄 🤔1
Ответить
← Предыдущая глава
Namespaces, requests и limits
Следующая глава →
Отладка: почему под не стартует

Все главы курса «Kubernetes на практике»

Поделиться темой: ✈ Telegram VK
  • Похожие темы

Вернуться в «Kubernetes на практике»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость