Выберите продукт

Kubernetes probes: liveness, readiness и startup probe без боли

Probes в Kubernetes — базовый механизм стабильности: они управляют трафиком, рестартами и поведением при долгом старте. Разберём liveness/readiness/startup probe, типы проверок и тайминги, чтобы Deployment раскатывался предсказуемо и без лишних рестартов.
Kubernetes probes: liveness, readiness и startup probe без боли

Если кратко: probes — это встроенные проверки состояния контейнера, которыми kubelet и контроллеры (Deployment/ReplicaSet) пользуются, чтобы принимать решения: давать ли Pod трафик, перезапускать ли контейнер и как пережить «долгий старт» приложения без ложных рестартов. На практике правильно настроенные probes — один из самых дешёвых способов повысить стабильность раскаток без усложнения архитектуры.

Три проверки — три разных решения

Kubernetes предоставляет три вида probes:

  • readiness — «можно ли направлять трафик в этот Pod прямо сейчас?»
  • liveness — «жив ли процесс/контейнер, или его пора перезапустить?»
  • startup probe — «контейнер ещё стартует; пока не закончится — не применяйте к нему liveness/readiness»

Главная ошибка новичков — считать, что это одно и то же «healthcheck». На самом деле эти проверки отвечают на разные вопросы и должны быть построены по разным принципам.

Ментальная модель простая: readiness управляет трафиком, liveness управляет рестартами, startup защищает долгий старт от ложных рестартов.

Как Kubernetes реально использует probes

Важно понимать роли компонентов:

  • kubelet на ноде запускает проверки и принимает решение перезапустить контейнер при провале livenessProbe (и при провале startupProbe).
  • Endpoints/EndpointSlice и Service учитывают readinessProbe: неготовые Pod исключаются из балансировки.
  • Deployment во время rollout опирается на готовность Pod (через readiness): если новые Pod не становятся Ready, раскатка замирает или откатывается согласно вашей политике.

Отсюда следствие: readiness — это не «мониторинг», это часть маршрутизации. А liveness — не «проверка HTTP 200», а условие для принудительного самоисцеления через рестарт.

Схема: readiness управляет трафиком, liveness — рестартами, startup — периодом запуска

Readiness probe: выключатель трафика

readiness должен отвечать строго на вопрос: способно ли приложение обслужить запросы корректно сейчас. Если ответ «нет», Pod должен стать NotReady, чтобы Service перестал отправлять на него трафик.

Что проверять в readiness

Хорошие критерии:

  • приложение подняло listener и принимает соединения;
  • готовы зависимости, без которых запросы всё равно упадут (например, подключение к БД или завершение критичных миграций, если вы делаете их на старте);
  • прогрет критичный кеш или загружена конфигурация;
  • воркеры/очереди не в «panic» состоянии, если это веб+воркеры в одном контейнере.

Плохие критерии:

  • «проверим, что внешняя БД отвечает вообще всегда» — при временной деградации БД readiness может массово убрать все Pod из трафика и усилить инцидент;
  • тяжёлые проверки, которые ходят в несколько сервисов: это увеличивает латентность probe и риск флаппинга.

Типичная схема для HTTP

Для HTTP-приложений удобен отдельный endpoint вроде /readyz, который проверяет минимум: «сервер принимает запрос и способен отдать простой ответ».

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: app
        image: example/app:1.0
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /readyz
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 2
          failureThreshold: 3

Здесь Pod будет исключён из трафика после трёх подряд провалов readiness. Это часто лучше, чем «сразу выключить»: кратковременный GC-пауз или всплеск CPU не должен мгновенно ронять готовность.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Liveness probe: предохранитель от зависаний

liveness отвечает на вопрос: «контейнер в таком состоянии, что сам не восстановится, и проще его перезапустить». Это защита от deadlock, зависшего event-loop, утечек ресурсов, когда процесс формально жив, но запросы не обслуживаются.

Главное правило liveness

Не делайте liveness слишком умным. Чем умнее liveness, тем выше шанс перезапускать рабочий контейнер из-за проблем вне приложения (сеть, зависимость, короткий всплеск задержек). Лучше пусть liveness отражает «процесс жив и способен отвечать на минимальную проверку».

Типовые варианты:

  • tcpSocket — проверяет, что порт слушается (минимальный, но иногда слишком слабый сигнал);
  • httpGet — отвечает ли приложение быстро на лёгкий endpoint;
  • exec — локальная команда внутри контейнера (например, проверка файла/сокета).

Пример liveness с более «мягкими» порогами

Часто liveness делают менее чувствительным, чем readiness: пусть Pod сначала выйдет из трафика, а перезапуск случится только если проблема длится дольше.

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 20
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 6

При таких параметрах перезапуск произойдёт примерно через минуту стабильных провалов. За это время readiness успеет убрать Pod из балансировки, а система — пережить кратковременные проблемы без рестарта.

Startup probe: когда приложение стартует долго

startup probe закрывает распространённую боль: приложения, которые «долго поднимаются» (прогрев JIT, миграции, загрузка больших моделей, компиляция шаблонов), проваливают liveness в первые секунды или минуты и уходят в бесконечный цикл рестартов.

Механика простая: пока startupProbe не успешна, Kubernetes не считает контейнер «запущенным» и не применяет к нему liveness; readiness при этом не даст трафик, пока приложение реально не готово. Это позволяет честно дать время на инициализацию.

startupProbe:
  httpGet:
    path: /startupz
    port: 8080
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 30

Здесь Kubernetes даст контейнеру до 150 секунд на старт (5 секунд × 30 попыток). После успеха startup начинают действовать readiness и liveness.

Кому startup probe нужен почти всегда

  • Java/Spring, .NET, крупные Node.js приложения с миграциями на старте;
  • приложения, которые на старте проверяют внешние ресурсы и «раскачиваются»;
  • контейнеры, где первый запрос разогревает кеши/компиляцию.
FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Выбор типа проверки: HTTP, TCP или exec

Короткие практические рекомендации:

  • HTTP — лучший вариант для веб-приложений, если можете сделать лёгкий endpoint. Важно, чтобы он был быстрым и не делал тяжёлых запросов.
  • TCP — подходит для простых сервисов, где факт listening уже многое значит (например, прокси). Но TCP не отличит «порт слушается, а внутри всё умерло».
  • exec — полезен, когда нет HTTP, или нужно проверить локальный ресурс (например, наличие сокета). Минус: exec сложнее стандартизировать и тестировать, и он зависит от утилит внутри образа.

Тайминги: как не устроить флаппинг и лишние рестарты

Параметры, которые чаще всего ломают стабильность:

  • timeoutSeconds — слишком маленький таймаут даёт ложные провалы под нагрузкой;
  • periodSeconds — слишком частые проверки усиливают нагрузку и шанс поймать кратковременный лаг;
  • failureThreshold — слишком маленький порог создаёт «дёрганую» готовность и лишние перезапуски.

Практический подход:

  • Для readiness начните с periodSeconds 5–10 и failureThreshold 3–5.
  • Для liveness делайте проверку реже или порог выше, чем у readiness, чтобы сначала убрать Pod из трафика, а потом уже перезапускать.
  • Если старт «плавает» (то 10 секунд, то 60 секунд) — добавьте startupProbe и выбирайте окно с запасом по p95/p99 времени старта.

Нормальный порядок самовосстановления: Pod стал NotReady, нагрузка ушла; и только если не помогло — liveness перезапускает контейнер.

Как probes влияют на rollout и стабильность Deployment

На стабильность Deployment probes влияют напрямую:

  • Если readiness слишком строгий или нестабильный, новые Pod долго не становятся Ready, rollout «зависает».
  • Если liveness слишком агрессивный, Pod будут уходить в рестарты прямо во время раскатки, что выглядит как «Deployment не поднимается».
  • Startup probe часто является разницей между «всё катится» и «CrashLoopBackOff после каждого деплоя» для тяжёлых приложений.

Отдельно помните про terminationGracePeriodSeconds: при обновлениях и даунскейле Pod завершаются. Если приложение не умеет корректно закрывать соединения, readiness можно использовать как «быстро убрать из трафика», а дальше спокойно завершить воркеры. Практики аккуратного завершения и снятия готовности на stop-сигнале удобно реализовывать на уровне systemd/entrypoint; см. также материал про graceful readiness: как правильно снимать готовность при остановке сервиса.

Вывод kubectl describe pod с событиями о провалах readiness и liveness

Диагностика: как понять, какая probe ломает жизнь

Когда начинаются «плавающие» проблемы, действуйте по шагам:

  1. Посмотрите события Pod: что именно падает — readiness или liveness, и с каким сообщением.
  2. Проверьте частоту рестартов контейнера и причины: часто видно, что liveness убивает контейнер раньше, чем тот успевает подняться.
  3. Временно увеличьте timeoutSeconds и failureThreshold, чтобы отличить «реальную поломку» от «тайминги слишком жёсткие».
  4. Если проблема только на старте — добавьте startupProbe и пересмотрите initialDelaySeconds.
kubectl describe pod demo-xxxx
kubectl get pod demo-xxxx -o wide
kubectl logs demo-xxxx -c app --previous

Логи с --previous особенно полезны, когда контейнер перезапускается и вы не успеваете поймать момент.

Практические шаблоны: что ставить «по умолчанию»

Универсальных значений нет, но есть безопасные базовые шаблоны, от которых удобно плясать.

1) Быстрый веб-сервис (старт до 5–10 секунд)

readinessProbe:
  httpGet:
    path: /readyz
    port: 8080
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 3
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 6

2) Тяжёлый старт (30–180 секунд)

startupProbe:
  httpGet:
    path: /startupz
    port: 8080
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 36
readinessProbe:
  httpGet:
    path: /readyz
    port: 8080
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 3
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 6

Ключевой момент: startup даёт до 180 секунд (5 × 36) «иммунитета» от liveness, а readiness не даст Pod получить трафик раньше времени.

Антипаттерны, которые часто встречаются

  • Одинаковый endpoint и одинаковая логика для readiness и liveness. Это приводит к рестартам из-за временных проблем, которые лучше пережить без перезапуска.
  • Readiness зависит от внешней сети. Например, «проверим сторонний API». При сбое сети вы потеряете готовность всех Pod.
  • Слишком частые probes. periodSeconds 1 при неидеальном endpoint — прямой путь к лишней нагрузке и деградации.
  • timeoutSeconds = 1 на перегруженных нодах. Чаще безопаснее дать 2–5 секунд и подобрать пороги.

Чеклист перед продакшеном

  1. Есть ли отдельные endpoints под /readyz, /healthz, /startupz (или чётко разделённая логика)?
  2. Readiness выключает трафик достаточно быстро, но не флапает на коротких пиках.
  3. Liveness не перезапускает контейнер при кратковременной деградации и не зависит от внешних сервисов.
  4. Для долгого старта добавлен startupProbe с окном по p95/p99.
  5. Параметры проверены на реальной нагрузке (хотя бы на стейджинге) и не создают заметной нагрузки на сам сервис.

Итоги

Правильные probes — это не формальность в манифесте, а инструмент управления жизненным циклом Pod и стабильностью раскаток. В большинстве случаев, когда «вроде всё работает, но Deployment постоянно флапает», корень проблемы — в смешивании ролей readiness и liveness или в отсутствии startup probe для долгого старта. Начните с простых проверок, подберите тайминги по наблюдениям и дайте системе шанс сначала убрать Pod из трафика, а уже потом лечить рестартом.

Если вы катаете Kubernetes на собственных серверах, следите за ресурсами нод: дефицит CPU/IO часто проявляется именно как «random timeouts» в probes. Для небольших и средних кластеров удобнее держать предсказуемые ресурсы на VDS, а для вспомогательных веб-панелей и внутренних сервисов иногда достаточно виртуального хостинга.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: APT repository does not have a Release file — как исправить ошибку OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: APT repository does not have a Release file — как исправить ошибку

Ошибка APT repository does not have a Release file в Debian и Ubuntu обычно связана с неподдерживаемым репозиторием, неверным code ...
Debian/Ubuntu: SSH зависает на Connecting to — как найти и убрать задержку входа OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: SSH зависает на Connecting to — как найти и убрать задержку входа

Если SSH в Debian или Ubuntu зависает на этапе Connecting to, долго показывает banner или тормозит уже после ввода пароля, причина ...
Debian/Ubuntu: конфликт systemd-resolved DNSStubListener на 127.0.0.53 с dnsmasq, Unbound и BIND OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: конфликт systemd-resolved DNSStubListener на 127.0.0.53 с dnsmasq, Unbound и BIND

Если локальный DNS в Debian или Ubuntu не стартует с ошибкой address already in use, причина часто в systemd-resolved и DNSStubLis ...