Автоматический анализ сбоев в CI/CD: как сократить время разбора логов с часов до секунд
В современных процессах разработки пайплайны непрерывной интеграции и доставки (CI/CD) выполняют множество задач: компиляцию, тесты, сканирование безопасности, подпись артефактов и деплой. С ростом масштабов инфраструктуры отладка усложняется. Когда пайплайн падает, инженеры анализируют гигантские логи. Например, в практике команды Release Engineering в Red Hat при сборке дистрибутивов задача подписи образов может генерировать лог объемом более 170 000 строк, где сама ошибка скрывается в районе 4000-й строки. Ручной поиск первопричины в таких условиях занимает от получаса до нескольких часов на один инцидент.
Традиционные инструменты сбора логов (ELK, Splunk, Datadog) не понимают контекст выполнения CI/CD. Встроенная аналитика GitHub Actions или GitLab CI показывает лишь статус шагов, не давая ответа на вопрос о первопричине. Попытки использовать стандартных ИИ-ассистентов «в лоб» проваливаются, поскольку они не имеют доступа к динамическому окружению Kubernetes, не знают о взаимосвязях задач Tekton и специфике авторизации во внешних реестрах.
Для решения этой проблемы команда Red Hat в рамках платформы Konflux внедрила подход на основе анализа сбоев непосредственно на этапе выполнения пайплайна. Решение базируется на использовании финальных задач (finally tasks) в Tekton. Такие задачи гарантированно запускаются в конце пайплайна независимо от исхода предыдущих шагов. Анализатор собирает системные сигналы из API Kubernetes, дистиллирует логи до компактного payload размером около 500 байт и передает его в языковую модель (LLM) для генерации точного диагноза. Внедрение системы сократило среднее время локализации проблемы с 30–60 минут до менее чем 5 секунд, снизив еженедельные затраты инженеров со 100+ часов до менее чем 5.
Ниже представлено руководство по реализации такой системы в вашей инфраструктуре.
Инструкция по развертыванию автоматического анализатора логов CI/CD
1. Подготовка окружения и прав доступа (Prerequisites)
Убедитесь, что в кластере Kubernetes настроена система Tekton Pipelines, а конфигурации пайплайнов находятся под контролем команды. Анализатору требуются права на чтение конфигураций и логов. В терминале управления кластером создайте выделенную сервисную учетную запись (ServiceAccount) и назначьте ей минимально необходимые права (RBAC) для чтения ресурсов в вашем пространстве имен (namespace).
!IMPORTANT Для обеспечения безопасности строго соблюдайте принцип наименьших привилегий. Не назначайте аккаунту анализатора права администратора кластера (
cluster-admin). Он должен иметь доступ только на чтение (get,list) ресурсовpipelineruns,taskruns,pods,eventsиpods/logв конкретном пространстве имен.
Пример манифеста для создания роли:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: ci-pipelines
name: pipeline-analyzer-role
rules:
- apiGroups: ["tekton.dev"]
resources: ["pipelineruns", "taskruns"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods", "pods/log", "events"]
verbs: ["get", "list"]
2. Настройка пайплайна (Tekton Pipeline Configuration)
Чтобы анализатор запускался при любом исходе сборки, объявите его в секции spec.finally вашего файла конфигурации Pipeline. Согласно спецификации Tekton, задачи из этого блока выполняются после завершения основных задач.
Вставьте следующий фрагмент в описание пайплайна:
spec:
tasks:
- name: build-app
taskRef:
name: build-task
finally:
- name: analyze-pipeline-failures
taskRef:
name: pipeline-analyzer-task
params:
- name: pipelineRunName
value: $(context.pipelineRun.name)
- name: namespace
value: $(context.pipelineRun.namespace)
Официальная документация доступна по ссылке: Tekton Pipelines Spec.
3. Сбор системных сигналов из API Kubernetes
Внутри контейнера диагностической задачи должен выполняться скрипт, опрашивающий API-сервер для сбора метаданных:
- Получите статус всех шагов через TaskRun API:
kubectl get taskruns -o json. - Извлеките состояние контейнеров внутри подов:
kubectl get pods -o json(ищите состоянияOOMKilled,ImagePullBackOffили событияEviction). - Соберите коды завершения процессов (
exit codes) для упавших контейнеров.
4. Алгоритм дистилляции логов (Log Distillation)
Для эффективной работы напишите модуль предварительной фильтрации логов со следующей логикой:
- Выполняйте поиск по известным сигнатурам сбоев (ключевые слова
ERROR,Failed,Exception,timeout). - Группируйте и дедуплицируйте повторяющиеся ошибки. Если в логе содержится 135 идентичных строк от утилиты подписи
cosignоб ошибке подключения к серверуRekor, сожмите их до одной записи со счетчиком. - Сохраняйте только контекстные строки (например, 5 строк до и после ошибки), полностью удаляя успешные шаги, индикаторы прогресса загрузки пакетов и избыточный вывод сборщиков.
- На выходе сформируйте компактный JSON-объект, содержащий только критически важные сигналы сбоя.
5. Безопасность и маскирование данных (Data Sanitization)
Перед отправкой дистиллированного лога в модель проведите процедуру очистки данных.
!CAUTION Логи сборки могут содержать конфиденциальную информацию: секретные токены, пароли к реестрам, приватные ключи подписи, внутренние доменные имена и IP-адреса. Передача этих данных во внешние системы является уязвимостью.
Настройте парсер санитаризации:
- Заменяйте любые строки, похожие на приватные ключи, токены или пароли, на заглушки (
[REDACTED_SECRET]). - Маскируйте внутренние URL-адреса и пути к закрытым репозиториям.
- Если политика безопасности запрещает передачу данных за пределы контура организации, настройте использование локально развернутой модели (например, с помощью платформы InstructLab) вместо коммерческих внешних API.
6. Классификация ошибок и интеграция с LLM
Отправьте очищенный JSON-вывод в языковую модель. Задайте системный промпт, требующий классифицировать ошибку по одному из типов:
OOMKilled— превышен лимит оперативной памяти. Рекомендация: увеличить лимит в YAML-манифесте.AuthFailure— ошибка авторизации во внешнем сервисе. Рекомендация: обновить секрет доступа.ExternalServiceFailure— недоступность внешнего API. Рекомендация: повторить попытку через 10 минут.BuildError— синтаксическая ошибка в коде. Рекомендация: передать задачу автору коммита.
Пример входного JSON-контекста для LLM:
{
"pipelineRun": "ocp-stage-4-14-managed",
"namespace": "release-prod",
"failedTask": "rh-sign-image-cosign",
"category": "EXTERNAL_SERVICE_FAILURE",
"signals": {
"failedContainers": [{"name": "sign", "exitCode": 1}],
"duplicateErrors": [{"pattern": "rekor server unavailable", "count": 135}],
"impact": "26 of 66 images failed"
},
"redactions": {"tokens": 4, "internalUrls": 3}
}
7. Оповещение команды
Настройте отправку готового диагноза через интеграционный вебхук в корпоративный чат (например, Slack). Сообщение должно содержать имя упавшего пайплайна, ссылку на веб-интерфейс, четко сформулированную первопричину сбоя на русском языке и конкретный шаг для исправления ситуации (remediation).
Как проверить работоспособность (Verification Actions)
- Намеренно спровоцируйте ошибку в тестовом пайплайне (например, передайте неверный токен доступа или установите заниженный лимит памяти).
- Запустите пайплайн и убедитесь с помощью
kubectl get taskruns, что задача-анализатор в блокеfinallyзапустилась и завершила работу. - Проверьте отправленное уведомление в чате. Убедитесь, что в тексте сообщения отсутствуют сырые секреты и внутренние адреса вашей сети.
- Сравните сгенерированный ИИ диагноз с логами ручного разбора, чтобы оценить точность классификации (целевой показатель ложноотрицательных срабатываний должен быть ниже 5%).

