Уязвимости в образах контейнеров: где ломается Trivy CI/CD
Образ с известными уязвимостями доезжает до прода чаще не потому, что сканирования нет, а потому что оно стоит не на том шаге. Отчёт формируется, складывается в артефакты, кто-то его просматривает — а контейнер уже в реестре и уже развёрнут. Дальше начинается дорогое: экстренный перевыпуск, откат сервиса, внеплановое согласование изменений в рабочее время.
Цена умножается на число сервисов. Уязвимость в базовом слое — это не один релиз, а все образы, собранные от той же основы, включая те, что никто не трогал месяцами. Отдельная ловушка — подмена базового образа: тег указывает на пересобранного родителя, содержимое поменялось, а прежние проверки этого не заметили, потому что сравнивали имя, а не неизменяемую ссылку.
Типовые причины сбоя выглядят буднично: шаг проверки стоит после публикации в реестр; ненулевой код возврата гасится, чтобы сборка «не краснела» перед релизом; слои, поднятые из кэша, повторно не разбираются. Тогда сканирование на сборке формально есть, но решения об остановке не принимает никто, и уязвимые образы проходят ревью по инерции.
Всё это не про отсутствие инструмента в конвейере, а про его место в процессе и про то, что считать блокирующим. Разбираем, как это закрывается: где ставить проверку, какие пороги останавливают выпуск и как удержать безопасность контейнеров на уровне, который не обходится в спешке.
Что даёт сканирование образов в Trivy CI/CD
Контроль уязвимостей на каждом коммите
Образ проверяется на слои и зависимости приложения сразу после сборки, а не раз в квартал по регламенту. Отчёт привязан к конкретному тегу, поэтому видно, какая библиотека дала находку и чьё изменение её принесло. Критичные уязвимости перестают копиться месяцами — их закрывают в момент появления, пока правка стоит одной строки в манифесте зависимостей.
Сборка растёт на секунды, а не на минуты
База уязвимостей подтягивается один раз и переиспользуется между задачами, проверяется изменённый слой, а результат возвращается в тот же отчёт сборочной линии. Инженер не переключается в отдельный интерфейс и не ждёт ручной проверки в конце недели.
Блокировка выката по порогу
Политика сборочной линии останавливает публикацию при находках критичного уровня, значимые помечает предупреждением для разбора. Образ с известной дырой физически не доходит до эксплуатации, и класс отказов «выкатили уязвимую сборку» уходит из процесса.
Реестр перестаёт расти
Сканер Trivy отсекает проблемные образы до отправки в реестр: непрошедшие сборки не публикуются вовсе, а правило жизненного цикла держит последние сборки на ветку и чистит остальное. Реестр растёт по числу релизов, а не по числу попыток сборки — объём хранилища сокращается в разы, при этом откат на предыдущий релиз остаётся возможным.
Режимы проверки: от ручного прогона до блокировки сборки
Режим проверки — это не про то, включён ли Trivy в конвейер, а про то, где именно стоит решение о том, можно ли двигать образ дальше. Порог критичности задаётся один раз и определяет, какие уровни уязвимостей считать провалом сборки: без него отчёт появляется, а реакции на него нет.
Ниже четыре режима сканирования — от самого мягкого к самому жёсткому. На практике их не выбирают навсегда, а комбинируют: быстрая обратная связь разработчику на сборке плюс страховка на входе в рабочую среду.
| Режим | Когда подходит | Ограничения |
|---|---|---|
| Ручной прогон | Знакомство с образами, разбор накопленного долга | Регулярность держится на человеке, результат не остаётся в истории сборки |
| Проверка на сборке без блокировки | Команда только вводит практику, много срабатываний на базовых слоях | Отчёт читают не всегда, уязвимость уходит в реестр вместе с образом |
| Блокировка сборки по порогу критичности | Публикуемые образы, важно не вынести известную уязвимость | Нужна политика исключений, иначе сборки встают на чужих зависимостях |
| Проверка в реестре по расписанию | Образы лежат долго и не пересобираются | Находит проблему после публикации: неясно, что делать с выпущенным тегом |
| Контроль на входе в среду | Критичные среды, где недопустим запуск непроверенного образа | Отказ на запуске — самая дорогая задержка, нужен понятный путь к откату |
Выбор режима — это выбор того, насколько рано команда готова узнать о проблеме и сколько ручной работы готова на это тратить.
Порядок внедрения: от аудита образа до регламента
Сканирование образов редко ломается на самом сканере — обычно всё упирается в порядок работ: проверку включают сразу на всех сборках, получают сотни срабатываний в первом же отчёте и через неделю отключают, потому что релиз встал. Мы идём обратным путём: от инвентаризации того, что уже собирается и запускается, к правилам, которые команда готова поддерживать долго.
- Аудит образов. Собираем перечень базовых образов, реестров и сборочных заданий, смотрим, что тянется из внешних источников и где нет закрепления по контрольной сумме, — получаем карту того, что вообще предстоит проверять.
- Схема допусков. Договариваемся, что считать блокирующим: критичные уязвимости с доступным исправлением останавливают сборку, остальное уходит в отчёт и очередь на разбор. Без этого правила внедрение скатывается в спор о каждой строке.
- Настройка сканирования. Встраиваем Trivy в сборку и в проверку перед отправкой в реестр, разносим уровни строгости для веток разработки и релизных, кэшируем базу уязвимостей, чтобы проверка не тянула её заново.
- Проверка на реальных образах. Прогоняем правила на текущих артефактах, а не на учебных: смотрим, сколько срабатываний реально блокируют сборку, и калибруем пороги, пока добавленное время не станет незаметным.
- Исключения и срок их жизни. Оформляем обоснованные исключения с ответственным и датой пересмотра — так временное послабление не превращается в постоянную дыру в схеме допусков.
- Регламент и передача. Фиксируем порядок действий при срабатывании, точки отката и порядок обновления правил, проводим разбор с командой и отдаём документацию вместе с настройками.
Пакет передачи: политики, конфигурации и документация
После сдачи в репозитории остаётся вся обвязка вокруг Trivy: не только запускаемые проверки в CI/CD, но и конфигурация, политики и регламенты. Всё это версионируется рядом с кодом и меняется через обычное ревью изменений, а не через переписку с подрядчиком.
- Конфигурация проверок — файл настроек сканирования с наборами правил, уровнями серьёзности и списком исключений; каждый пропуск помечен владельцем и датой пересмотра.
- Политики допуска образов — какие уязвимости блокируют сборку, какие только логируются, для каких веток действует строгий режим.
- Артефакты сканирования — отчёт в машиночитаемом виде и состав образа в форматах CycloneDX или SPDX, привязанные к тегу сборки.
- Регламент реагирования — таблица «уровень серьёзности → срок реакции → ответственный», порядок подтверждения и снятия исключений.
- Инструкции для дежурных — как читать отчёт, что делать при критичной находке в опубликованном образе, как откатиться на предыдущий тег.
- Схема интеграции — на каких этапах конвейера запускается проверка, куда уходят результаты и как они связаны с журналом сборки.
- Журнал решений — разбор спорных находок с командой и точка расширения: куда добавлять новые правила и как их проверять.
Разбор: как закрыли поток уязвимых образов в продуктовой команде
До внедрения проверку образов команда делала руками раз в квартал: отчёт приходил в тикет, когда образ уже стоял в проде, а тег успевал перезаписаться. Воспроизводимой сборки не оставалось, и источник находки искать было нечем. Треть образов в реестре несла уязвимости с готовым исправлением, а от обнаружения до пересборки проходило девять дней.
Что изменили
Сканирование на Trivy поставили отдельным шагом перед публикацией в реестр — на той же сборке, что уходит в прод. Сборка падает на критичных и высоких находках, для которых есть исправленная версия зависимости; остальное уходит в отчёт для разбора. Список обоснованных исключений лежит в репозитории рядом с кодом — каждое с причиной и владельцем, чтобы правило не глушили целиком. Базу уязвимостей кешируем на сборочном узле: шаг добавляет к сборке секунды, а не минуты.
Что стало
Доля образов с критичными уязвимостями упала с трети до единиц процентов — до прода доходит только то, что прошло проверку. От обнаружения до пересборки теперь несколько часов вместо девяти дней: правка зависимости и новый тег идут одним проходом. Ушёл целый класс инцидентов «уязвимость в базовом слое» — раньше их разбирали по факту, теперь образ с таким слоем просто не публикуется. У релизного инженера освободилось около шести часов в неделю, которые уходили на ручные сверки списков.
Чем отличается проверка в реестре от проверки на сборке?
Проверка на сборке отвечает на вопрос «можно ли вообще выпускать этот образ». Сканирование вроде Trivy выполняется до отправки в реестр, результат становится частью отчёта сборки, и по критичности срабатывает порог: сборка падает, артефакт дальше не уходит. Это единственный режим, который что-то предотвращает, — но видит он только те образы, что прошли через конвейер, и только на момент сборки.
Проверка в реестре отвечает на другой вопрос: что уже лежит в хранилище и не стало ли оно опасным. Состав образа неизменяем, а база уязвимостей обновляется постоянно — образ, чистый на сборке, через несколько недель получает критичные находки, потому что их раскрыли позже. Поймать это может только регулярное сканирование реестра, зато оно ничего не блокирует: это сигнал, а не шлагбаум.
Разница подходов видна и в охвате. На сборке под контроль попадает только то, что собирает конвейер; образы, принесённые извне, собранные вручную или взятые у внешнего поставщика, остаются вне проверки. Реестр закрывает эту дыру — сканирует по манифесту всё, что запушено, включая старые версии, которые никто не пересобирает. Ограничение тоже есть: без доступа к слоям или при неполном манифесте часть находок теряется.
Практический вывод — не «или», а «и то, и другое, с разными ролями». На сборке держим блокирующий порог по критичным уязвимостям и явный список исключений, чтобы выпуск не ломался из-за ложных срабатываний. В реестре — регулярный пересмотр с отчётом и понятным правилом: какой образ и в какой срок пересобирать или отзывать.
Технические сомнения инженеров: разбираем возражения
Перед пилотом инженеры задают одни и те же вопросы: не превратится ли проверка в поток ложных срабатываний, не затормозит ли сборку, что делать в закрытом контуре. Разбираем каждый пункт так, как он решается в реальных сборках.
Сканер Trivy ставим на этап сборки образа, до публикации в реестр. Порог блокировки задаём по уровню критичности — сборка падает только на том, что действительно требует правки.
Ложные срабатывания заблокируют сборку?
Порог отсекает основную часть шума: проверяем только исправляемые уязвимости пакетов, находки без доступного обновления не поднимаются в блокирующие. Спорные случаи уходят в файл исключений — каждая строка привязана к компоненту и имеет владельца со сроком пересмотра.
Как оформляются исключения в правилах?
Проверку целиком не отключаем. Исключение — это запись с пакетом, кодом уязвимости и причиной, плюс срок, после которого оно перестаёт действовать. Такие правки идут через ревью вместе с кодом, а в отчёте видно, сколько исключений активно и какие просрочены.
Работает ли это в закрытом контуре?
Да. Обновления базы уязвимостей загружаются во внутреннее зеркало и раздаются сканеру без выхода во внешнюю сеть. Кэш базы переиспользуется между задачами, поэтому проверка не тормозит параллельные сборки и не создаёт лишней нагрузки на реестр.
Где граница ответственности?
Наша часть — сборка, настройка сканера, пороги, связка с реестром и отчёты. Ваша — приоритизация находок и обновление базовых образов: сканер показывает, что править, решение о патче принимает владелец сервиса. Список фиксируем на старте, чтобы спорные находки не зависали.
Обсудим задачу и вернёмся с оценкой и планом работ
Для старта нам нужен доступ к репозиторию и реестру образов — на чтение достаточно, чтобы посмотреть текущий конвейер, Dockerfile-ы и то, как собираются и публикуются артефакты. Плюс короткий список сервисов, где цена пропущенной уязвимости выше всего: обычно это то, что ходит наружу или работает с платёжными и персональными данными. Если есть окно, в которое допустимо менять сборку, скажите о нём сразу — от этого зависят сроки.
Дальше мы возвращаемся не общим «надо внедрить Trivy», а планом, где каждый пункт можно проверить и принять:
- план внедрения по этапам: сначала сканирование в режиме отчёта, потом блокирующие проверки на сборке и в реестре;
- политики по уровням критичности — что останавливает сборку, что уходит в отчёт, а что закрывается по сроку;
- схема встраивания в конвейер: на каком шаге запускается проверка, какие артефакты сканируются, куда уходит результат;
- регламент работы с ложными срабатываниями и список обоснованных исключений, чтобы проверки не превратились в шум;
- порядок обновления баз уязвимостей и сверки с версиями зависимостей, которые вы уже используете;
- инструкции для разработчиков: как читать отчёт, что делать при срабатывании, как согласовать исключение;
- сроки по каждому этапу и точки приёмки, где фиксируем результат.
Опишите задачу и текущее состояние сборки — вернёмся с оценкой объёма работ и планом, в каком порядке внедрять проверки без остановки релизов.







