Найти в Дзене
ИТ разнообразно

Доставляем образы Docker меньшего размера - лучшие практики. Часть 2.

Как Docker создаёт образ Прежде, чем приступить к практическому примеру, нам необходимо понять, как Docker подходит к созданию образов. Мы могли бы легко предположить, что образы Docker работают так же, как образы виртуальных машин. Мы устанавливаем то, что нам нужно, в результате чего, получается большой файл, который мы доставляем. Реальность совсем иная. Если вы запустите docker build несколько раз подряд, вы заметите, что первый вызов занимает некоторое время для завершения, в то время как все последующие запуски занимают лишь небольшую долю этого времени. Почему? При создании нового образа Docker создаёт его поэтапно, слой за слоем. Каждая строка в Dockerfile приводит к созданию дополнительного слоя. Если строка не изменилась, нет необходимости пересобирать слой. Рассмотрим этот Dockerfile: FROM ubuntu:latest RUN apt-get update RUN apt-get install -y vim RUN rm -rf /var/apt/lists* Мы используем ubuntu, обновляем исходники пакетов, устанавливаем vim и, после завершения, очищаем кеш

Как Docker создаёт образ

Прежде, чем приступить к практическому примеру, нам необходимо понять, как Docker подходит к созданию образов.

Мы могли бы легко предположить, что образы Docker работают так же, как образы виртуальных машин. Мы устанавливаем то, что нам нужно, в результате чего, получается большой файл, который мы доставляем.

Реальность совсем иная.

Если вы запустите docker build несколько раз подряд, вы заметите, что первый вызов занимает некоторое время для завершения, в то время как все последующие запуски занимают лишь небольшую долю этого времени.

Почему?

При создании нового образа Docker создаёт его поэтапно, слой за слоем. Каждая строка в Dockerfile приводит к созданию дополнительного слоя. Если строка не изменилась, нет необходимости пересобирать слой.

Рассмотрим этот Dockerfile:

FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y vim
RUN rm -rf /var/apt/lists*

Мы используем ubuntu, обновляем исходники пакетов, устанавливаем vim и, после завершения, очищаем кеши пакетов apt и т. д.

docker build -t layers . [+] Building 23.1s (9/9) FINISHED
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 168B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:latest 3.0s
=> [auth] library/ubuntu:pull token for registry-1.docker.io 0.0s
=> [1/4] FROM docker.io/library/ubuntu:latest@sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508 6.2s
=> [2/4] RUN apt-get update 5.6s
=> [3/4] RUN apt-get install -y vim 7.4s
=> [4/4] RUN rm -rf /var/apt/lists* 0.3s
=> exporting to image 0.6s
=> => exporting layers 0.6s
=> => writing image sha256:6dcadf381f8e3b7ee143e818884a9f2a773a23a11bdac78831671b8fcb10d233 0.0s
=> => naming to docker.io/library/layers 0.0s
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
layers latest 6dcadf381f8e 18 seconds ago 179MB

Мы хотим подтвердить количество имеющихся слоев:

$ docker inspect 6dcadf381f8e | jq ".[0].RootFS.Layers"

docker inspect выводит много информации, но нас интересует только количество слоёв. Поэтому мы используем jq, чтобы сократить вывод до основных фрагментов:

[
"sha256:59c56aee1fb4dbaeb334aef06088b49902105d1ea0c15a9e5a2a9ce560fa4c5d", "sha256:c15e21155336e02611e896a2a73e93db8d27c903aa6fff59b1cc5956669b4119", "sha256:811f5dabaddf01eb6d50d6d54da46f18acbeaba9925051ad2ac3d69b91af500f", "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
]

Результат: Четыре слоя.

Давайте повторим этот эксперимент со следующим Dockerfile:

FROM ubuntu:latest
RUN apt-get update && \
apt-get install -y vim && \
rm -rf /var/apt/lists*

Результат:

docker inspect fc57434f273e | jq ".[0].RootFS.Layers"
[
"sha256:59c56aee1fb4dbaeb334aef06088b49902105d1ea0c15a9e5a2a9ce560fa4c5d", "sha256:136403671b74fc503d5d4c2e08c8ae99ab461390f448983adb9f1e86197e80cf"
]

Мы по-прежнему запускаем те же самые команды, только теперь с двумя слоями!

Но почему вы решили использовать меньше слоёв?

При сравнении размеров образов оба занимают одинаковое количество места. Меньшее количество слоёв имеет значение, когда образ нужно (пере-)собирать.

Меньшее количество слоёв означает более быстрые сборки. Кроме того, если изменяется верхний слой, это делает недействительными все последующие слои.

Продолжение следует...

Перевод с некоторыми авторскими заголовками.

Автор оригинала: Jan Schulte.