Перейти к содержанию

Инвентаризация /var/lib/docker: что съедает диск и почему штатная уборка это пропускает

Опубликовано
  • Админы
Инвентаризация /var/lib/docker
Четыре статьи расхода внутри каталога докера

Раздел под корень заполнен на 95 %, мониторинг об этом уже напомнил. Запускается штатная уборка — docker system prune -f, — рапортует про освобождённую пару сотен мегабайт, и на этом всё заканчивается: свободного места как не было, так и нет. Ещё через час демон отказывается поднимать контейнеры, а du по каталогу /var/lib/docker выдаёт сорок гигабайт.

Команда при этом исправна. Просто круг её обязанностей описан в документации довольно узко, и совпадает он с ожиданиями администратора далеко не всегда. Разберём каталог по статьям расхода — и посмотрим, каким инструментом берётся каждая из них.

ℹ️ Справка

Перечень того, что забирает docker system prune без единого флага, выглядит так: остановленные контейнеры, сети без единого потребителя, dangling-образы, неиспользуемый кэш сборки. Ни логи живых контейнеров, ни тома в этот список не входят — а основной объём чаще всего накапливается именно в них.

Инвентаризация до того, как что-то удалено

Стартовать стоит ровно с одной команды:

docker system df
TYPE            TOTAL   ACTIVE   SIZE      RECLAIMABLE
Images          5       2        16.43MB   11.63MB (70%)
Containers      2       0        212B      212B (100%)
Local Volumes   2       1        36B       0B (0%)

Ключевая колонка — RECLAIMABLE, она задаёт потолок: больше этого освободить не выйдет при всём желании. Отдельно сравните сумму по колонке SIZE с фактическим весом каталога /var/lib/docker. Заметный разрыв означает, что объём ушёл мимо этой таблицы, — а мимо неё проходят логи контейнеров. Детализация включается флагом -v: каждая строка разворачивается в перечень конкретных образов, контейнеров и томов, с колонками SHARED SIZE и UNIQUE SIZE. Так проще всего вычислить образ-тяжеловес.

Карта /var/lib/docker
Колонка «system prune» описывает работу команды без дополнительных флагов. Составлено по документации Docker.

Ротация, которой из коробки нет

За логи по умолчанию отвечает драйвер json-file. Значения его опций из документации: max-size-1, то есть без предела, max-file1, compressfalse. Вдобавок параметр max-file просто игнорируется, пока не выставлен max-size. Итог: ротация не настроена, и разговорчивый контейнер льёт всё в единственный файл, пока раздел не кончится.

Оценить масштаб:

du -sh /var/lib/docker/containers/*/*-json.log | sort -h | tail -5

Правится через /etc/docker/daemon.json:

✅ Как правильно

{
  "log-driver": "local",
  "log-opts": { "max-size": "20m", "max-file": "5" }
}

На драйвер local документация указывает прямо: ротация у него включена изначально (20 МБ на файл, пять файлов, со сжатием), а формат хранения экономнее. Взамен придётся смириться с одним ограничением: docker logs продолжит работать, а вот внешние агенты, которые парсят *-json.log с диска, останутся ни с чем. При наличии таких агентов разумнее задержаться на json-file, прописав ему max-size и max-file явно.

Тут же и типовая ловушка. Новые настройки драйвера из daemon.json распространяются исключительно на контейнеры, созданные позже правки, — перезагрузка демона ранее созданным ничего не даст. Узнать, что реально используется:

docker inspect -f '{{.HostConfig.LogConfig.Type}}' имя_контейнера

Увидели прежний json-file без опций — контейнер придётся пересоздать через docker compose up -d --force-recreate; простого рестарта недостаточно. Срочно освободить место поможет обнуление файла:

truncate -s 0 $(docker inspect -f '{{.LogPath}}' имя_контейнера)

Работает однократно: пока конфигурация не изменена, файл наберёт прежний вес снова.

Данные, которые уборка обходит намеренно

⚠️ Осторожно

Тома оставлены в стороне не по недосмотру: в них лежат данные. Ключ --volumes расширяет уборку только на анонимные тома, именованные при этом уцелеют. До них добирается docker volume prune --all — но сначала стоит пробежать глазами список и удостовериться, что там не окажется базы Immich или конфигурации Home Assistant. Аналогично ведёт себя docker compose down: тома остаются на месте, снести их способен только вариант down -v.

Отдельная статья расхода — writable-слой контейнера. Когда приложение складывает кэш или пользовательские загрузки внутрь контейнера вместо тома, каталог overlay2 пухнет без всяких внешних признаков. Показывает это следующая команда:

docker ps -s

Первая величина в колонке SIZE относится к writable-слою, значение virtual в скобках включает ещё и read-only слои образа. Гигабайты в writable-слое — признак не проблемы докера, а забытого тома для конкретного каталога. Когда всё перечисленное уже сделано, а места по-прежнему мало, остаются образы: docker system prune -a снимет не только dangling, но и все, на которые не ссылается ни один контейнер.

Кэш сборки и его собственный сборщик мусора

Второе место по объёму почти всегда занимает кэш BuildKit — при условии, что на хосте что-нибудь собирается: CI-раннер, docker compose build. Штатная уборка его затрагивает, но лишь в неиспользуемой части. Управлять по возрасту позволяет отдельная команда:

docker buildx prune --filter until=72h

За автоматическую чистку отвечает секция builder.gc всё того же daemon.json. Документация перечисляет четыре политики по умолчанию: эфемерный кэш вычищается спустя 48 часов, любой неиспользуемый — спустя 60 дней, а верхнюю границу задаёт defaultKeepStorage (в случае Docker Desktop это разворачивается в 20 ГБ). Серверного значения по умолчанию документация не приводит, поэтому лимит имеет смысл выставить самостоятельно: иначе границей для кэша окажется объём диска, а не выбранная вами цифра.


Источники

💬 Вопрос к сообществу

Кто оказался главным потребителем места на вашем хосте — журналы, кэш сборки или тома, про которые все забыли? И как прошёл переезд на драйвер local, если он был: возникали ли конфликты со сборщиками логов?

Featured Replies

No posts to show

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

Последние посетители 0

  • Ни одного зарегистрированного пользователя не просматривает данную страницу
Яндекс.Метрика

Account

Navigation

Поиск

Поиск

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.