Создание образов Docker, без Docker, с использованием Kaniko + Gitlab CI и AWS
Почему Kaniko?
"Что не имеет рук, но может постучаться в вашу дверь, и вам лучше открыть, если это произойдет?" - Эдвард Нигма / Загадочник
Хотите узнать ответ? Пожалуйста, продолжайте читать эту статью, и вы узнаете далее... LOL.
Kaniko решает две проблемы, связанные с методом сборки Docker-in-Docker:
- Docker-in-Docker требует привилегированного режима для работы, что представляет собой значительную проблему с точки зрения безопасности.
- Docker-in-Docker обычно снижает производительность и может быть довольно медленным.
Прежде чем продолжить, позвольте мне рассказать вам, что такое Kaniko и как он работает.
Что такое Kaniko?
Kaniko - это инструмент для создания образов контейнеров из Dockerfile внутри контейнера или кластера Kubernetes. Kaniko не зависит от демона Docker и выполняет каждую команду в Dockerfile полностью в пользовательском пространстве. Это позволяет создавать образы контейнеров в средах, в которых нельзя легко или безопасно запустить демон Docker, таких как стандартный кластер Kubernetes.
Коротко говоря, Kaniko позволяет вам создавать и загружать образы в кластере Kubernetes без каких-либо особых привилегий или разрешений и собирать их из Dockerfile без доступа к Docker Daemon. Это фантастический инструмент, потому что теперь нам больше не нужен Docker Daemon для создания образов контейнеров.
Как работает Kaniko?
Образ-исполнитель Kaniko отвечает за создание образа из Dockerfile и его отправку в реестр. Внутри образа-исполнителя мы извлекаем файловую систему базового образа (образ, указанный в инструкции FROM в Dockerfile). Затем мы выполняем команды из Dockerfile, создавая снимки файловой системы в пользовательском пространстве после выполнения каждой команды. После каждой команды мы добавляем слой измененных файлов к базовому образу (если такие есть) и обновляем метаданные образа.
- Kaniko не поддерживает создание Windows-контейнеров.
- Запуск Kaniko в любом образе Docker, кроме официального образа Kaniko, не поддерживается (то есть это может работать нестабильно).
- Это включает в себя копирование исполняемых файлов Kaniko из официального образа в другой образ Docker.
- Kaniko не поддерживает v1 Registry API (Устаревший API реестра v1).
Вы можете узнать больше подробностей о Kaniko здесь.
Теперь, когда вы знаете, что такое Kaniko и как он работает, я покажу вам пример использования, в котором я расскажу, как его настроить с использованием Gitlab CI для создания образов Docker и их отправки в ECR (AWS Elastic Container Registry).
Пример использования
Я покажу вам сценарий, в котором мы используем:
- AWS Elastic Container Registry для хранения образов Docker,
- Gitlab CI для автоматизации процесса создания контейнерных образов,
- Gitlab Runners, запущенные внутри кластера Kubernetes (EKS),
- Инструмент Kaniko, который будет отвечать за создание Docker-образа на основе Dockerfile.
Учитывая, что мы запускаем Gitlab Runner в кластере EKS, первое, что нам нужно сделать, это повысить разрешения IAM-роли, используемой Gitlab Runner.
Если вы не знакомы с Gitlab CI или Gitlab Runners, пожалуйста, ознакомьтесь с этими подробностями:
Шаг за шагом
Пройдите пошаговую инструкцию, необходимую для настройки Kaniko для создания и загрузки образов в ECR с помощью конвейера Gitlab CI:
Шаг 1. Добавьте следующую политику ECR для каждого репозитория, в котором будут храниться образы, созданные с помощью Kaniko:
В строках 9, 10 и 11 вы можете видеть, что мы предоставляем разрешение на Push и Pull образов для трех ролей IAM, и в строках 29 и 30 мы разрешаем двум учетным записям AWS Pull образов.
Шаг 2. В этом сценарии наши Gitlab Runners используют роль IAM, позволяющую Kaniko выполнять Push в ECR без аутентификации. Поэтому нам нужно присоединить следующую политику IAM к роли IAM:
AmazonEC2ContainerRegistryPowerUser
Эта политика включает следующие разрешения:
ecr
– Позволяет принципалам читать и записывать в репозитории, а также читать политики жизненного цикла. Принципалам не предоставляется разрешение на удаление репозиториев или изменение применяемых к ним политик жизненного цикла.
В этом примере мы собираемся создать Dockerfile для установки Terraform и Terragrunt:
Шаг 4. Настройте файл Gitlab CI (.gitlab-ci
) в корневом каталоге вашего репозитория:
Учитывая, что мы собираемся создать образ с установленными Terraform и Terragrunt, вы увидите некоторые переменные, специфичные для создания этого образа, например, TF_VERSION
и TG_VERSION
.
Ключевые слова, определенные здесь в этом конвейере:
На строке 1 мы определили этапы этого конвейера. В данном случае у нас будет только этап Build.
С 5-й по 10-ю строку у нас есть следующие переменные:
CONTAINER_REGISTRY: адрес ECR в регионе, который мы используем
IMAGE_NAME: имя репозитория ECR
IMAGE_TAG: тег, который Kaniko создаст, в данном случае мы используем предопределенную переменную.
TF_VERSION: версия клиента Terraform.
TG_VERSION: версия клиента Terragrunt.
CACHE_TTL: срок действия в часах.
С 12-й по 22-ю строку мы определили шаблон (также известный как Gitlab Anchors для скриптов. Подробнее здесь.)
С 24-й по 35-ю строку у нас есть определение задачи (Job), в котором мы используем:
На строке 25 мы указали этап, к которому относится эта задача, Build.
С 27-й по 29-ю строку у нас есть раздел image, где главной строкой является 28-я строка, указывающая имя образа, который мы будем использовать для выполнения задачи. В данном случае рекомендуется использовать образ kaniko debug (gcr.io/kaniko-project/executor:debug), так как в нем есть необходимая оболочка для работы с GitLab Runner. Подробнее здесь.
На строках 30 и 31 мы определили, как извлекать образы Docker из ECR без аутентификации.
На строках 32 и 33 мы определили скрипт, который нужно выполнить в этой задаче. Вы можете видеть, что мы вызываем тот шаблон, который был определен с 12-й по 22-ю строку.
И на строках 34 и 35 мы контролируем, когда создаются задачи. В данном случае только при событиях push/merge в ветку main.
Подробнее о ключевых словах .gitlab-ci.yml можно узнать здесь.
Заключение
Kaniko - это мощный инструмент для создания образов Docker без Docker Daemon. Для тех, кто работает с Gitlab CI, плюсом является поддержка использования Kaniko. Одним из хороших аргументов в пользу использования Kaniko является кеширование:
Используя эти два аргумента, вы можете сократить время сборки, потому что Kaniko будет использовать ваш репозиторий ECR для хранения промежуточных слоев образов Docker с целью оптимизации времени сборки.
Советы
Если вы переходите с другого инструмента CI/CD, ознакомьтесь с этой документацией:
Если вы не знакомы с Gitlab CI, пожалуйста, найдите более подробную информацию здесь.