Что такое Blue-Green Deployment?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Blue-Green Deployment: полный разбор
Blue-Green Deployment — это техника безопасного развёртывания новых версий приложения в production. Это стандартная практика в modern DevOps.
Основная идея
У тебя есть два идентичных production окружения:
- Blue — текущая активная версия (на которой работают пользователи)
- Green — новая версия (которую тестируют)
Когда Green готов и протестирован, ты переключаешь весь трафик на Green. Blue остаётся как fast rollback.
Перед развёртыванием:
Users → Load Balancer → Blue (v1.0) ✅ Production
Green (v0.9) ❌ Staging
После развёртывания:
Users → Load Balancer → Blue (v1.0) ❌ Staging
Green (v1.1) ✅ Production
Практический пример
Инфраструктура с AWS/Docker:
# 1. Текущее состояние
# Blue работает с трафиком
# Green не используется
docker run -d --name app-blue \
-p 8001:3000 \
myapp:1.0
docker run -d --name app-green \
-p 8002:3000 \
myapp:1.0 # Та же версия
# Load Balancer направляет трафик на :8001 (Blue)
Развёртывание новой версии:
# 2. Запускаем новую версию на Green
docker stop app-green
docker rm app-green
docker run -d --name app-green \
-p 8002:3000 \
myapp:1.1 # Новая версия
# 3. Тестируем Green
curl http://localhost:8002/api/health
curl http://localhost:8002/api/users
# 4. Запускаем smoke tests
npm run test:smoke -- http://localhost:8002
# 5. Если всё OK — переключаем трафик
# Load Balancer теперь направляет на :8002 (Green)
В Kubernetes
Blue-Green очень просто в K8s с использованием Service и Deployment:
# deployment-blue.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
version: blue # Трафик идёт на blue
ports:
- port: 80
targetPort: 3000
Развёртывание:
# 1. Создаём Green deployment с новой версией
kubectl set image deployment/app-green app=myapp:1.1
# 2. Ждём когда все pods станут ready
kubectl rollout status deployment/app-green
# 3. Запускаем smoke tests
kubectl run smoke-test --image=myapp:1.1 -- npm run test:smoke
# 4. Если OK — переключаем Service на green
kubectl patch service myapp -p '{"spec":{"selector":{"version":"green"}}}'
# 5. Если что-то пошло не так — быстро откатываемся
kubectl patch service myapp -p '{"spec":{"selector":{"version":"blue"}}}'
С использованием Terraform
# Два независимых ASG (Auto Scaling Group)
resource "aws_autoscaling_group" "blue" {
name = "app-blue"
launch_template {
id = aws_launch_template.app.id
version = 1 # Старая версия
}
desired_capacity = 3
tags = [
{
key = "Environment"
value = "blue"
}
]
}
resource "aws_autoscaling_group" "green" {
name = "app-green"
launch_template {
id = aws_launch_template.app.id
version = 2 # Новая версия
}
desired_capacity = 0 # Изначально выключен
}
# Load Balancer
resource "aws_lb_target_group_attachment" "blue" {
target_group_arn = aws_lb_target_group.app.arn
target_id = aws_autoscaling_group.blue.id
}
# Для развёртывания: запускаем green, тестируем, переключаем LB
Преимущества Blue-Green
✅ Zero downtime — переключение трафика мгновенно ✅ Instant rollback — если проблема, переключиться назад за секунды ✅ Полное тестирование — можно тестировать на реальной инфраструктуре ✅ Безопасность — старая версия остаётся доступной ✅ Production идентичность — тестируешь на том же, что в production
Недостатки Blue-Green
❌ Высокие затраты — нужно 2x инфраструктуры ❌ Сложность миграции БД — если есть schema changes ❌ Состояние — сессии могут потеряться при переключении
Проблемы и решения
1. Миграция БД во время Blue-Green
Это сложно, потому что Blue и Green используют одну БД.
// Backward compatible migrations!
// Шаг 1: Добавляем новое поле (Blue и Green видят)
ALTER TABLE users ADD COLUMN new_field VARCHAR(255);
// Шаг 2: Blue работает старым способом
// Green работает новым способом
// Шаг 3: Мигрируем данные
UPDATE users SET new_field = ... WHERE new_field IS NULL;
// Шаг 4: После Blue → Green переключения
// удаляем старое поле
ALTER TABLE users DROP COLUMN old_field;
2. Состояние приложения (Session state)
При переключении сессии могут потеряться.
// Решение 1: Хранить состояние в Redis (не в памяти)
const session = await redis.get(`session:${sessionId}`);
// Решение 2: Использовать JWT токены
const decoded = jwt.verify(token, secret);
// Решение 3: Sticky sessions (некоторые пользователи остаются на Blue)
3. Graceful shutdown
Важно корректно завершить Blue перед окончательным отключением.
const express = require('express');
const app = express();
const server = app.listen(3000);
process.on('SIGTERM', async () => {
console.log('SIGTERM received, shutting down gracefully...');
// Перестаём принимать новые запросы
server.close(() => {
console.log('Server closed');
});
// Даём время на завершение текущих запросов
setTimeout(() => {
process.exit(0);
}, 30000);
});
Сравнение стратегий развёртывания
Blue-Green Canary Rolling Recreate
────────────────────────────────────────────────────────
Downtime Нет Нет Нет Да
Рollback Мгновенный Быстрый Медленный Медленный
Комплексность Средняя Высокая Низкая Низкая
Цена инфры 2x 1.2x 1x 1x
Время развёрт Минуты Часы Часы Минуты
Когда использовать Blue-Green
✅ Критичные production системы ✅ Нужен мгновенный rollback ✅ Большие изменения в версии ✅ Есть бюджет на 2x инфраструктуру ❌ Microservices с индивидуальным расписанием ❌ Частые развёртывания ❌ Ограниченный бюджет
Для большинства стартапов сейчас используют Canary deployment (постепенное внедрение) или Rolling updates (пошаговая замена). Blue-Green хорош для kritical services.