#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]