Как создать минималистичный Docker-образ hello-world.
Мы знаем, что образы Docker состоят из ряда составных слоев, каждый из которых представляет собой дельту изменений предыдущего уровня. Например, давайте рассмотрим Dockerfile
для образа Docker nginx:alpine
:
Содержимое Dockerfile
выше взято из репозитория docker-nginx
(ссылка). Этот Dockerfile
содержит инструкции по созданию nginx:alpine
образа Docker путем добавления нового доступного для записи уровня (также известного как слой контейнера) поверх родительского образа (например, образа alpine:3.11
в строка 1). Слой с возможностью записи обычно находится там, где мы пишем новые файлы, изменяем существующие файлы и удаляем файлы, и этот слой представляет собой дельту от его нижележащих слоев.
Теперь вопрос в том, какой самый нижний или самый нижний слой образов Docker? Или, другими словами, как мы создаем базовые образы, такие как alpine
(~ 5,6 МБ) и busybox
(~ 1,2 МБ)?
Чтобы ответить на эти вопросы, мы можем проверить репозитории Git на наличие alpine
(ссылка на репо) и busybox
(ссылка на репо), а также прочитать их сценарии сборки и файлы Docker. Например, на следующем снимке экрана показан Dockerfile
для изображения busybox
.
В Dockerfile
выше строка 1 инструктирует Docker создать образ, начиная с scratch
образа. Строка 2 добавляет предварительно созданную корневую файловую систему (rootfs
) поверх образа scratch
. Обратите внимание, что команда ADD busybox.tar.xz /
извлечет файл tar
в папку назначения /
. (Это одно из различий между командами ADD
и COPY
в инструкциях Dockerfile
.) Строка 3 устанавливает точку входа по умолчанию и запускает оболочку для контейнера, в котором запущен образ busybox
.
Теперь, когда мы знаем, что самый нижний слой изображения может быть создан из scratch
изображения. Тогда что это за scratch
изображение? Хорошее место для изучения изображений - Docker Hub, как показано на следующем снимке экрана.
Несмотря на то, что образ scratch
появляется в Docker Hub, мы не можем его извлечь. На следующем снимке экрана показан ответ с ошибкой на команду docker pull scratch
.
Согласно Docker Hub, scratch
образ - это зарезервированный пустой образ Docker, который полезен в контексте создания базовых образов (таких как debian
и busybox
) или суперминимальных образов. Начиная с Docker 1.5.0, FROM scratch
не используется в Dockerfile
и не будет создавать дополнительный слой в нашем образе. Команда FROM scratch
сигнализирует процессу сборки, что мы хотим, чтобы следующая команда в Dockerfile
была первым слоем файловой системы в нашем образе.
Превосходно! Теперь у нас есть приблизительное представление об изображении scratch
. Как насчет того, чтобы создать образ Docker с нуля? Dockerfile
должен выглядеть следующим образом.
В Dockerfile
строка 1 указывает, что это изображение будет начинаться с пустого изображения. Строка 2 копирует файл hello
в корневую файловую систему, а строка 3 выполняет программу hello
.
Поскольку рабочий образ ничего не содержит, программа hello
должна быть двоичным файлом Linux, который статически скомпилирован, чтобы его можно было выполнять в минималистичном контейнере Docker. Чтобы создать статически скомпилированные двоичные файлы, мы можем собрать их из кода на Go или C / C ++. Например, есть несколько статей (link1, link2, link3), в которых рассказывается о том, как создать самый маленький исполняемый файл hello world в Linux. В этой статье я буду использовать двоичный файл из статьи Самый маленький x86 ELF Hello World. Мы можем выполнить следующие команды, чтобы загрузить helloworld.tar.gz
файл из этой статьи и извлечь его в папку.
После загрузки и извлечения файла tar
мы можем переключиться в папку helloworld
и протестировать исполняемый файл. На следующем снимке экрана показаны извлеченные файлы и выполнение программы hello
.
Из приведенного выше снимка экрана мы можем подтвердить, что двоичный файл hello
имеет размер всего 142 байта и при запуске выводит на консоль строку «Hi World
».
Чтобы создать образ, мы перемещаем Dockerfile
в каталог helloworld
и запускаем следующую команду.
docker build --tag hello .
После успешного создания образа мы можем проверить размер образа и запустить его в контейнере Docker, как показано ниже.
Первая команда docker image ls hello
дает некоторые показатели о нашем недавно созданном изображении. Показатели показывают, что размер изображения составляет 142 байта, что совпадает с размером двоичного файла hello
.
Вторая команда запускает программу hello
в контейнере Docker, а программа hello
выводит в консоли «Hi World
».
Если мы проверим изображение hello
, мы увидим, что у него только один слой изображения. Кроме того, мы можем использовать команду docker save -o hello.tar hello
для экспорта изображения hello
в файл hello.tar
, чтобы мы могли легко просматривать файлы в изображении с помощью проводника.
Потрясающие! Это все, что у меня есть на сегодня. В этой статье мы рассмотрели концепцию образа scratch
и создали минималистичный образ Docker для приветствия. Спасибо за прочтение!