Дайджесты новостей
Редакционная иллюстрация: двухпанельный послойный аудит контейнера выявляет скрытые избыточные файлы в слоях сборки.

Dive: послойный аудит Docker-образов и контроль чистоты в CI

Каждый инженер, упаковывавший веб-приложение в контейнер, хотя бы раз сталкивался с парадоксальной ситуацией: проект состоит из нескольких простых скриптов, а итоговый Docker-образ весит полтора гигабайта. Попытка исправить ситуацию добавлением команды RUN rm -rf /tmp/build-cache в конец Dockerfile ничего не меняет: размер образа остается прежним или даже слегка увеличивается. В результате замедляется развертывание в Kubernetes, растут счета за облачный реестр, а ноды тратят минуты на скачивание раздутых слоев.

Консольная утилита Dive, созданная инженером Алексом Гудманом на языке Go, помогает найти первопричину лишнего веса. Инструмент предлагает интерактивный аудит каждого слоя контейнера и позволяет встроить жесткий автоматический контроль чистоты сборки прямо в пайплайны непрерывной интеграции (CI/CD).

Ловушка неизменяемых слоев в OverlayFS

Причина раздувания контейнеров кроется в архитектуре многослойных файловых систем UnionFS и OverlayFS, лежащих в основе Docker. Образ представляет собой стопку неизменяемых слоев, накладывающихся друг на друга подобно прозрачным пленкам. Если на втором слое распаковывается архив с зависимостями на 400 МБ, а на третьем слое он удаляется, файл становится невидимым в готовом контейнере, но физически навсегда остается запеченным во втором слое.

Dive анализирует файловые дескрипторы и сопоставляет метаданные inode по всей толще слоев. Утилита вычисляет два ключевых показателя:

  • Wasted Space: суммарный объем дискового пространства, занятый файлами, которые были перезаписаны или удалены на более поздних этапах сборки.
  • Image Efficiency Score: процент полезного использования объема (соотношение реально видимых файлов к суммарному размеру всех слоев).

В двухпанельном терминальном интерфейсе слева выводится список слоев с точным размером и командами Dockerfile, а справа — дерево файлов результирующей системы с цветовой индикацией: зеленым подсвечиваются новые файлы, желтым — измененные, а красным — скрытые удаленные остатки.

Сквозной сценарий: от терминала до блокировки в CI

Для разового исследования образа достаточно запустить утилиту в командной строке или выполнить проверку через официальный контейнер:

# Интерактивный анализ локального или удаленного образа
dive nginx:alpine

# Сборка проекта и мгновенный переход к исследованию слоев
dive build -t my-company-api:latest .

# Запуск аудита через изолированный Docker-контейнер
docker run --rm -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  wagoodman/dive:latest my-company-api:latest

Чтобы предотвратить случайное попадание мусорных файлов в продакшен, Dive встраивается в автоматический конвейер CI. При установке переменной окружения CI=true утилита отключает интерактивный интерфейс и валидирует образ по правилам файла .dive-ci:

# .dive-ci - пороговые значения для проверки сборки
rules:
  # Минимально допустимый коэффициент полезности образа (от 0 до 1)
  lowestEfficiency: 0.95

  # Максимально допустимый объем потерянных байтов
  highestWastedBytes: 20MB

  # Допустимая доля потерь в пользовательских слоях (без учета базового образа)
  highestUserWastedPercent: 0.15

Если неаккуратный коммит оставит в промежуточных слоях тяжелый кэш пакетов или временный тестовый архив, утилита завершит работу с ненулевым кодом выхода, заблокировав выкатку дефектного билда.

Границы применения и инженерный вердикт

Dive незаменим при оптимизации классических многоэтапных Dockerfile, поиске забытых ключей доступа и отладочных утилит (curl, gcc), случайно оставленных в промежуточных слоях.

Однако утилита теряет смысл в проектах, где контейнеризация изначально построена на минималистичных образах без дистрибутива (Distroless) или инструментах вроде ko и apko, которые генерируют однослойные бинарные артефакты вообще без промежуточных шагов сборщика. Также при запуске в контейнере требуется аккуратный проброс сокета Docker с соответствующими привилегиями.

Для большинства команд Dive остается самым наглядным инструментом оптимизации: сокращение веса образа с гигабайта до сотни мегабайт не только экономит терабайты сетевого трафика, но и в разы снижает потенциальную поверхность атак.