Learning Platform
Глоссарий Troubleshooting
Урок 13.05 · 22 мин
Средний
ProbesYAMLproductionexamplesCKAD

Production-ready probe configurations

Готовые шаблоны probes для типовых сценариев. Каждый шаблон — компромисс между «достаточно быстро ловит проблемы» и «не создаёт false-positive restart-ов». На CKAD можно использовать как заготовки — запоминайте структуру, корректируйте параметры под задачу.


Monitoring Stack Kafka: JMX + Prometheus + Grafana

Web app (Node.js / Python / Go)

Стандартный HTTP сервис с разделёнными health endpoints:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels: {app: web}
  template:
    metadata:
      labels: {app: web}
    spec:
      containers:
      - name: web
        image: example/web:1.4.2
        ports:
        - name: http
          containerPort: 8080
        startupProbe:
          httpGet:
            path: /healthz
            port: http
          failureThreshold: 30
          periodSeconds: 10
          # max startup 5 минут
        readinessProbe:
          httpGet:
            path: /ready
            port: http
          periodSeconds: 5
          failureThreshold: 3
          successThreshold: 1
        livenessProbe:
          httpGet:
            path: /healthz
            port: http
          periodSeconds: 20
          failureThreshold: 3
          timeoutSeconds: 3

Эндпойнты в коде:

  • /healthz — возвращает 200 если процесс жив. Никаких внешних запросов. Используется и startup, и liveness.
  • /ready — возвращает 200 если БД pool инициализирован, кэш прогрет, миграции применены. Используется readiness.
NOTE

В port: http использован named port из containers.ports[].name. Если порт в Deployment изменится — probe и Service синхронно подхватят. Магический integer 8080 в трёх probes легко рассинхронизировать при правках.


gRPC service

С v1.27 — native gRPC probe:

spec:
  containers:
  - name: grpc-server
    image: example/grpc-server:2.1
    ports:
    - name: grpc
      containerPort: 9090
    readinessProbe:
      grpc:
        port: 9090
        service: ""    # default — overall server health
      periodSeconds: 5
      failureThreshold: 2
    livenessProbe:
      grpc:
        port: 9090
      periodSeconds: 20
      failureThreshold: 3

Приложение должно implement grpc.health.v1.Health/Check. На Go — grpc.health.NewServer() + healthpb.RegisterHealthServer. На Python — grpc_health.v1.health.HealthServicer. Просто открытый порт на 9090 не подойдёт — kubelet ждёт ответ SERVING.

Для кластеров до v1.27 — exec с grpc-health-probe:

readinessProbe:
  exec:
    command: ["/bin/grpc_health_probe", "-addr=:9090"]
  periodSeconds: 5

Это требует, чтобы бинарь grpc_health_probe был встроен в image.


TCP-only legacy service

Сервис без HTTP/gRPC — например, custom binary protocol на порту 5000:

spec:
  containers:
  - name: legacy
    image: example/legacy:1.0
    ports:
    - name: tcp
      containerPort: 5000
    readinessProbe:
      tcpSocket:
        port: tcp
      periodSeconds: 10
      failureThreshold: 3
    livenessProbe:
      tcpSocket:
        port: tcp
      periodSeconds: 30
      failureThreshold: 3
WARNING

tcpSocket даёт минимум информации — только «listener открыт». Если у legacy app есть способ проверки протокол-уровня (CLI-команда), лучше exec с этой командой — больше сигнала.


Batch worker (нет HTTP endpoint)

Воркер, читающий из очереди. HTTP нет, но процесс должен сигнализировать своё состояние через файл-флаг:

spec:
  containers:
  - name: worker
    image: example/worker:3.0
    livenessProbe:
      exec:
        command: ["sh", "-c", "test -f /tmp/healthy && find /tmp/healthy -mmin -1 | grep -q ."]
      periodSeconds: 30
      failureThreshold: 3
    readinessProbe:
      exec:
        command: ["test", "-f", "/tmp/ready"]
      periodSeconds: 10

Логика: worker touch /tmp/healthy каждые 10 секунд в основном loop. probe проверяет, что файл существует и был обновлён в последнюю минуту. Если worker завис — файл не обновляется → find -mmin -1 пустой → probe fail.

/tmp/ready создаётся один раз после init и удаляется при graceful shutdown — readiness signal.


Database (StatefulSet, PostgreSQL пример)

PostgreSQL внутри StatefulSet. Используем встроенные утилиты:

spec:
  containers:
  - name: postgres
    image: postgres:16
    ports:
    - name: pg
      containerPort: 5432
    readinessProbe:
      exec:
        command:
        - sh
        - -c
        - exec pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"
      periodSeconds: 5
      failureThreshold: 3
    livenessProbe:
      exec:
        command:
        - sh
        - -c
        - exec pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"
      periodSeconds: 30
      failureThreshold: 6
      timeoutSeconds: 5

Заметьте:

  • exec команда обёрнута в sh -c — нужен для подстановки ${POSTGRES_USER} и ${POSTGRES_DB}. Прямой pg_isready без shell не сможет ENV-substitution выполнить.
  • failureThreshold: 6 на liveness — БД может быть занята checkpoint-ом или vacuum, не рестартуем сразу.
  • pg_isready — лёгкий, никаких реальных запросов, просто accept TCP + simple protocol handshake.

Killer момент: split health endpoints

Главный паттерн production probes — три разных endpoint в коде приложения:

Три endpoint, три probe
/healthz → livenessProbeСамый простой: возвращает 200 если HTTP server отвечает. Без проверки БД, кэша, downstream. Цель: detect process hang, не detect degradation. FAIL → restart, поэтому максимально консервативно.
/ready → readinessProbeМожно ли обслуживать запросы прямо сейчас. Проверяет: БД pool готов, кэш прогрет, миграции применены, critical direct deps OK. FAIL → out of Endpoints. App keeps running.
/startup → startupProbeОпциональный, часто == /ready. Полезен когда startup-критерий строже ready (например, миграции выполнены — проверять каждые 5 секунд не нужно, но один раз на старте — да).

Если в команде нет конвенции — договоритесь о ней. Это лучшая инвестиция в стабильность сервиса. Стандарт /healthz пришёл из Google SRE practices и стал de-facto во всём Kubernetes-экосистеме.


CKAD: типовое задание

Условие: дан Deployment web без probes. Image слушает HTTP на 8080, endpoint /health возвращает 200 если app готов. Добавить readiness probe на /health, port 8080, периодически каждые 5 секунд, 3 fail для unhealthy.

Решение:

kubectl edit deployment web

В spec.template.spec.containers[0] добавить:

readinessProbe:
  httpGet:
    path: /health
    port: 8080
  periodSeconds: 5
  failureThreshold: 3

Проверка:

kubectl get pod -l app=web
# READY 1/1 — readiness PASS
kubectl describe pod <name> | grep -A5 Readiness
WARNING

На CKAD НЕ забывайте про indentation внутри YAML. probe идёт ВНУТРЬ containers[]., а не в spec.template.spec. напрямую. Типовая ошибка — вставить probe на уровне Pod spec, kubelet проигнорирует, контейнер останется без probes.


Проверка знанийKnowledge check
В вашем Deployment три probes ссылаются на 'port: 8080'. Через месяц вы меняете контейнер на новый image, который слушает на 8081. Что произойдёт и как избежать?
ОтветAnswer
Если забыть обновить probes — kubelet будет стучаться на 8080, connection refused, probe fail, restart loop. Избежать: использовать named port. В containers.ports указать name: http, в probe — port: http (по имени). При смене порта меняется только containers.ports[0].containerPort, probes автоматически подхватят. Также Service может ссылаться на named port — единая точка изменения.
Проверка знанийKnowledge check
В batch worker probe сделана exec test -f /tmp/ready. Worker зависает но файл /tmp/ready остаётся. Что не так?
ОтветAnswer
Файл создан один раз при init и не обновляется. Probe видит файл — PASS. Зависший worker не детектируется. Правильный паттерн liveness для воркеров: heartbeat — worker `touch /tmp/healthy` каждые 10 секунд в основном loop. Probe проверяет `find /tmp/healthy -mmin -1` (файл обновлён в последнюю минуту). Если worker завис — heartbeat не обновляется — probe fail.
Проверка знанийKnowledge check
gRPC service на v1.26 кластере. Какой handler использовать для readiness probe?
ОтветAnswer
grpc handler стал GA в v1.27. На v1.26 он либо отсутствует, либо требует feature gate (раньше был alpha/beta). Рабочее решение: exec с бинарём grpc_health_probe (https://github.com/grpc-ecosystem/grpc-health-probe), встроенным в image. command: ['/bin/grpc_health_probe', '-addr=:9090']. Этот же бинарь работает на всех версиях Kubernetes — fallback, который имеет смысл для multi-cluster деплоев с разными версиями.
Проверка знанийKnowledge check
В PostgreSQL probe команда exec command: ['pg_isready', '-U', '$POSTGRES_USER']. Сработает ли подстановка ENV переменной?
ОтветAnswer
Нет. Каждый элемент array передаётся напрямую процессу как argv — ENV substitution делает shell, не kubelet. Передастся литерально строка $POSTGRES_USER. Нужно обернуть в shell: command, sh, -c, pg_isready -U $POSTGRES_USER. Тогда sh подставит переменную. Это та же грабля, что с pipes/redirects — без явного shell они не работают.

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 5. CKAD задание: добавить к Deployment 'web' readiness probe на endpoint /health, port 8080, периодически каждые 5 секунд. Где в манифесте размещается probe?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5