Мы любим контейнеры и каждый день используем эту технологию. Тем не менее, контейнеры не идеальны. Однако за последние несколько месяцев появился ряд проектов, которые затрагивают некоторые из проблем, которые мы испытали.
Мы начали использовать контейнеры с Docker, так как этот проект сделал эту технологию настолько популярной. Помимо использования контейнера, мы узнали, как использовать docker-compose и начали управлять своими проектами. Наша производительность взлетела!
Через некоторое время мы начали замечать проблемы. Наиболее очевидные из них связаны с процессом создания образов контейнеров. Инструмент Docker использует пользовательский формат файла в качестве рецепта для создания образов контейнеров – Dockerfiles. Этот формат прост в освоении, и через короткое время вы готовы самостоятельно создавать изображения контейнеров. Проблемы возникают, если вы хотите овладеть лучшими навыками или иметь сложные сценарии.
Давайте сделаем перерыв и отправимся в другую страну: мир Ansible. Вы знаете что это? Это здорово, правда? У вас нет? Ну, пришло время узнать что-то новое. Ansible – это проект, который позволяет вам управлять своей инфраструктурой, записывая задачи и выполняя их в выбранными вами средах. Не нужно устанавливать и настраивать какие-либо службы; все может легко работать с вашего ноутбука. Многие люди уже обнимают Ansible.
Представьте себе этот сценарий: вы вложили капитал в Ansible, вы написали много невероятных ролей и схем, которые вы используете для управления своей инфраструктурой, и вы думаете об инвестировании в контейнеры. Что вы должны сделать? Начать писать определения образов контейнера с помощью сценариев оболочки и Dockerfiles? Это звучит не так.
Некоторые люди из команды разработчиков Ansible задали этот вопрос и поняли, что те же самые роли и схемы, которые люди пишут и используют ежедневно, также могут использоваться для создания образов контейнеров. Но не только это – они могут использоваться для управления полным жизненным циклом контейнерных проектов. Из этих идей родился проект Ansible Container. Он использует существующие роли Ansible, которые могут быть превращены в образы контейнеров и могут даже использоваться для полного жизненного цикла приложения, от сборки до развертывания на производстве.
Давайте поговорим о проблемах, которые мы упомянули в отношении лучших практик в контексте Dockerfiles. Предупреждение: это будет очень конкретным и техническим. Вот три главных вопроса, которые у нас есть:
При написании Dockerfiles вы можете указать скрипт, который будет интерпретироваться через /bin/sh -c . Это может быть что-то вроде этого:
RUN dnf install -y nginx
где RUN – это команда Dockerfile, а остальные – ее аргументы (которые передаются оболочке). Но представьте себе более сложный сценарий:
RUN set -eux; \ \ this "case" statement is generated via "update.sh" %%ARCH-CASE%%; \ \ url="https://golang.org/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \ wget -O go.tgz "$url"; \ echo "${goRelSha256} *go.tgz" | sha256sum -c -; \
Это взято из официального изображения golang. Это не выглядит красиво, не так ли?
Dockerfiles – новый формат без формальной спецификации. Это сложно, если вам нужно обработать Dockerfiles в вашей инфраструктуре (например, немного автоматизировать процесс сборки). Единственная спецификация – это код, который является частью dockerd. Проблема в том, что вы не можете использовать его в качестве библиотеки. Самое простое решение – написать парсер самостоятельно и надеяться на лучшее. Не лучше ли использовать какой-нибудь известный язык разметки, такой как YAML или JSON?
Если вы знакомы с внутренними изображениями контейнеров, вы можете знать, что каждое изображение состоит из слоев. После создания контейнера слои укладываются друг на друга (например, как блины), используя технологию файловой системы union. Проблема в том, что вы не можете явно контролировать это расслоение – вы не можете сказать: «Здесь начинается новый слой». Вы вынуждены изменить свой файл Docker таким образом, чтобы ухудшить читаемость. Большая проблема заключается в том, что для достижения оптимальных результатов необходимо использовать набор лучших практик – новичкам здесь очень тяжело.
Самым большим недостатком Dockerfiles по сравнению с Ansible является то, что Ansible, как язык, намного более мощный. Например, Dockerfiles не имеет прямого представления о переменных, тогда как Ansible имеет полную систему шаблонов (переменные являются лишь одной из его функций). Ansible содержит большое количество модулей, которые могут быть легко использованы, например wait_for, которые могут использоваться для проверки готовности к сервису, например, дождаться готовности службы до продолжения. С Dockerfiles все это сценарий оболочки. Поэтому, если вам нужно выяснить готовность к работе, это нужно сделать с помощью оболочки (или устанавливать отдельно). Другая проблема со сценариями оболочки заключается в том, что с растущей сложностью обслуживание становится обременительно. Множество людей уже поняли это и превратили эти сценарии в Ansible.
Извините, но перевод подстрочником абсолютно нечитаем:(