中文翻译暂不可用,显示俄语原文。
Реализовать blue-green deployment для RAG
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Реализовать blue-green deployment для RAG
1. Цель задачи
Научиться проектировать и реализовывать стратегию zero‑downtime deployment для RAG‑системы с использованием двух изолированных окружений (blue/green) и балансировщика нагрузки. Отработать процесс переключения трафика, автоматизированные smoke‑тесты и откат при обнаружении ошибок.
Ключевой результат Рабочий blue‑green pipeline, при котором переключение между версиями занимает менее 10 секунд и не вызывает ошибок у пользователей во время релиза.
2. Исходные данные
Перед началом работы необходимо иметь:
| Что нужно | Откуда взять |
|---|---|
| RAG‑система (собранная или тестовая) | Ваш pet‑проект RAG (например, FastAPI + LangChain + Qdrant) |
| Docker / Docker Compose | Установить, если нет |
| Балансировщик нагрузки | nginx, HAProxy или Traefik (на выбор) |
| Smoke‑тесты (набор запросов к API) | Разработать самостоятельно (см. этап 2) |
| CI/CD агент | GitHub Actions, GitLab CI или локальный скрипт |
| Доменное имя / localhost | Для тестирования достаточно localhost с разными портами |
Если нет реального инструмента — симулируем:
- Разверните RAG‑приложение в двух экземплярах (через Docker Compose) на разных портах (например, 8081 — blue, 8082 — green).
- Используйте nginx как reverse proxy с динамическим переключением upstream.
- Для имитации продакшен‑трафика запустите скрипт, отправляющий HTTP‑запросы каждые 2 секунды.
- Smoke‑тесты можно запускать как отдельный контейнер или через curl.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| RAG‑приложение | FastAPI / Flask + LangChain + Qdrant | Обработка запросов и поиск |
| Оркестрация контейнеров | Docker, Docker Compose | Изоляция окружений blue/green |
| Балансировщик нагрузки | nginx (с hot‑reload) | Маршрутизация трафика между blue/green |
| CI/CD | GitHub Actions или bash‑скрипт | Автоматизация переключения |
| Smoke‑тесты | pytest + requests | Проверка работоспособности перед переключением |
| Мониторинг / логи | Prometheus + Loki (опционально) | Отслеживание zero‑downtime |
4. Этапы выполнения
Этап 1: Подготовка двух окружений (1 час)
Действия
- Создайте docker-compose.blue.yml и docker-compose.green.yml – каждый запускает экземпляр RAG с уникальным тегом (например, rag:blue).
- Настройте разные порты внутри Compose: для blue –
8081:8000, для green –8082:8000. - Создайте общую сеть
rag_networkдля взаимодействия с балансировщиком. - В каждом окружении используйте отдельный volume для векторной базы (или общую, если индексы совместимы).
Ожидаемый результат этапа Оба окружения работают независимо, каждый отвечает на curl localhost:8081/health и localhost:8082/health.
Этап 2: Настройка балансировщика нагрузки (1–1.5 часа)
Действия
- Установите nginx (или используйте образ nginx:alpine) и настройте
/etc/nginx/conf.d/default.confс upstream, указывающим на активное окружение. - Первоначально укажите upstream на blue (порт 8081).
- Добавьте механизм переключения upstream: напишите скрипт
switch.sh, который заменяет строку в конфиге и выполняет nginx -s reload. - Настройте health‑check: nginx proxy_pass с проверкой /health на активном окружении.
Пример конфигурации nginx:
upstream rag_backend {
server rag_blue:8000; # или localhost:8081
}
server {
listen 80;
location / {
proxy_pass http://rag_backend;
proxy_set_header Host $host;
}
location /health {
proxy_pass http://rag_backend/health;
}
}
Ожидаемый результат этапа Трафик проходит только через активное окружение; при curl localhost получаем ответ от blue.
Этап 3: Разработка smoke‑тестов (30 минут)
Действия
- Напишите smoke‑тест на Python (pytest) с запросами к API:
- GET /health → 200
- POST
/queryс тестовым вопросом → ответ от LLM - Проверка времени ответа < 5 секунд
- Оберните тесты в контейнер или запускайте из CI.
- Подготовьте набор из 3–5 репрезентативных запросов, покрывающих основные сценарии RAG.
Пример теста:
def test_health(client):
r = client.get("/health")
assert r.status_code == 200
assert r.json()["status"] == "ok"
Ожидаемый результат этапа Smoke‑тесты проходят на активном окружении.
Этап 4: Реализация процесса blue‑green переключения (1.5–2 часа)
Действия
- Разработайте CI‑пайплайн (например, GitHub Actions) со следующей логикой:
- Build – собрать образ новой версии RAG.
- Deploy to passive – запустить новую версию на неактивном окружении (например, если активен blue, то запускаем green).
- Smoke tests on passive – запустить smoke‑тесты против пассивного окружения (через его порт).
- Switch – выполнить
switch.sh, переключающий nginx upstream на пассивное окружение. - Health check – удостовериться, что балансировщик начал отвечать на все запросы с новым бэкендом.
- Stop old – остановить старое окружение (через docker compose down).
- Добавьте шаг отката: если smoke‑тесты на новом окружении не прошли → не переключать трафик и отправить уведомление.
Пример скрипта switch.sh:
#!/bin/bash
ACTIVE=$1 # "green" или "blue"
sed -i "s/server rag_[a-z]*:8000/server rag_$ACTIVE:8000/" /etc/nginx/conf.d/default.conf
nginx -s reload
Ожидаемый результат этапа Переключение проходит без прерывания обработки запросов (проверяется фоновой нагрузкой).
Этап 5: Проверка zero‑downtime (30 минут)
Действия
- Запустите скрипт, непрерывно посылающий запросы к балансировщику (раз в секунду) и записывающий успешные ответы и ошибки.
- Во время нагрузки выполните переключение с blue на green (через тот же CI, если он локальный).
- Убедитесь, что количество ошибок 5xx за время переключения равно нулю.
- Повторите тест 3 раза, замерьте время переключения с момента выполнения switch до появления ответов от нового окружения.
Ожидаемый результат этапа Подтверждён zero‑downtime – ни одного HTTP‑статуса >=500 во всех запусках.
5. Критерии приемки (Definition of Done)
- Настроены два независимых окружения (blue/green) через Docker Compose.
- Балансировщик nginx корректно перенаправляет трафик на активное окружение.
- Скрипт переключения (
switch.sh) работает без потери соединений (проверено нагрузочным тестом). - Smoke‑тесты запускаются автоматически в CI перед переключением.
- При неудачных smoke‑тестах переключение не происходит, новое окружение останавливается.
- Время переключения (switch) не превышает 5 секунд.
- Во время тестовой нагрузки (1 rps) количество ошибок 5xx равно 0.
- После завершения работы old‑окружение удаляется (docker compose down).
- Вся конфигурация хранится в Git.
- Процесс документирован в README (шаги переключения, откат).
6. Ожидаемый результат
Итоговый артефакт Git‑репозиторий с:
docker-compose.blue.ymlиdocker-compose.green.yml(или единый сервис с переменными)nginx/conf.d/default.confс шаблоном upstreamscripts/switch.sh– скрипт переключенияscripts/rollback.sh– скрипт отката на предыдущее окружениеtests/test_smoke.py– набор smoke‑тестов.github/workflows/deploy.yml(илиdeploy.sh) – CI/CD пайплайнREADME.mdс описанием процедуры
Дополнительно (опционально): Скрипт нагрузки (load_test.py) для демонстрации zero‑downtime.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
Nginx не применяет reload без потери соединений | Убедиться, что nginx собран с модулем --with-http_stub_status_module. Использовать nginx -s reload, а не restart. |
| Разное содержимое векторной базы у blue/green | Использовать общий том для Qdrant или синхронизировать индексы; в MVP допускается раздельная БД с переиндексацией. |
| Smoke‑тесты не успевают проверить новое окружение до переключения | Добавить таймауты; проверять только health‑endpoint и один типовой запрос. |
| Порты конфликтуют при параллельном запуске | Использовать разные внешние порты (8081, 8082) внутри Docker Compose; внутренние (8000) одинаковы. |
| Во время переключения есть «холодный старт» нового окружения | Предварительно прогреть (warm up) новый экземпляр несколькими запросами перед переключением. |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Подготовка двух окружений | 1 час |
| Настройка балансировщика | 1–1.5 часа |
| Разработка smoke‑тестов | 30 мин |
| Реализация процесса переключения | 1.5–2 часа |
| Проверка zero‑downtime | 30 мин |
| Итого (первый раз) | 4.5–5.5 часов |
Примечание У новичка время может увеличиться до 8 часов из‑за отладки nginx и CI. Опытный инженер справится за 3–4 часа.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 17 | Архитектура RAG: компоненты и взаимодействие |
| 32 | Docker Compose для ML‑сервисов |
| 45 | Настройка nginx как reverse proxy |
| 67 | Health‑checks и graceful shutdown |
| 82 | CI/CD для AI‑систем |
| 124 | Smoke‑тестирование API |
| 156 | Zero‑downtime deployment стратегии |
| 211 | Мониторинг деплоев с Prometheus |
| 298 | Работа с upstream в nginx |
| 345 | Graceful rolling vs blue‑green |
10. Чек-лист самопроверки
- Я развернул два независимых экземпляра RAG на разных портах.
- Я настроил nginx и проверил, что трафик идёт только на активный экземпляр.
- Я написал smoke‑тест, который проверяет health и простой запрос.
- Я реализовал скрипт переключения, который меняет upstream без
restart. - Я провёл тест с постоянной нагрузкой (1 rps) и убедился, что 5xx ошибок нет.
- Я зафиксировал время переключения (меньше 5 секунд).
- Я задокументировал процедуру в README.
- Я создал отладочный сценарий отката в случае неудачи.