Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

Docker растет директория

#docker


Столкнулся с проблемой, при каждой сборке проекта постоянно растет директория /var/lib/docker/vfs/dir/

Как можно ее почистить?

При этом docker volume ls ничего не выдает
    


Ответы

Ответ 1



Почему, собирая образ с помощью Dockerfile, я получаю толстый слоеный пирог? Это связано c внутренней архитектурой Docker. Docker-образ представляет собой просто набор слоев, каждый из которых представляет собой слепок файловый системы (точнее, слепок отличий от нижележащей файловой системы) - по факту это файловая система на основе принципа copy-on-write, у которой каждый слой создается отдельной строчкой в Dockerfile. В тот момент, когда Docker необходимо собрать финальную файловую систему, он просто собирает композицию из этих слоев, и когда выполняющемуся в контейнере процессу необходимо получить содержимое файла X, собранная файловая система выдает содержимое файла в верхнем из слоев, содержащих этот файл; в случае, если нужно записать файл, он пишется в новом слое (слое контейнера). Это ключевой момент в инфраструктуре, который убивает сразу множество зайцев: Мгновенный запуск в новой файловой системе - несмотря на то что контейнер явялется почти полностью изолированной средой, для него не нужно копировать отдельную файловую систему. Файловая система собирается мгновенно, а все изменения записываются в новый слой, принадлежащий контейнеру, а сам контейнер ничего не может сделать с вышележащими слоями. Непосредственно сборка Docker-образа ведется ровно по такому же принципу: каждая строчка Dockerfile выполняется в новом слое (в новом контейнере, ФС которого собрана из предыдущих слоев), после чего этот слой коммитится (сохраняется), и следующая инструкция Dockerfile будет выполнена уже в новом контейнере, в который будет включен и текущий слой. Возможность собирать разные изображения из одних и тех же слоев: условная java:8 весит порядка 800 мб. Если бы каждый образ, который желает отнаследовать от нее, вбирал по 800 мб, то место бы выжиралось просто с невероятной скоростью. Однако система слоев позволяет один раз скачать java:8 и использовать ее во всех производных, не скачивая заново, поэтому непосредственно приложения на java:8 будут занимать всего 50-100 мегабайт места. Каждый из вышеописанных слоев имеет собственный идентификатор - такого же формата, как и контейнеры. Это, конечно, не очень human-friendly, поэтому и были придуманы реестры (серверы с изображениями), репозитории (название конкретного изображения, например ubuntu) и теги (версия изображения, например 14.04). Все это вместе (реестр-репозиторий-тег) может использоваться, чтобы отметить определенный слой в human-friendly стиле, в то время как внутренности остаются теми же самыми. И когда вы билдите новое изображение с определенным тегом, вы, де-факто, создаете еще слои файловой системы, последний из которых и отмечается заданным тегом. Со старыми слоями при этом ничего не происходит - они остаются там же, где и были, потому что команда создания нового изображения не может подразумевать удаление старых (т.к. они могут быть еще нужны) - оттуда и утечки дискового пространства. При определенных условиях (например, ADD и http-адрес архива) инструкция, несмотря на идентичность, будет каждый раз порождать новый слой, возможно, немалого объема - за этим, конечно, нужно следить и подчищать устаревшие изображения. Чтобы удалить все изображения без тега, можно воспользоваться следующим шорткатом: docker rmi $(docker images -qf "dangling=true") Последнее, о чем хочется сказать - кроме изображений, место могут жрать и т.н. volume, причина появления которых мне не очень понятна (но, тем не менее, они есть и могут "зависать" внутри хоста даже при удалении изображений). Их тоже надо время от времени чистить, для этого существует специальный скрипт.

Ответ 2



Спасибо за помощь! Вот решение: docker rmi image id можно узнать выполнив команду docker images Оказывается при сборке команда RUN добавляет новый слой к существующему образу, т.е. в Dockerfile встречается 2-е RUN команды, то образ будет с 2-я слоями и объемом равен первый слой + первый слой и незначительные изменения от 2-ой команды RUN https://xakep.ru/2015/06/04/docker-faq/ Раздел -- Почему, собирая образ с помощью Dockerfile, я получаю толстый слоеный пирог?

Ответ 3



В docker engine 1.13 можно использовать docker system prune. Смотри документацию. $ docker system prune WARNING! This will remove: - all stopped containers - all networks not used by at least one container - all dangling images - all build cache Are you sure you want to continue? [y/N]

Комментариев нет:

Отправить комментарий