Health Checks: проверка состояния

Health check — эндпоинт /health или /healthz, который оркестраторы (Kubernetes, Docker, load balancer) периодически опрашивают, чтобы убедиться, что сервис работоспособен.

Зачем нужно

Без health check оркестратор считает контейнер живым, пока он не упал. С health check Kubernetes перестаёт слать трафик на «живой, но сломанный» pod (приложение запущено, но не отвечает на запросы из-за deadlock или проблем с БД). Load balancer исключает нездоровые инстансы из ротации.

Где используется

  • Kubernetes Liveness и Readiness probes
  • Docker HEALTHCHECK
  • AWS ALB/ELB: Target Group health checks
  • Uptime-мониторинг (pingdom, betteruptime)

Основной контент

Типы проверок

Тип Что проверяет Kubernetes probe
Liveness Приложение не завис намертво livenessProbe
Readiness Приложение готово принимать трафик readinessProbe
Startup Приложение завершило инициализацию startupProbe

Реализация в Node.js (Express)

// Простой health check
app.get('/health', (req, res) => {
  res.json({ status: 'ok', timestamp: new Date.toISOString() });
});

// Расширенный health check с проверкой зависимостей
app.get('/health/ready', async (req, res) => {
  const checks = {};
  let healthy = true;

  // Проверка БД
  try {
    await db.query('SELECT 1');
    checks.database = 'ok';
  } catch (err) {
    checks.database = 'error: ' + err.message;
    healthy = false;
  }

  // Проверка Redis
  try {
    await redis.ping;
    checks.redis = 'ok';
  } catch (err) {
    checks.redis = 'error: ' + err.message;
    healthy = false;
  }

  const status = healthy ? 200 : 503;
  res.status(status).json({
    status: healthy ? 'ok' : 'degraded',
    checks,
    uptime: process.uptime,
  });
});

Kubernetes Probes

# deployment.yaml
spec:
  containers:
    - name: api
      image: myapp:latest
      ports:
        - containerPort: 3000

      # Проверяет готовность принимать трафик
      readinessProbe:
        httpGet:
          path: /health/ready
          port: 3000
        initialDelaySeconds: 5    # подождать 5с после запуска
        periodSeconds: 10         # проверять каждые 10с
        failureThreshold: 3       # 3 неудачи → убрать из service

      # Перезапускает pod если он завис
      livenessProbe:
        httpGet:
          path: /health
          port: 3000
        initialDelaySeconds: 15
        periodSeconds: 20
        failureThreshold: 3       # 3 неудачи → перезапуск pod

Docker HEALTHCHECK

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -qO- http://localhost:3000/health || exit 1
# Посмотреть статус health check
docker ps        # колонка STATUS: healthy / unhealthy
docker inspect --format='{{json .State.Health}}' mycontainer

Nginx upstream health check

upstream api {
    server api1:3000;
    server api2:3000;
    # Nginx Plus: активные health checks
    # В open-source Nginx: пассивные (по ошибкам)
}

Частые ошибки

  • Health check только проверяет HTTP 200, не проверяя реальное состояние БД — сервис «здоров», но не работает
  • Тяжёлый health check с множеством запросов — нагружает систему при частых проверках
  • Один эндпоинт для liveness и readiness: готовность к трафику и «жив» — разные вещи
  • Не настроен initialDelaySeconds — проверки начинаются до инициализации → лишние перезапуски

Связанные темы

Ресурсы