English translation is not available yet. Showing Russian content.
Реализовать canary analysis с авто-роллбэком для AI-сервиса
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Реализовать canary analysis с авто-роллбэком для AI-сервиса
1. Цель задачи
Получить практический навык настройки канареечного (canary) развёртывания для инференс-сервиса на основе LLM или другого AI-модуля. Необходимо организовать маршрутизацию 5% трафика на новую версию сервиса, настроить мониторинг ключевых метрик (latency, error rate, throughput) в течение 24 часов и реализовать автоматический откат (rollback) при превышении пороговых значений.
Ключевой результат Рабочая конфигурация canary‑деплоя, которая автоматически откатывает новую версию при ухудшении качества обслуживания.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Docker-образ текущей стабильной версии AI-сервиса | Собственная сборка или образ из публичного реестра (например, your-registry/llm-server:stable) |
| Docker-образ новой (canary) версии AI-сервиса | Сборка с изменением модели или конфигурации (например, your-registry/llm-server:canary) |
| Инструмент для взвешенной маршрутизации трафика | Nginx (reverse proxy) / Traefik / Istio (в данном ТЗ – Nginx) |
| Система мониторинга и алертинга | Prometheus + Alertmanager + Grafana |
| Тестовый генератор запросов | locust, hey, wrk или простой Python-скрипт |
| CI/CD (опционально) | GitLab CI / GitHub Actions / Jenkins |
Если нет реального инструмента — симулируем:
- Создать два Docker-образа (stable и canary) с минимальным Flask/FastAPI приложением, которое имитирует инференс (например, случайная задержка + ответ).
- Настроить Nginx в Docker‑compose как ingress controller с балансировкой по весу (weight=95 для stable, weight=5 для canary).
- Эмулировать нагрузку с помощью
heyилиlocust, отправляющего ~100 rps. - Искусственно внести ошибку в canary (например, добавить
random.choices([time.sleep(0.1), 1/0], weights=[0.9, 0.1])), чтобы проверить авто‑роллбэк.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| AI-сервис (стабильный и canary) | Python, Flask/FastAPI, Docker | Выдача ответов на запросы |
| Маршрутизация трафика | Nginx (с upstream и weights), Docker‑compose | Направление 5% трафика на canary |
| Мониторинг метрик (latency, errors, throughput) | Prometheus (node_exporter + custom metrics) + Grafana | Сбор и визуализация |
| Алертинг и авто‑роллбэк | Alertmanager + bash-скрипт (или Python) | Автоматический откат при превышении порога ошибок |
| Генератор нагрузки | hey / locust / ab | Эмуляция пользовательского трафика |
| Оркестрация | Docker Compose (опционально Kubernetes) | Запуск всех компонентов |
4. Этапы выполнения
Этап 1: Настройка окружения и базового сервиса (2 часа)
Действия
-
Создать репозиторий проекта с файловой структурой:
canary-demo/ ├── stable/ │ ├── app.py │ └── Dockerfile ├── canary/ │ ├── app.py │ └── Dockerfile ├── nginx/ │ └── nginx.conf ├── monitoring/ │ ├── prometheus.yml │ └── alertmanager.yml ├── rollback.sh ├── docker-compose.yml └── README.md -
Написать stable/app.py – минимальное FastAPI приложение с одним endpoint
/predict:from fastapi import FastAPI import uvicorn import time, random app = FastAPI() @app.post("/predict") async def predict(data: dict): # имитация предсказания time.sleep(0.05 + random.uniform(0, 0.02)) return {"result": "stable", "latency_ms": 50} if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000) -
Создать canary/app.py – копия stable, но с искусственным дефектом:
@app.post("/predict") async def predict(data: dict): if random.random() < 0.1: # 10% ошибок raise HTTPException(status_code=500, detail="Internal Error") time.sleep(0.05 + random.uniform(0, 0.1)) # большая задержка return {"result": "canary", "latency_ms": 50} -
Написать Dockerfile для каждого сервиса (на базе
python:3.11-slim). -
Настроить nginx.conf
upstream ai_backend { server stable:8000 weight=95; server canary:8000 weight=5; } server { listen 80; location /predict { proxy_pass http://ai_backend; proxy_set_header Host $host; } } -
Создать docker-compose.yml с сервисами:
stable,canary,nginx,prometheus,alertmanager,grafana.
Ожидаемый результат этапа Запущенные контейнеры, Nginx раздаёт трафик: 95% на stable, 5% на canary. При curl-запросах видно распределение.
Этап 2: Настройка мониторинга и метрик (1,5 часа)
Действия
-
Добавить экспорт метрик в приложения с помощью
prometheus_client:REQUESTS_TOTAL(counter) с меткамиversion=stable|canary,status=200|500LATENCY_MS(histogram)- Пример:
from prometheus_client import Counter, Histogram, generate_latest requests_total = Counter('requests_total', 'Total requests', ['version', 'status']) latency_hist = Histogram('latency_ms', 'Request latency ms', ['version'], buckets=(10, 50, 100, 200, 500)) app.add_route("/metrics", lambda: Response(generate_latest(), media_type="text/plain"))
-
Создать prometheus.yml для сбора метрик со всех таргетов (stable, canary, nginx).
-
Создать alertmanager.yml с правилом:
groups: - name: canary_alerts rules: - alert: CanaryErrorRateHigh expr: (rate(requests_total{version="canary",status="500"}[5m]) / rate(requests_total{version="canary"}[5m])) > 0.05 for: 2m labels: severity: critical annotations: summary: "Canary error rate over 5%" -
Настроить webhook receiver (или использовать
alertmanagerдля вызова скрипта черезwebhook). Упрощённо: в alertmanager.yml добавить receiver с URL, который триггеритrollback.sh.
Ожидаемый результат этапа Prometheus собирает метрики, в Grafana построен дашборд (latency, error rate, RPS), Alertmanager может отправить оповещение.
Этап 3: Реализация авто‑роллбэка (1 час)
Действия
-
Создать rollback.sh – скрипт, который:
-
Организовать вызов скрипта через Alertmanager:
- В alertmanager.yml определить
webhook_config:receivers: - name: rollback_webhook webhook_configs: - url: "http://rollback-trigger:5000/rollback" - Запустить микросервис
rollback-trigger(Flask), который принимает POST и выполняетsubprocess.run(['/rollback.sh']).
- В alertmanager.yml определить
-
Проверить, что авто‑роллбэк работает – искусственно поднять error rate выше порога и убедиться, что canary отключается.
Ожидаемый результат этапа При превышении 5% ошибок (за 2 минуты) система автоматически убирает canary и возвращает 100% трафика на stable.
Этап 4: Тестирование канареечного анализа в течение 24 часов (симуляция) (1,5 часа)
Действия
-
Запустить генератор нагрузки на 24 часа (на деле для учебной задачи достаточно 1–2 часов):
hey -z 2h -c 10 -m POST -d '{"text":"hello"}' http://localhost/predict -
Убедиться, что canary получает ровно ~5% трафика – проверить в Grafana соотношение
requests_total{version="canary"}к общему числу. -
Через полчаса внести ошибку (если не была внесена изначально) – например, отредактировать код canary на лету через
docker cpили поднять error rate до 20%. -
Наблюдать за срабатыванием алерта и авто‑роллбэком – проверить, что трафик на canary упал до 0.
-
Собрать логи и дашборды для отчёта.
Ожидаемый результат этапа Получены графики распределения трафика и метрик, проверен сценарий успешного отката.
Этап 5: Документирование (0,5 часа)
Действия
- Написать README с описанием архитектуры, инструкцией по развёртыванию, параметрами порогов, примером алерта и процедурой восстановления.
- Сохранить скриншоты Grafana (latency, error rate, request volume).
- Задокументировать условия авто‑роллбэка и команды для ручного отката.
Ожидаемый результат этапа Полный набор артефактов: код, конфиги, скрипты, документация.
5. Критерии приемки (Definition of Done)
- Развёрнута docker-compose система из 4+ контейнеров (stable, canary, nginx, prometheus, grafana, alertmanager).
- Nginx корректно разделяет трафик: 95% на stable, 5% на canary (подтверждено метриками за 10 минут).
- Prometheus собирает custom-метрики (requests_total, latency_ms) с лейблами version и status.
- Alertmanager настроен на оповещение при превышении error rate canary >5% в течение 2 минут.
- Автоматический роллбэк реализован: при срабатывании алерта canary отключается (weight=0, контейнер stop).
- Лог событий авто‑роллбэка записывается в файл или stdout.
- Написан README с исчерпывающей инструкцией по запуску и тестированию.
- В Grafana создан дашборд с панелями: общий RPS, error rate по версиям, p95 latency.
6. Ожидаемый результат
Основные артефакты (как файлы в репозитории):
docker-compose.yml– полная оркестровка.stable/app.py,canary/app.py– исходный код AI-сервисов.nginx/nginx.conf– конфигурация с весами.monitoring/prometheus.yml,monitoring/alertmanager.yml– конфиги мониторинга.rollback.sh– скрипт автоматического отката.README.md– документация.
Дополнительно: скриншоты Grafana-дашборда и логи отработки роллбэка.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Alertmanager не вызывает webhook | Проверить network (docker-compose network) и правильность URL. Использовать curl внутри контейнера для отладки. |
| Nginx reload не отрабатывает внутри контейнера | Назначить скрипту права на выполнение docker exec nginx nginx -s reload или использовать docker kill -s HUP nginx. |
| Метрики не появляются в Prometheus | Проверить targets в Prometheus UI, правильность портов и путь /metrics. |
| Авто‑роллбэк срабатывает слишком поздно | Уменьшить for в алерте, увеличить частоты scrape (scrape_interval: 5s). |
| Трафик не распределяется 95/5 из‑за keepalive или клиентского кэширования | В nginx отключить keepalive для upstream (или настроить proxy_http_version 1.1). |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Настройка окружения | 2 ч |
| Этап 2: Мониторинг и метрики | 1,5 ч |
| Этап 3: Авто‑роллбэк | 1 ч |
| Этап 4: Тестирование (симуляция 24 ч) | 1,5 ч |
| Этап 5: Документирование | 0,5 ч |
| Итого | 6,5 ч |
Примечание: для первого выполнения (без готовых шаблонов) заложите 8–10 часов.
9. Связанные вопросы из базы знаний
| № вопроса | Тема |
|---|---|
| 45 | Стратегии деплоя (blue‑green, canary, rolling) |
| 112 | Настройка Prometheus для инференс‑сервисов |
| 138 | Auto‑rollback и health checks в CI/CD |
| 209 | Мониторинг latency и error rate LLM-сервисов |
| 315 | Docker Compose для ML‑пайплайнов |
| 402 | Nginx как reverse‑proxy с взвешенным upstream |
| 507 | Alertmanager: конфигурация webhook |
| 618 | A/B тестирование моделей в production |
| 734 | Нагрузочное тестирование AI-сервисов (locust, hey) |
| 819 | Интеграция Grafana с Prometheus |
10. Чек-лист самопроверки
- Я подготовил Docker-образы для stable и canary и убедился, что они запускаются отдельно.
- Nginx настроен с весами 95/5, и я проверил распределение через несколько curl-запросов.
- Prometheus успешно собирает метрики с обоих сервисов; в Grafana есть дашборд с latency и error rate.
- Alertmanager срабатывает при превышении 5% ошибок на canary (я проверил, искусственно увеличив error rate).
- После срабатывания алерта скрипт rollback.sh выполнился, canary получил вес 0 и контейнер остановлен.
- Я задокументировал все шаги в README и приложил скриншоты Grafana.