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.
В 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
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 в коде приложения:
Если в команде нет конвенции — договоритесь о ней. Это лучшая инвестиция в стабильность сервиса. Стандарт /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
На CKAD НЕ забывайте про indentation внутри YAML. probe идёт ВНУТРЬ containers[]., а не в spec.template.spec. напрямую. Типовая ошибка — вставить probe на уровне Pod spec, kubelet проигнорирует, контейнер останется без probes.