Предлагаю вашему вниманию перевод статьи What are Docker none:none images? из блога Project Atomic.
Последние несколько дней я потратил на упражнения с образами Docker <none>:<none>
. Чтобы объяснить, что они собой представляют, и что могут натворить, я пишу этот пост, в котором ставлю вопросы:
- Что собой представляют образы Docker
<none>:<none>
? - Что собой представляют обособленные (dangling) образы ?
- Почему я вижу кучу образов
<none>:<none>
, когда делаюdocker images -a
? - В чем разница между
docker images
иdocker images -a
?
Прежде чем я начну отвечать на вопросы, запомните, что есть два вида образов <none>:<none>
: хорошие и плохие.
Хорошие образы <none>:<none>
Чтобы разобраться в них, нужно понять как работает файловая система образов Docker, и как организованы слои образов. В этом посте для примера будет использоваться образ Fedora. Демон Docker запущен на ноутбуке, и я собираюсь загрузить образ fedora из docker hub.
На этом скриншоте, docker images
показывает fedora:latest
, а docker images -a
уже два образа fedora:latest
и <none>:<none>
. Если вы используете Docker, вы замечали что количество образов <none>:<none>
растет экспоненциально числу загруженных образов.
Для чего нужны образы <none>:<none>
? Чтобы понять это, нужно знать как организованы слои файловой системы Docker. Каждый образ docker состоит из слоев, и слои имеют родительские и дочерние связи с другими слоями. Все слои файловой системы docker по умолчанию хранятся в /var/lib/docker/graph
. В терминологии Docker она называется графовой базой данных. В примере fedora:latest
состоит из двух слоев, их можно найти в /var/lib/docker/graph
.
IMAGE ID
соответствует слою в директории /var/lib/docker/graph
. Когда вы делаете docker pull fedora
, образ загружает один слой за раз. Сначала docker загружает слой 48ecf305d2cf
и помечает его <none>:<none>
, так как это лишь один из слоев образа fedora:latest
. В терминологии Docker он называется промежуточным образом из за опции -a
.
Далее Docker загружает слой ded7cd95e059
и помечает его fedora:latest
. Образ fedora:latest состоит из этих двух слоев, формируя связь родителя и дочернего элемента.
Для проверки существования родительско-дочерней связи мы можем проверить JSON файл слоя ded7cd95e059
.
Все верно! Теперь мы поняли что значат образы <none>:<none>
. Это промежуточные образы, которые могут быть увидены с использованием docker images -a
. Они не приводят к переполнению жесткого диска, но занимают много места в выводе команды. И довольно сложно понять к чему они относятся.
Мы ответили на (1), (3) и (4). Давайте прольем свет на (2).
Плохие <none>:<none>
Другие образы <none>:<none>
это обособленные образы, которые могут переполнить жесткий диск.
В языках программирования Java и Golang обособленный блок памяти, это блок без ссылок из любого места в коде. Система сборки мусора таких языков периодически помечает блоки обособленными и возвращает их в кучу, после этого эти блоки доступны для будущего использования. Подобно им, обособленный слой файловой системы Docker это что-то неиспользуемое и не имеющее ссылок из любых образов. Следовательно, нам нужен способ указать Docker очищать эти обособленные образы.
Мы уже знаем что значит <none>:<none>
в docker images -a
. Выше сказано что это промежуточные образы. Тем не менее при отсутствии образов <none>:<none>
в выводе docker images
, есть промежуточные образы, доступные для очистки. Откуда они берутся?
Эти промежуточные образы — результаты работы команд docker build
или pull
. В качестве конкретного примера,
Давайте соберем образ hello_world
используя наш загруженный ранее базовый образ fedora. Мы соберем образ hello_world
используя Dockerfile.
Как показано на верхнем скриншоте, мы успешно собрали образ hello_world
используя Dockerfile.
Прошло время после сборки образа hello_world
, и вышла новая версия Fedora. Давайте скачаем новый образ Fedora.
Я получил новый образ Fedora. Теперь я хочу собрать образ hello_world
с новой Fedora. Давайте соберем образ снова с тем же Dockerfile.
Если вы отвлечетесь и проверите, старый образ Fedora имеет IMAGE ID (ded7cd95e059
) а новый образ Fedora со скриншота выше имеет IMAGE ID (5c6d07393f9f
), это значит что образ Fedora был успешно обновлен. Важная вещь, которую нужно отметить на верхнем скриншоте это образ <none>:<none>
.
Если вы помните, образы <none>:<none>
указанные в docker images -a
это промежуточные (хорошие) образы, но этот образ <none>:<none>
является обычным образом docker. Это обособленный образ и должен быть очищен. Когда образ hello_world
пересобрали используя Dockerfile, его ссылка на старую Fedora стала неотмеченной и обособленной.
Эта команда может быть использована для очистки обособленных образов.
docker rmi $(docker images -f "dangling=true" -q)
Сейчас Docker не имеет автоматической системы сборки мусора. Будет круто иметь такую. А пока что эта команда может использоваться для ручной сборки мусора.