Как организовать деплой 4 сервисов, если 3 из них зависят от запуска 4-го (базового)?

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

Ответ

В Kubernetes для управления зависимостями между микросервисами мы используем комбинацию Readiness Probes, Init Containers и порядок развертывания (Helm hooks). Это надежнее, чем простой depends_on в Docker Compose, так как проверяет именно готовность сервиса, а не факт запуска контейнера.

Реализация:

  1. Readiness Probe для базового сервиса: У сервиса-зависимости (например, service-core) должна быть точная проверка готовности (readinessProbe), которая возвращает успех только когда сервис полностью инициализирован и готов принимать запросы.

    # deployment.yaml для service-core
    apiVersion: apps/v1
    kind: Deployment
    spec:
      template:
        spec:
          containers:
          - name: app
            readinessProbe:
              httpGet:
                path: /health/ready
                port: 8080
              initialDelaySeconds: 10
              periodSeconds: 5
  2. Init Containers в зависимых сервисах: В деплойментах сервисов 1-3 добавляем initContainer, который ожидает готовности service-core.

    # deployment.yaml для service-1
    apiVersion: apps/v1
    kind: Deployment
    spec:
      template:
        spec:
          initContainers:
          - name: wait-for-core
            image: curlimages/curl:latest
            command: ['sh', '-c', 'until curl -f http://service-core.prod.svc.cluster.local:8080/health/ready; do echo "Waiting for core service..."; sleep 3; done']
          containers:
          - name: app
            # основной контейнер
  3. Управление порядком деплоя в Helm: Если используем Helm для деплоя всего стека, можно применять helm hooks (например, pre-install, pre-upgrade) для гарантии, что service-core обновлен/запущен перед остальными.

    # templates/service-core.yaml
    annotations:
      "helm.sh/hook-weight": "-5" # Отрицательный вес, выполняется раньше других ресурсов
  4. Стратегия обновления: Для зависимых сервисов настраиваем стратегию обновления RollingUpdate с maxUnavailable: 0, чтобы во время деплоя всегда оставались работающие поды, которые уже прошли проверку зависимости через initContainer.

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