Docker Images and Layers
Docker version 18.09.8
Общая информация
Докер образ состоит из последовательности слоев наложенный друг на друга.
Каждая команда типа COPY и RUN создает новый слой при сборке образа.
Каждый слой в процессе сборки кэшируется и может переиспользоваться, поэтому для повышения скорости сборки, слои в которых реже происходят изменения выгодно создавать вначале.
Каждый слой сохраняется как часть контейнера, удаление файлов в новом слое не удаляет их физически из предыдущего слоя, что приводит к избыточному росту размера образа, поэтому для оптимизации размера выгодно объединять команды в одну.
Будем экспериментировать на контейнере ubuntu:18.04
ubuntu 18.04 549b9b86cb8d 31 hours ago 64.2MB
$ docker run --rm -it ubuntu:test bash $ du -chx / 70M total
Размер образа 64.2MB, размер данных внутри контейнера 70MB
На сегодняшний день, в образе Ubuntu есть настройка apt менеджера, которая сама удаляет кэш после установки пакетов, для эксперимента она нам будет мешать
/etc/apt/apt.conf.d/docker-clean
Сборка #1
Dockerfile
FROM ubuntu:18.04 RUN rm -f /etc/apt/apt.conf.d/docker-clean RUN apt-get update RUN apt-get install curl
ubuntu test 853a1c2b7ca5 3 seconds ago 213MB
$ docker run --rm -it ubuntu:test bash $ du -ch /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin /var/lib/apt/lists/*.* 97M total $ du -chx / 180M totalРазмер образа 213MB (+148.8), размер данных внутри контейнера 180MB (+110), кэша 97MB
Сборка #2
Теперь добавим удаление apt кэша отдельной командой RUN
Dockerfile
FROM ubuntu:18.04 RUN rm -f /etc/apt/apt.conf.d/docker-clean RUN apt-get update RUN apt-get install curl RUN rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin /var/lib/apt/lists/*.*
ubuntu test d35d7a6be3a2 13 seconds ago 213MB
$ docker run --rm -it ubuntu:test bash $ du -ch /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin /var/lib/apt/lists/*.* 0 total $ du -chx / 84M total
Размер образа 213MB (+148.8), размер данных внутри контейнера 84MB (+14), кэша 0MB
Образ хранит слои созданные двумя предыдущими командами RUN, а в них все еще есть файлы кэша, поэтому итоговый размер образа не изменился
Сборка #3
Теперь объединим команды установки и очистки в один RUN
Dockerfile
FROM ubuntu:18.04 RUN rm -f /etc/apt/apt.conf.d/docker-clean RUN apt-get update && \ apt-get install -y curl && \ rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin /var/lib/apt/lists/*.*
ubuntu test 9e767a2936a4 About a minute ago 78.5MB
$ docker run --rm -it ubuntu:test bash $ du -chx / 84M total
Размер образа 78.5MB (+14.3), размер данных внутри контейнера 84MB (+14), кэша 0MB
Все действия выполнялись в одной команде RUN (в одном слое) - это трюк который используется повсеместно
Вот теперь прирост размера образа соответствует приросту данным
Обсуждение