Как создать минималистичный 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 для приветствия. Спасибо за прочтение!