flea/_deploy/README.md
ruberoid 1be50c3eeb
Some checks failed
continuous-integration/drone/tag Build is failing
deploy_only: 0.7.35
2025-10-17 10:56:40 +04:00

16 KiB
Raw Permalink Blame History

🚀 Документация CI/CD Pipeline NOCR

📋 Обзор

Проект NOCR использует современную многопайплайновую CI/CD систему на базе Drone CI, работающую на Kubernetes. Этот документ описывает 5 специализированных пайплайнов и способы их использования.


🎯 Архитектура пайплайнов

Пайплайн 1: Feature Validation (Валидация функциональных веток)

Триггер: Push в ветки feature/*, fix/* или issues/* Назначение: Быстрая обратная связь для разработчиков Длительность: ~3-5 минут

Что делает:

  • Клонирует репозиторий с субмодулями
  • Восстанавливает все NuGet-пакеты (общий кэш)
  • Собирает все 4 сервиса в Debug-режиме
  • Запускает unit и integration тесты с Testcontainers

Пример рабочего процесса:

git checkout -b feature/add-new-filter
# Внесите изменения...
git add .
git commit -m "Add new filter functionality"
git push origin feature/add-new-filter

Drone автоматически запустит тесты. Проверьте результаты перед созданием PR.


Пайплайн 2: Main Validation (Валидация основной ветки)

Триггер: Push в ветку main Назначение: Валидация основной ветки после мерджа Длительность: ~3-5 минут

Что делает:

  • То же, что и Feature Validation
  • Гарантирует, что ветка main всегда в рабочем состоянии

Пример рабочего процесса:

# После мерджа PR в main
# Пайплайн запускается автоматически

Пайплайн 3: Contracts-Only Publish (Публикация только контрактов)

Триггер: Тег с сообщением коммита, содержащим contracts_only:<service> Назначение: Быстрая публикация NuGet-пакетов контрактов без сборки Docker-образов Длительность: ~2 минуты

Что делает:

  • Упаковывает контракты указанного сервиса в NuGet-пакеты
  • Публикует во внутреннем NuGet-фиде
  • Пропускает сборку Docker-образов

Пример рабочего процесса:

# Обновите контракты telegram-listener
cd telegram-listener
# Внесите изменения в Async.Api.Contracts...
git add .
git commit -m "contracts_only:telegram_listener - Add MessageEdited event"
git push origin main

# Создайте тег
git tag v1.2.4-contracts
git push origin v1.2.4-contracts

Поддерживаемые маркеры:

  • contracts_only:telegram_listener
  • contracts_only:text_matcher
  • contracts_only:users

Пайплайн 4: Full Release (Полный релиз)

Триггер: Тег на main БЕЗ contracts_only или deploy_only в сообщении коммита Назначение: Полный цикл релиза Длительность: ~8-10 минут

Что делает:

  1. Этап 1: Публикация всех контрактов в NuGet (параллельно)
  2. Этап 2: Сборка всех Docker-образов с Kaniko (3 параллельных потока)
  3. Этап 3: Деплой в Kubernetes (только для тегов, начинающихся с v)

Пример рабочего процесса:

# Готовы к релизу
git tag v1.3.0
git push origin v1.3.0

# Drone выполнит:
# 1. Публикацию контрактов
# 2. Сборку образов (с тегами v1.3.0, commit SHA, и latest)
# 3. Деплой в k8s (если тег начинается с 'v')

Создаваемые теги образов:

  • hub.musk.fun/k8s/nocr/telegram_listener:v1.3.0
  • hub.musk.fun/k8s/nocr/telegram_listener:abc1234 (commit SHA)
  • hub.musk.fun/k8s/nocr/telegram_listener:latest

Пайплайн 5: Deploy-Only (Только деплой)

Триггер: Тег с сообщением коммита, содержащим deploy_only: <version> Назначение: Быстрый деплой уже собранных образов Длительность: ~1 минута

Что делает:

  • Пропускает сборку
  • Деплоит указанные образы в Kubernetes
  • Полезно для отката или продвижения существующих образов

ВАЖНО: В сообщении коммита нужно указать версию образов для деплоя:

Пример рабочего процесса:

# Деплой существующих образов v1.2.9
git commit --allow-empty -m "deploy_only: v1.2.9"
git tag deploy-v1.2.9
git push origin deploy-v1.2.9

# Откат на предыдущую версию v1.2.8
git commit --allow-empty -m "deploy_only: v1.2.8"
git tag rollback-v1.2.8
git push origin rollback-v1.2.8

Формат commit message:

  • deploy_only: v1.2.9 - деплоит образы с тегом v1.2.9
  • Скрипт извлекает версию из сообщения и использует соответствующие образы
  • Образы должны существовать в registry (собраны ранее через full-release)

🛠️ Скрипты деплоя

Все скрипты деплоя находятся в _deploy/scripts/:

deploy.sh

Назначение: Деплой сервисов в Kubernetes Использование:

# Full release (использует TAG для образов)
./deploy.sh v1.3.0 abc1234

# Deploy only (переопределяет тег образа)
./deploy.sh deploy-v1.2.9 def5678 v1.2.9

Параметры:

  1. tag - Git тег (обязательный)
  2. commit-sha - SHA коммита (опциональный)
  3. image-tag-override - Переопределение тега образа (опциональный, для deploy_only)

Возможности:

  • Обновляет deployment-манифесты новыми тегами образов
  • Применяет манифесты в кластер
  • Ожидает завершения rollout с таймаутом
  • Запускает проверки здоровья после деплоя
  • Показывает статус подов

rollback.sh

Назначение: Откат деплоев к предыдущей версии Использование:

# Откат одного сервиса
./rollback.sh telegram-listener

# Откат всех сервисов
./rollback.sh all

Возможности:

  • Показывает историю ревизий
  • Выполняет kubectl rollout undo
  • Ожидает завершения отката
  • Запускает проверки здоровья после отката

health-check.sh

Назначение: Проверка здоровья всех сервисов NOCR Использование:

./health-check.sh

Проверяет:

  • Статус подов (Running/Ready)
  • Health-эндпоинты (/health)
  • Последние события для упавших подов

📦 Оптимизации

Общий NuGet-кэш

Все пайплайны используют общий временный volume для NuGet-пакетов:

  • Первый dotnet restore скачивает пакеты
  • Последующие сборки переиспользуют кэшированные пакеты
  • ~60% быстрее, чем индивидуальное восстановление для каждого сервиса

Параллельное выполнение

  • Публикация контрактов: 3 сервиса параллельно
  • Сборка Docker: 3 параллельных потока
  • Независимые операции никогда не блокируют друг друга

Кэширование Kaniko

Все сборки Kaniko используют:

  • --cache=true - Включено кэширование слоев
  • --cache-repo=hub.musk.fun/k8s/cache/* - Общий репозиторий кэша
  • --compressed-caching=true - Быстрая передача кэша

🧪 Поддержка Testcontainers

Пайплайны валидации Feature и Main включают Docker-in-Docker сервис для Testcontainers:

services:
  - name: docker
    image: docker:27-dind
    privileged: true

Тесты могут использовать Testcontainers для запуска реальных баз данных, очередей сообщений и т.д.


🔒 Необходимые секреты

Настройте эти секреты в Drone:

  • hub_username - Имя пользователя Docker registry
  • hub_password - Пароль Docker registry
  • nuget_musk_api_key - API-ключ NuGet-фида

📊 Дерево решений пайплайна

Push в feature/* → Feature Validation (сборка + тесты)
Push в main → Main Validation (сборка + тесты)

Тег + "contracts_only:" → Contracts Publish
Тег + "deploy_only:" → Deploy Only
Тег (без маркеров) → Full Release (контракты → образы → деплой)

🎓 Лучшие практики

  1. Функциональные ветки

    • Всегда создавайте функциональные ветки для новой работы
    • Дайте CI валидировать перед мерджем в main
  2. Изменения контрактов

    • Используйте contracts_only: для быстрого обновления контрактов
    • Другие сервисы могут сразу обновить ссылки
  3. Процесс релиза

    • Создавайте теги только из ветки main
    • Используйте семантическое версионирование (v1.2.3)
    • Теги, начинающиеся с v, автоматически деплоятся в k8s
  4. Экстренный откат

    # Быстрый откат через deploy-only
    git commit --allow-empty -m "deploy_only: v1.2.8"
    git tag rollback-v1.2.8
    git push origin rollback-v1.2.8
    
    # Или используйте скрипт отката напрямую в кластере
    kubectl exec -it deploy-pod -- bash
    cd /flea/_deploy/scripts
    ./rollback.sh all
    
  5. Мониторинг деплоев

    • Следите за UI Drone для прогресса пайплайна
    • Проверяйте логи подов: kubectl logs -f deployment/telegram-listener -n nocr
    • Запускайте проверки здоровья: ./_deploy/scripts/health-check.sh

🐛 Устранение неполадок

Пайплайн завис на "Waiting for contracts"

Причина: Публикация контракта упала Решение: Проверьте NuGet-фид, проверьте API-ключ

Сборка Docker падает с ошибкой "unauthorized"

Причина: Неверные учетные данные registry Решение: Обновите секреты hub_username и hub_password

Тесты падают с ошибкой "Cannot connect to Docker daemon"

Причина: Testcontainers не может достичь Docker-in-Docker сервиса Решение: Проверьте, что переменная окружения DOCKER_HOST установлена правильно

Деплой падает с ошибкой "ImagePullBackOff"

Причина: Образ не найден в registry Решение: Проверьте, что образ был собран и запушен успешно на предыдущем этапе

YAML-ошибки в .drone.yml

Причина: Неправильное форматирование многострочных команд или двоеточие в переменных Решение:

  • Используйте блоки | для многострочных команд
  • Экранируйте переменные с двоеточиями (например, "${VAR:0:7}")
  • Проверьте YAML: python3 -c "import yaml; list(yaml.safe_load_all(open('.drone.yml')))"

📚 Дополнительные ресурсы


🔄 История изменений (15-16 октября 2025)

Исправлена критическая проблема с YAML

Проблема:

  • Ошибка yaml: line 126: mapping values are not allowed in this context
  • Многострочные команды /kaniko/executor содержали переменные с двоеточием (${DRONE_COMMIT_SHA:0:7})
  • YAML парсер интерпретировал двоеточие как разделитель ключ:значение

Решение:

  1. Обернули все команды /kaniko/executor в многострочные блоки с |
  2. Добавили обратные слэши \ для продолжения команды
  3. Экранировали аргументы с двоеточиями в кавычках

Пример:

# До (неправильно):
commands:
  - /kaniko/executor
    --destination=hub.musk.fun/image:${DRONE_COMMIT_SHA:0:7}

# После (правильно):
commands:
  - |
    /kaniko/executor \
      --destination=hub.musk.fun/image:${DRONE_COMMIT_SHA:0:7}    

Добавлены новые функции

  • Контракты-только пайплайн для быстрой итерации
  • 🚀 Деплой-только пайплайн для откатов
  • 🔄 Обработка MessageEdited событий
  • 📝 Скрипт автокоммита субмодулей
  • Оптимизированный общий NuGet-кэш
  • 🔧 Параллельная сборка и деплой

📞 Поддержка

Если у вас возникли проблемы с CI/CD:

  1. Проверьте логи в Drone UI: https://drone.musk.fun/nocr/flea
  2. Проверьте статус подов: kubectl get pods -n nocr
  3. Запустите health-check: ./health-check.sh
  4. Проверьте логи контейнеров: kubectl logs -f <pod-name> -n nocr

Для вопросов по инфраструктуре обращайтесь к DevOps-команде.