Предлагаю вашему вниманию перевод статьи What are Docker none:none images? из блога Project Atomic.


Последние несколько дней я потратил на упражнения с образами Docker <none>:<none>. Чтобы объяснить, что они собой представляют, и что могут натворить, я пишу этот пост, в котором ставлю вопросы:


  1. Что собой представляют образы Docker <none>:<none> ?
  2. Что собой представляют обособленные (dangling) образы ?
  3. Почему я вижу кучу образов <none>:<none>, когда делаю docker images -a ?
  4. В чем разница между docker images и docker images -a ?

Прежде чем я начну отвечать на вопросы, запомните, что есть два вида образов <none>:<none>: хорошие и плохие.


Хорошие образы <none>:<none>


Чтобы разобраться в них, нужно понять как работает файловая система образов Docker, и как организованы слои образов. В этом посте для примера будет использоваться образ Fedora. Демон Docker запущен на ноутбуке, и я собираюсь загрузить образ fedora из docker hub.


docker images


На этом скриншоте, 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.


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 состоит из этих двух слоев, формируя связь родителя и дочернего элемента.


parent child


Для проверки существования родительско-дочерней связи мы можем проверить JSON файл слоя ded7cd95e059.


parent JSON


Все верно! Теперь мы поняли что значат образы <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


Как показано на верхнем скриншоте, мы успешно собрали образ hello_world используя Dockerfile.


Прошло время после сборки образа hello_world, и вышла новая версия Fedora. Давайте скачаем новый образ Fedora.


new fedora


Я получил новый образ Fedora. Теперь я хочу собрать образ hello_world с новой Fedora. Давайте соберем образ снова с тем же Dockerfile.


dangling


Если вы отвлечетесь и проверите, старый образ 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 не имеет автоматической системы сборки мусора. Будет круто иметь такую. А пока что эта команда может использоваться для ручной сборки мусора.

Поделиться с друзьями
-->

Комментарии (4)


  1. Sild
    26.06.2016 18:33

    Несколько дней, чтобы понять что такое промежуточный образ? При сборке из Dockerfile это понимание приходит бонусом


  1. hanovruslan
    27.06.2016 10:43

    Какой версии у вас docker engine?
    Я проверил свою /var/lib/docker (ubuntu 14.04 и Docker version 1.11.2)
    у меня там


    • aufs
    • containers
    • image
    • network
    • tmp
    • trust
    • volumes

    Это я к чему… к тому, что у меня сложилось мнение, что с каждой новой версией в engine могут быть заметно большие изменения и соот. статьи-описания того как всё работает могут быть не очень полезными. Без претензии к этой статье, но вообще об актуальности.


  1. Ravager
    27.06.2016 12:00
    +1

    слово «обособленные» так непривычно звучит в контексте программирования. dangling — «висячие» «повисшие», не имеющие ссылок извне.


    1. foxmuldercp
      28.06.2016 11:06

      Orphaned ещё, но это из терминов apt|yum про забытые/ненужные пакеты, от которых что-то раньше зависело, но теперь их можно удалить, если я правильно помню