DevOps

Деплой без простоя: стратегия Blue‑Green

10 сент. 2024 г.
10 min
Деплой без простоя: стратегия Blue‑Green

Blue‑Green 2025: 30 секунд от «клик» до «всё в проде» и 3 секунды назад, если что-то пошло не так. Ноль даунтайма, ноль слёз.

Полный zero‑downtime рецепт (копипаст в GitLab/Spacelift/ArgoCD) 1. Два namespace: `prod-blue` (живёт) и `prod-green` (спит) 2. Один Ingress → `serviceName: prod-router` 3. Router — обычный Traefik/NGINX с динамическим configMap

Шаг за шагом (15 минут и готово) ```yaml # .gitlab-ci.yml stages: [build, green, switch, cleanup]

build: script: docker build -t registry/myapp:${CI_COMMIT_SHA} .

green_deploy: stage: green script: - helm upgrade --install myapp-green ./chart \ --namespace prod-green \ --set image.tag=${CI_COMMIT_SHA} \ --wait --timeout=5m - kubectl rollout status deploy/myapp-green -n prod-green environment: green

smoke: parallel: - script: k6 run smoke.ws.js # 100 VU WebSocket - script: hey -z 30s https://green.example.com/healthz

warmup: script: | curl -X POST https://green.example.com/admin/warm-cache echo "Cache warmed: $(redis-cli -h green-redis KEYS \* | wc -l) keys"

migrate: script: flyway -url=jdbc:postgresql://green-db:5432 -user=app migrate # только expand‑шаги! contract — в следующем релизе

switch: stage: switch script: | kubectl patch configmap prod-router -n prod \ -p="{\"data\":{\"active\":\"green\"}}" sleep 5 # ждём ALB health-check echo "Трафик на Green! Blue спит" when: manual # или auto + canary 5%

cleanup: script: helm uninstall myapp-blue -n prod-blue || true ```

Откат одним кликом ```bash kubectl patch cm prod-router -n prod -p='{"data":{"active":"blue"}}' # 3 секунды — и пользователи обратно на старой версии ```

Миграции без паники (expand/contract) ```sql -- релиз N ALTER TABLE orders ADD COLUMN status_v2 TEXT; UPDATE orders SET status_v2 = CASE WHEN status='open' THEN 'pending' ELSE status END; -- код читает status_v2, пишет в оба

-- релиз N+1 ALTER TABLE orders DROP COLUMN status; ALTER TABLE orders RENAME COLUMN status_v2 TO status; ```

Feature Flag + Async Backfill ```java if (ff.isEnabled("new-scoring")) { scoreV2(payload); } else { scoreV1(payload); } // параллельно в фоне kafka.backfill(topic="orders-v1-to-v2", parallelism=32); ```

Canary внутри Blue‑Green ```yaml canary: script: kubectl apply -f - <<EOF apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: myapp spec: targetRef: Deployment/myapp-green service: myapp-svc analysis: interval: 1m threshold: 5 maxWeight: 50 stepWeight: 10 metrics: - name: error-rate thresholdRange: {max: 1} - name: latency-p95 thresholdRange: {max: 80} EOF ```

Мониторинг «не отвалилось ли?» Grafana → 4 золотые метрики за 60 сек до/после свитча: • `http_error_5xx{env="green"}` • `p95_latency_ms` • `ws_reconnect_total` • `synthetic_login_success`

Полная схема 2025 Clients → Global ALB (health → prod-router) → Traefik CM "active=green" → Pod-Green ↔ Redis-Cluster ↔ Postgres-Primary + 2 Replicas

Готовы к 10 деплоям в день? 1. Скоприруй YAML выше 2. `git push` → 3 минуты → миллион пользователей на новой версии 3. Пьёшь кофе, а не тушишь пожары.