Только представьте, что у вас есть рабочий образ Docker с реальным размером базового образа всего ~ 30 КБ, так что у вас почти не будет никаких накладных расходов. Давайте сделаем это в этой статье.

Как далеко мы можем зайти?

Таким образом, вы можете спросить, действительно ли возможно запустить ваше приложение на базовом образе 30 КБ. Короче говоря: «Да, это так!», Хотя, конечно, есть и недостаток.

Итак, давайте сначала проверим некоторые окончательные результаты. На следующем изображении вы можете увидеть три разных образа Docker. Все три изображения содержат одно и то же работающее приложение Go, простую программу Hello-World, ничего особенного.

  • pz/my-go-app-full - golang:1.15 использовался как базовый образ → Вся среда выполнения Go + двоичные файлы, конечно, полный перебор. Здесь уже лучше было бы использовать альпийский или тонкий вариант. Мы не тестировали его в этом конкретном случае, но он должен уменьшить размер примерно на 90% или около того.
  • pz/my-go-app-alpine - alpine:3.13.1 был использован в качестве базового образа → Супер маленький дистрибутив Linux, содержащий только самое важное. Никакой дополнительной среды выполнения Go здесь нет, просто Linux.
  • pz/my-go-app-scratch - scratch использовался в качестве базового образа → На самом деле это не совсем базовый образ, но мы говорим Docker, что действительно хотим начать с истинного нуля. Подробнее о scratch позже в этой статье.

На следующем изображении вы можете увидеть файлы из корневой папки, в которые были встроены образы Docker. Как вы можете видеть, наше app, приложение Go, которое мы запускаем через образы Docker, имеет размер около 2 МБ. Поскольку размер нашего изображения, созданного с нуля, составляет всего 2,03 МБ, мы можем оценить накладные расходы примерно в 30 КБ для образа Docker по сравнению с реальным приложением. Довольно круто, правда?

Изображение `царапины '

«Можем ли мы использовать FROM scratch для всех видов приложений / языков?»

Теоретически да, практически никогда не должны. 😉

Но давайте начнем с того, о чем scratch изображение. Прежде всего, согласно описанию на Docker Hub, это образ, который наиболее полезен в контексте создания базовых образов или суперминимальных образов, содержащих только отдельные двоичные файлы.

Кроме того, начиная с Docker 1.5.0, команда FROM scratch не используется в Dockerfile и, как таковая, не создает дополнительный слой в образе. Несмотря на то, что образ scratch доступен в реестре Docker, его нельзя извлечь или запустить, и на него можно ссылаться только в Dockerfile.

«Хорошо, хорошо, я понял. Но могу ли я теперь запустить с ним свое приложение Node.Js / Python / любое другое? »

Длинный ответ: только если вы установите на нем Node.js / Python / что-то еще 😐

Довольно неудовлетворительно, правда? Верно, но на то есть причина. Как упоминалось ранее, изображение scratch на самом деле означает создание с нуля. Так что там уже абсолютно ничего нет. Ни оболочек, ни библиотек, ни системных файлов, ничего.

Поскольку scratch образ на самом деле ничего не содержит, вы также не сможете открыть bash в контейнере с помощью обычного docker exec -it CONTAINER /bin/bash. Так что во многих случаях изображение alpine, которое включает как минимум оболочку, может стоить дополнительных 5,5 МБ. 😉

Кроме того, такие языки, как JavaScript (Node.js) и Python, являются языками-интерпретаторами, которые предварительно не собираются в двоичные файлы, поэтому их невозможно запустить на scratch изображении. В случае JavaScript вам сначала нужно будет установить там Node.js, чтобы ваш код можно было интерпретировать во время выполнения. В случае с Node.js я хотел бы сослаться на другую мою статью Уменьшение размера образа Docker для Node.js на 90%!.



Фактический файл Dockerfile

«Хорошо, я понял, использование« царапины »создает супероптимизированный образ Docker, и решение использовать его должно быть осознанным ... Но я хочу его использовать, поэтому, пожалуйста, покажите мне код!»

Раз уж вы спросили, поехали. Отдельные шаги описаны непосредственно в Dockerfile:

Теперь давайте создадим и запустим этот Dockerfile. Имейте в виду, что требуется образец Go-приложения, использующего app.go в качестве точки входа. В качестве альтернативы вы можете проверить мой пример репозитория, содержащий приложение Go «Hello World» и указанное выше Dockerfile:



### Run into root application folder
# Build application in current directory
$ docker build -t pz/my-go-app-scratch . 
# Run built container once.
# '--rm' indicates that the container should be removed aber run
$ docker run --rm pz/my-go-app-scratch

Заключительные слова

Я надеюсь, что смогу дать вам небольшой рецепт, как докеризовать ваше приложение Go, а также дать несколько советов по оптимизации его размера. Имейте в виду, что начало с scratch может иметь свои подводные камни, и я обычно рекомендую использовать alpine в качестве базового образа, поскольку накладные расходы очень малы, и у вас есть, по крайней мере, возможность exec в ваш работающий контейнер.

Спасибо, что нашли время прочитать мою статью.

Если у вас есть какие-либо вопросы или дополнения, не стесняйтесь использовать раздел комментариев или напишите мне в LinkedIn или Twitter, чтобы связаться со мной 😊