Blue-Green Deployment (Безопасное обновление приложений)

⌘K

Blue-Green Deployment (Безопасное обновление приложений)

Blue-Green Deployment — это стратегия выката новых версий приложений, при которой одновременно существуют две полностью изолированные среды: blue (текущая стабильная версия) и green (новая версия, готовая к переключению). Всё пользовательское обращение в каждый момент времени направляется только на одну из них. После проверки новой версии происходит мгновенное переключение трафика с blue на green — без даунтайма и с возможностью моментального отката.


Как это работает

  1. Текущая версия приложения (blue) обслуживает весь трафик.
  2. Новая версия (green) разворачивается параллельно, но не принимает трафик.
  3. Проводится проверка работоспособности и автоматическое тестирование green.
  4. При успехе — трафик целиком переключается на green (обычно через Service или Ingress).
  5. При необходимости — возможен откат к blue путём обратного переключения.

Преимущества подхода

  • Zero-downtime — трафик не прерывается, даже при обновлении ядра приложения;
  • Быстрый rollback — возвращение к предыдущей версии не требует переразвёртывания;
  • Изоляция окружений — blue и green могут использовать разные конфигурации, переменные среды, версии зависимостей;
  • Гибкость инфраструктуры — поддерживается в Kubernetes, облаках (AWS, GCP, Azure) и on-prem кластерах.

Реализация в Kubernetes

Схема:

  • Два Deployment объекта: my-app-blue, my-app-green;
  • Один Service, указывающий на активную версию через selector;
  • Переключение трафика = изменение spec.selector в Service.

Пример:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      version: green
  template:
    metadata:
      labels:
        app: my-app
        version: green
    spec:
      containers:
        - name: app
          image: my-registry/my-app:v2
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  selector:
    app: my-app
    version: green  # здесь и происходит "переключение"
  ports:
    - port: 80
      targetPort: 8080

Разница: Blue-Green vs. Canary

ПодходПереключение трафикаПоведениеНазначение
Blue-GreenМгновенноеВсё или ничегоПростое переключение
Canary ReleaseПостепенноеПошаговая доставкаГибкое A/B тестирование

Поддержка в платформах

  • AWS: через Elastic Beanstalk, ECS или CodeDeploy с Traffic Routing;
  • Google Cloud: Cloud Run + Traffic Splitting, GKE + Ingress;
  • On-prem: Istio VirtualService, NGINX Ingress с аннотациями;
  • CI/CD: GitLab, Argo CD, Spinnaker, Flux поддерживают шаблоны blue-green;

Важно учитывать

  • Наличие внешнего состояния (например, БД) требует синхронизации или миграций;
  • Слежение за метриками после переключения — для своевременного отката;
  • Проверка на feature parity между версиями;
  • Чёткая автоматизация rollback-процесса — часть стратегии disaster recovery.

Blue-Green Deployment — это надёжный шаблон доставки для продакшн-сред, где критично избежать сбоев, откатов и неожиданных прерываний сервиса. Он отлично сочетается с GitOps и платформенной автоматизацией.

Вот логичное и практическое продолжение — инструменты и конфигурации для автоматизации Blue-Green Deployment, включая:

  1. Скрипт переключения трафика через kubectl
  2. Helm-чарт с параметризуемой blue/green-логикой
  3. Мониторинг переключения с использованием Prometheus и алерта
  4. Автоматизация через GitOps (Argo CD или Flux)

1. Скрипт: переключение сервиса на green

#!/bin/bash

APP_NAME="my-app"
TARGET_VERSION="green"

echo "Switching ${APP_NAME} service to ${TARGET_VERSION}..."

kubectl patch service ${APP_NAME} \
  -p "{\"spec\": {\"selector\": {\"app\": \"${APP_NAME}\", \"version\": \"${TARGET_VERSION}\"}}}"

Этот простой kubectl patch меняет Service.spec.selector, направляя трафик на новую версию без перезапуска.


2. Helm-чарт: параметризуемый деплой

values.yaml

deploymentColor: green
image:
  tag: "v2"

deployment.yaml

metadata:
  name: my-app-{{ .Values.deploymentColor }}
spec:
  selector:
    matchLabels:
      app: my-app
      version: {{ .Values.deploymentColor }}
  template:
    metadata:
      labels:
        app: my-app
        version: {{ .Values.deploymentColor }}

service.yaml

spec:
  selector:
    app: my-app
    version: {{ .Values.deploymentColor }}

Для переключения достаточно задать --set deploymentColor=blue или green — всё автоматически обновится.


3. Мониторинг: Prometheus Rule на ошибку после переключения

- alert: App5xxAfterBlueGreenSwitch
  expr: increase(http_requests_total{status=~"5..",app="my-app"}[5m]) > 10
  for: 3m
  labels:
    severity: critical
  annotations:
    summary: "Ошибки 5xx после переключения"
    description: "Новая версия приложения генерирует ошибки. Проверь и откати при необходимости."

Такое правило поможет откатиться при росте ошибок после переключения.


4. GitOps: автоматизация переключения через Argo CD

  • Service и оба Deployment (blue/green) — под контролем Git.
  • Переключение — просто git commit → service.yaml указывает version: green.
  • Argo CD автоматически синхронизирует изменения, Git — источник правды.

Можно интегрировать с Argo Rollouts, добавить webhook от CI для автоматического переключения и health verification.

CI/CD-интеграция для Blue-Green Deployment с автооткатом, с использованием GitLab CI и health check’ов.

Пример .gitlab-ci.yml для blue-green деплоя

stages:
  - deploy
  - validate
  - switch
  - cleanup

variables:
  KUBE_CONTEXT: your-kube-context
  APP_NAME: my-app

deploy-green:
  stage: deploy
  script:
    - helm upgrade --install ${APP_NAME}-green ./helm-chart \
        --set deploymentColor=green \
        --set image.tag=$CI_COMMIT_SHORT_SHA
  only:
    - main

validate-green:
  stage: validate
  script:
    - echo "Waiting for pods to be ready..."
    - kubectl rollout status deploy/${APP_NAME}-green --timeout=120s
    - echo "Running smoke tests..."
    - curl --fail http://green.my-app.svc.cluster.local/health
  only:
    - main

switch-service:
  stage: switch
  script:
    - kubectl patch service ${APP_NAME} \
        -p "{\"spec\": {\"selector\": {\"app\": \"${APP_NAME}\", \"version\": \"green\"}}}"
  only:
    - main

rollback-on-failure:
  stage: switch
  when: on_failure
  script:
    - echo "Deployment failed. Rolling back service to blue..."
    - kubectl patch service ${APP_NAME} \
        -p "{\"spec\": {\"selector\": {\"app\": \"${APP_NAME}\", \"version\": \"blue\"}}}"

cleanup-blue:
  stage: cleanup
  script:
    - kubectl delete deploy ${APP_NAME}-blue || true
  only:
    - main
  when: manual

Что делает этот пайплайн:

  • Разворачивает green-версию;
  • Валидирует её (готовность подов + HTTP health check);
  • Переключает сервис на green;
  • Если что-то идёт не так — автоматический откат на blue;
  • Очистка blue-окружения — вручную, после подтверждения.

Дополнительно можно подключить:

  • Smoke test контейнер — e2e-проверки внутри кластера перед переключением;
  • Prometheus webhook — прерывание пайплайна при росте ошибок;
  • Istio / Ingress routing — переключение трафика по хосту или path вместо Service patch;
  • GitOps-схему — где patch заменяется коммитом в service.yaml в Git, а Argo CD делает всё остальное.