Налаштування Blue-Green розгортання для веб-додатків
Blue-Green розгортання — стратегія zero-downtime розгортання з двома однаковими production-середовищами. В будь-який момент часу тільки одне отримує трафік. Нова версія розгортається в "холодне" середовище, тестується, потім трафік переключається миттєво.
Принцип роботи
┌─────────────────┐
Користувачі → │ Load Balancer │
└────────┬────────┘
│
┌───────────┴───────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Blue (v1.0) │ ← │ Green (v1.1) │
│ ACTIVE │ ←── │ STANDBY │
└──────────────┘ └──────────────┘
Після переключення:
┌──────────────┐ ┌──────────────┐
│ Blue (v1.0) │ │ Green (v1.1) │
│ STANDBY │ ──→ │ ACTIVE │
└──────────────┘ └──────────────┘
Реалізація через Nginx
# /etc/nginx/conf.d/upstream.conf
upstream blue {
server 10.0.0.10:8080;
}
upstream green {
server 10.0.0.11:8080;
}
# Симлинк вказує на активне середовище
# /etc/nginx/conf.d/active → blue.conf або green.conf
# /etc/nginx/conf.d/blue.conf
upstream active {
server 10.0.0.10:8080;
}
# /etc/nginx/conf.d/myapp.conf
server {
listen 80;
location / {
proxy_pass http://active;
}
}
# Скрипт переключення
#!/bin/bash
CURRENT=$(readlink /etc/nginx/conf.d/active.conf | grep -o 'blue\|green')
TARGET=$([ "$CURRENT" = "blue" ] && echo "green" || echo "blue")
echo "Switching from $CURRENT to $TARGET"
# Переключити симлинк
ln -sfn /etc/nginx/conf.d/${TARGET}.conf /etc/nginx/conf.d/active.conf
# Перезагрузити Nginx (без даунтайму)
nginx -t && nginx -s reload
echo "Traffic now flowing to $TARGET"
Blue-Green на AWS з ALB
# boto3 — переключення Target Groups
import boto3
elbv2 = boto3.client('elbv2', region_name='eu-west-1')
def switch_traffic(listener_arn: str, target_blue: str, target_green: str):
listener = elbv2.describe_listeners(ListenerArns=[listener_arn])
current_action = listener['Listeners'][0]['DefaultActions'][0]
current_tg = current_action['TargetGroupArn']
# Визначити, який активний
new_tg = target_green if current_tg == target_blue else target_blue
environment = 'green' if new_tg == target_green else 'blue'
# Переключити
elbv2.modify_listener(
ListenerArn=listener_arn,
DefaultActions=[{
'Type': 'forward',
'TargetGroupArn': new_tg,
}]
)
print(f"Traffic switched to {environment} ({new_tg})")
Blue-Green у Docker Swarm
#!/bin/bash
SERVICE=myapp
REGISTRY=registry.example.com
NEW_IMAGE=$REGISTRY/myapp:$BUILD_TAG
# Визначити поточний слот
CURRENT_SLOT=$(docker service inspect $SERVICE --format '{{index .Spec.Labels "slot"}}')
NEW_SLOT=$([ "$CURRENT_SLOT" = "blue" ] && echo "green" || echo "blue")
# Запустити нову версію
docker service create \
--name "${SERVICE}-${NEW_SLOT}" \
--label slot=$NEW_SLOT \
--network myapp-network \
--replicas 2 \
$NEW_IMAGE
# Дождатися готовності
echo "Waiting for $NEW_SLOT to be ready..."
until docker service ls --filter "name=${SERVICE}-${NEW_SLOT}" --format "{{.Replicas}}" | grep -q "2/2"; do
sleep 2
done
# Health check
HEALTH=$(curl -sf https://green.internal.example.com/health && echo "ok" || echo "fail")
if [ "$HEALTH" = "fail" ]; then
echo "Health check failed, aborting"
docker service rm "${SERVICE}-${NEW_SLOT}"
exit 1
fi
# Переключити трафік
./switch-nginx.sh $NEW_SLOT
# Видалити старе середовище через 30 секунд
sleep 30
docker service rm "${SERVICE}-${CURRENT_SLOT}"
Blue-Green в Kubernetes
# Два Deployment'а — blue і green
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-green
labels:
app: myapp
slot: green
spec:
replicas: 3
selector:
matchLabels: { app: myapp, slot: green }
template:
metadata:
labels: { app: myapp, slot: green }
spec:
containers:
- name: myapp
image: registry.example.com/myapp:v1.1.0
# Переключення трафіку в k8s
kubectl patch service myapp-svc \
-p '{"spec":{"selector":{"app":"myapp","slot":"green"}}}'
# Перевірка
kubectl rollout status deployment/myapp-green
# Откат
kubectl patch service myapp-svc \
-p '{"spec":{"selector":{"app":"myapp","slot":"blue"}}}'
Конвеєр з Blue-Green
# GitHub Actions
deploy-green:
needs: [test]
steps:
- name: Deploy to Green
run: docker stack deploy -c docker-compose.green.yml myapp-green
- name: Health Check
run: |
for i in $(seq 1 30); do
curl -sf https://green.internal/health && exit 0
sleep 2
done
exit 1
- name: Switch Traffic
run: ./switch-traffic.sh green
- name: Cleanup Blue (after 5 min)
run: sleep 300 && docker service rm myapp-blue
Терміни реалізації
- Nginx Blue-Green на VPS: 2–3 дні
- AWS ALB + Target Groups: 3–4 дні
- Kubernetes Blue-Green: 3–5 днів







