Реализовать canary deployment агента с автооткатом
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Реализовать canary deployment агента с автооткатом
1. Цель задачи
Научиться безопасно разворачивать новые версии LLM-агента (RAG, чат-бот и т.п.) на production-подобном окружении, используя canary deployment с прогрессивным увеличением трафика 1% → 5% → 10% → 100%. Реализовать автоматический откат (auto‑rollback) при обнаружении деградации ключевых метрик качества ответов и производительности. Отработать взаимодействие с трафик-менеджментом (Istio/Enovy), мониторингом и автоматизацией.
Ключевой результат Рабочий пайплайн canary‑деплоя агента, который автоматически откатывает новую версию при падении качества ответов ниже заданного порога.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Работающий LLM-агент (например, RAG) | Собственный пет-проект / готовый образ Docker с версией v1 (стабильная) |
| Новая версия агента (v2) с заведомо ухудшенным качеством (для теста отката) | Модифицировать v1 – например, снизить temperature или отключить filtering |
| Kubernetes кластер (minikube / kind / реальный) | Локально: minikube, kind, k3s; облако: GKE / EKS / AKS |
| Service Mesh (Istio) | Установка через istioctl / Helm (версия ≥1.18) |
| Мониторинг: Prometheus + Grafana | Установка через kube-prometheus-stack Helm chart |
| Инструмент оценки качества ответов | Пример: RAGAS (для RAG) или LLM-as-Judge (для чатов) через Python |
| Язык программирования Python + библиотеки | requests, kubernetes, prometheus-api-client, istio-api (k8s custom resources) |
Если нет реального инструмента — симулируем:
- Разверните два образа агента:
my-agent:v1(стабильный, baselines) иmy-agent:v2(с заведомо ухудшенным качеством: заменить эмбеддинг‑модель на примитивную, снизить top‑k, увеличить вероятность ошибок). - Создайте симулятор трафика (Python‑скрипт с aiohttp или locust), который шлёт запросы к агенту и фиксирует ответы.
- Определите метрику качества (например, relevance score от LLM-as-Judge). Реализуйте простого «судью» через OpenAI API (gpt-4o-mini), который ставит оценку 1–5.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Контейнеризация | Docker, Docker Compose (для разработки) | Упаковка агента и сервисов |
| Оркестрация | Kubernetes (minikube / kind) | Развёртывание агента, canary, откат |
| Service Mesh | Istio (VirtualService, DestinationRule, Gateway) | Распределение трафика между версиями |
| Мониторинг | Prometheus + Grafana + kube-state-metrics | Сбор и визуализация метрик деградации |
| Качество ответов | Python-скрипт (LLM-as-Judge) + Prometheus Pushgateway или direct metrics endpoint | Вычисление score качества и экспорт в Prometheus |
| Управление canary | Custom Controller / Python-скрипт с вызовом k8s API и Istio API | Изменение весов трафика, проверка метрик, автооткат |
| Нагрузочное тестирование | Locust / простой Python threading | Симуляция пользовательского трафика |
4. Этапы выполнения
Этап 1: Подготовка окружения и сбор базовых метрик (2–3 часа)
Действия
- Разверните Kubernetes кластер (minikube с драйвером docker, запуск с
minikube start --cpus=4 --memory=8g). - Установите Istio через
istioctl install --set profile=demo -y. Включите sidecar injection для namespacecanary:kubectl create namespace canary kubectl label namespace canary istio-injection=enabled - Разверните стабильную версию агента (v1):
- Создайте Deployment
agent-v1(образmy-agent:v1) с меткойversion: v1. - Создайте Service
agent-svc(ClusterIP, порт 80 → 8080). - Создайте Gateway и VirtualService для доступа через Ingress Gateway.
- Создайте Deployment
- Установите Prometheus + Grafana через Helm (kube-prometheus-stack). Убедитесь, что метрики из агента (latency, error rate) поступают.
- Реализуйте метрику качества:
- Напишите Python-скрипт
quality_metric.py, который опрашивает логи агента или получает ответы и с помощью LLM-as-Judge вычисляет среднийquality_score(0–1). Экспортируйте в Prometheus через Pushgateway или встроенный эндпоинт агента. - Запустите скрипт как sidecar-контейнер в подах агента.
- Напишите Python-скрипт
- Соберите baseline:
Ожидаемый результат этапа Рабочий кластер с агентом v1, Istio, мониторинг и baseline метрики.
Этап 2: Реализация canary-стратегии с распределением трафика (1–2 часа)
Действия
- Создайте DestinationRule для разделения трафика между версиями:
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: agent spec: host: agent-svc subsets: - name: stable labels: version: v1 - name: canary labels: version: v2 - Создайте VirtualService с начальным весом 100% на v1, v2 = 0%:
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: agent spec: hosts: - agent-svc http: - route: - destination: host: agent-svc subset: stable weight: 100 - destination: host: agent-svc subset: canary weight: 0 - Разверните canary-версию (v2):
- Deployment
agent-v2с образомmy-agent:v2и меткойversion: v2. Убедитесь, что он подхватывается DestinationRule.
- Deployment
- Постепенно увеличивайте вес canary (ручная проверка):
- Измените VirtualService: weight v2 = 1% (остальное v1). Проверьте через
istioctl proxy-status. - Проконтролируйте, что трафик распределяется корректно (через логи агентов или дашборд Grafana).
- Измените VirtualService: weight v2 = 1% (остальное v1). Проверьте через
Ожидаемый результат этапа Трафик 1% идёт на canary v2, 99% — на stable v1.
Этап 3: Определение метрик и порогов для auto-rollback (1 час)
Действия
- Определите метрики деградации:
error_rate_canary: доля ошибок (HTTP 5xx) от всех запросов к canary за последние 5 минут.p95_latency_canary: задержка ответов (ms) p95.avg_quality_score_canary: средняя оценка качества ответов (0–1) за последние 5 минут.
- Установите пороги отката (на основе baseline v1):
- Создайте Prometheus Recording Rules (опционально) для удобства запросов:
groups: - name: canary.rules rules: - record: canary:error_rate:5m expr: sum(rate(http_requests_total{version="v2",status=~"5.."}[5m])) / sum(rate(http_requests_total{version="v2"}[5m])) - Реализуйте Python-скрипт проверки метрик:
- Используйте
prometheus-api-clientдля запроса метрик за последние 5 минут. - Сравните с порогами.
- Используйте
Ожидаемый результат этапа Чётко определённые метрики, пороги и скрипт проверки.
Этап 4: Разработка auto-rollback (2–3 часа)
Действия
- Напишите Python-скрипт
canary_controller.py, который:- Циклически (каждые 60 секунд) проверяет метрики canary-версии через Prometheus API.
- Если любая из метрик выходит за порог — выполняет откат:
- Выставляет вес canary = 0% через обновление VirtualService.
- Масштабирует deployment canary до 0 реплик (опционально).
- Отправляет уведомление в Slack / Telegram (через webhook).
- Если метрики в норме — увеличивает вес canary на следующую ступень: 1% → 5% → 10% → 100% (шаги по таймеру или после стабильной проверки).
- Используйте Kubernetes API (через
kubernetesPython client) для обновления VirtualService.from kubernetes import client, config from kubernetes.client.rest import ApiException import yaml import requests config.load_kube_config() api = client.CustomObjectsApi() # Получить текущий VirtualService vs = api.get_namespaced_custom_object( group="networking.istio.io", version="v1beta1", namespace="canary", plural="virtualservices", name="agent" ) # Изменить weight vs['spec']['http'][0]['route'] = [ {'destination': {'host': 'agent-svc', 'subset': 'stable'}, 'weight': 100}, {'destination': {'host': 'agent-svc', 'subset': 'canary'}, 'weight': 0} ] api.replace_namespaced_custom_object(...) - Реализуйте логику градации (state machine):
STEPS = [1, 5, 10, 100] current_step = 0 # После успешной проверки в течение N циклов переходим к следующему шагу - Добавьте sidecar-контейнер с quality_metric (если не сделано ранее) в оба deployment для автоматического поступления метрик.
Ожидаемый результат этапа Auto-rollback скрипт, способный откатывать canary при деградации.
Этап 5: Тестирование canary и отката (2 часа)
Действия
- Убедитесь, что canary-версия v2 действительно хуже v1 (например, замените RAG-ретривер на выдающий нерелевантные документы). Проверьте вручную, что
quality_scoreпадает. - Запустите
canary_controller.pyв отдельном процессе (или в Kubernetes Job). - Запустите симулятор трафика (Locust или скрипт), генерирующий запросы с равномерным распределением между версиями (через Ingress Gateway).
- Наблюдайте за метриками в Grafana.
- При весе canary = 1%, метрики v2 должны быть плохими.
- После проверки скрипт должен зафиксировать деградацию и откатить: выставить вес canary = 0%.
- Проверьте, что stable-версия не пострадала (100% трафика возвращается к v1).
- Повторите сценарий с «хорошей» canary (v2 такая же, как v1) – убедитесь, что автооткат не срабатывает и вес постепенно доходит до 100%.
Ожидаемый результат этапа Демонстрация успешного отката при деградации и успешного деплоя при нормальных метриках.
5. Критерии приемки (Definition of Done)
- Canary-версия (v2) развёрнута в Kubernetes без влияния на stable (v1).
- Трафик распределяется через Istio: 1% → 5% → 10% → 100% (контролируется скриптом).
- Метрики качества ответов (quality_score), ошибок (error_rate) и задержек (latency) собираются в Prometheus.
- Auto-rollback скрипт срабатывает, когда хотя бы одна метрика canary превышает порог, и немедленно обнуляет вес canary.
- После отката 100% трафика идёт на stable-версию (v1).
- Логика отката корректно восстанавливает VirtualService (вес 100/0) и может быть запущена повторно.
- При «хорошей» canary вес постепенно достигает 100% без отката.
- Вся конфигурация и скрипты хранятся в Git-репозитории.
6. Ожидаемый результат
Основной артефакт GitHub-репозиторий (или папка) содержащий:
agent-v1/— Dockerfile и код стабильной версии агента.agent-v2/— Dockerfile и код ухудшенной версии (для тестов).canary-controller/— Python-скриптcontroller.pyс автооткатом.k8s/— манифесты: Deployment, Service, DestinationRule, VirtualService, Gateway.monitoring/— конфигурация Prometheus (recording rules, scrape configs) и дашборд Grafana (JSON export).load-test/— скрипт симулятора трафика (Locust или Python).README.md— инструкция по развёртыванию, запуску и тестированию.
Дополнительно Запись экрана или лог консоли, демонстрирующий:
- Развёртывание.
- Постепенное увеличение веса canary.
- Срабатывание auto-rollback при деградации.
- Восстановление стабильной версии.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Istio не распределяет трафик корректно | Проверьте label version на подах, убедитесь, что sidecar injection включён. Используйте istioctl analyze. |
| Prometheus не видит метрики кастомного quality_score | Используйте Pushgateway или добавьте в агент экспорт метрик через /metrics на 8080. Настройте scrape_config. |
| Auto-rollback скрипт не успевает откатить до массового падения | Установите интервал проверки 30 секунд и пороги с запасом. Можно также добавить alert на срабатывание ручного отката. |
| Конфликт при одновременной правке VirtualService из нескольких источников | Используйте оптимистичную блокировку через resourceVersion; запускайте только один экземпляр controller’а. |
| Симулятор трафика не достигает canary из-за маршрутизации | Убедитесь, что симулятор шлёт запросы через Istio Ingress Gateway, а не напрямую к Service. |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| 1. Подготовка окружения и сбор baseline | 3 часа |
| 2. Реализация canary через Istio | 1.5 часа |
| 3. Определение метрик и порогов | 1 час |
| 4. Разработка auto-rollback | 3 часа |
| 5. Тестирование сценариев | 2.5 часа |
| Итого | 11 часов |
Примечание: Для первого раза заложите +2–3 часа на отладку Istio и мониторинга.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 14 | Как настроить canary deployment в Kubernetes через Istio? |
| 42 | Метрики для мониторинга LLM-систем |
| 58 | Реализация A/B тестирования для ML моделей |
| 73 | Auto‑rollback при ухудшении метрик ML |
| 118 | Инструменты оценки качества ответов LLM (LLM-as-Judge) |
| 201 | Kubernetes Custom Resources и Python клиент |
| 245 | Мониторинг задержек через Prometheus Histogram |
| 308 | Prometheus Pushgateway — когда и как использовать |
| 375 | Graceful shutdown подов в Istio |
| 412 | Нагрузочное тестирование ML-сервисов с Locust |
10. Чек-лист самопроверки
- Я развернул кластер minikube с Istio и Prometheus/Grafana.
- Я создал два образа агента (стабильный и ухудшенный) и запустил их как Deployment.
- Я настроил Istio VirtualService с весами 100/0.
- Я написал скрипт, который увеличивает вес canary по шагам и проверяет метрики.
- Я удостоверился, что при запуске «плохой» canary скрипт откатывает её вес до 0.
- Я зафиксировал результаты и сохранил все конфигурации в Git.