Как ты обеспечиваешь отказоустойчивость в приложениях на уровне инфраструктуры и конфигурации?

«Как ты обеспечиваешь отказоустойчивость в приложениях на уровне инфраструктуры и конфигурации?» — вопрос из категории Архитектура и DevOps-практики, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Мой подход к отказоустойчивости приложений — это комбинация правильной конфигурации Kubernetes и облачных сервисов.

1. Репликация и распределение подов:

  • Всегда задаю replicas: >1 для Deployment'ов критичных сервисов.
  • Использую topologySpreadConstraints для равномерного распределения подов по зонам и нодам, что защищает от падения одной зоны или ноды.
    spec:
    topologySpreadConstraints:
    - maxSkew: 1
    topologyKey: topology.kubernetes.io/zone
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: backend

2. Проверки жизнеспособности (Probes):

  • Liveness Probe: Определяет, когда контейнер нужно перезапустить. Например, если HTTP-эндпоинт /health не отвечает 200 OK.
  • Readiness Probe: Определяет, когда под готов принимать трафик. Поды, не прошедшие проверку, удаляются из балансировщика нагрузки Service.
  • Startup Probe: Для "медленно" стартующих приложений (Java), даёт им время на запуск перед началом liveness/readiness проверок.
    livenessProbe:
    httpGet:
    path: /healthz
    port: 8080
    initialDelaySeconds: 30
    periodSeconds: 10
    readinessProbe:
    httpGet:
    path: /ready
    port: 8080
    initialDelaySeconds: 5
    periodSeconds: 5

3. Автомасштабирование:

  • Настраиваю Horizontal Pod Autoscaler (HPA) на основе CPU, памяти или кастомных метрик из Prometheus (например, RPS).
  • Использую Cluster Autoscaler, который автоматически добавляет ноды в кластер, если поды не могут быть размещены из-за нехватки ресурсов.

4. Стратегия деплоя:

  • Использую стратегию rolling update с maxSurge и maxUnavailable для бесшовного обновления без простоя.
  • Для критичных приложений настраиваю blue-green или canary деплой через инструменты вроде Flagger и Istio, что позволяет быстро откатиться при проблемах.

5. Зависимости и graceful shutdown:

  • Настраиваю terminationGracePeriodSeconds (обычно 30+ секунд) и реализую в приложении обработку сигнала SIGTERM для корректного завершения работы: завершения соединений с БД, обработки текущих запросов, снятия с балансировки.
  • Для stateful-приложений (БД) использую StatefulSet с привязкой к устойчивым томам (Persistent Volumes) и настраиваю репликацию на уровне самого приложения (например, Patroni для PostgreSQL).