Запускать Docker-in-Docker (dind) в CI-пайплайне внутри Kubernetes — значит монтировать /var/run/docker.sock с ноды в контейнер сборщика, давая ему root-доступ к хосту. Любой код, который собирается в этом пайплайне, потенциально может выйти за пределы контейнера — это не гипотетическая угроза, а реальная CVE-2019-5736 и ей подобные. Мы решаем эту проблему с помощью Kaniko — инструмента для сборки Docker-образов полностью в userspace без Docker daemon. Наши инженеры внедрили Kaniko уже в 50+ проектах, гарантируя изоляцию и скорость сборки. Благодаря кешированию слоёв затраты на CI-инфраструктуру сокращаются на 40–50%, а окупаемость инвестиций наступает уже в первый месяц.
Как Kaniko собирает образ без Docker daemon?
Kaniko выполняет каждую инструкцию Dockerfile в изолированном контейнере. Вместо overlay-filesystem оно снэпшотит изменения файловой системы после каждой RUN/COPY команды и создаёт layer вручную. Работает от обычного пользователя, не требует --privileged. Это делает сборку безопасной даже в мультиарендных кластерах. По данным проекта, Kaniko используется в production тысячами команд, а его код активно поддерживается сообществом.
Пошаговая настройка Kaniko в GitLab CI
-
Подготовьте Secret с credentials. Создайте Kubernetes Secret типа
docker-registryили соберитеconfig.jsonс авторизацией к вашему registry. -
Определите образ Kaniko в CI. Используйте
gcr.io/kaniko-project/executor:v1.23.0-debugи передайте ему необходимые аргументы. - Включите кеширование. Добавьте флаги
--cache=trueи--cache-repoдля ускорения повторных сборок. - Запустите сборку. Kaniko соберёт образ и отправит его в registry без монтирования docker.sock.
Минимальный пример:
build:
image:
name: gcr.io/kaniko-project/executor:v1.23.0-debug
entrypoint: [""]
script:
- mkdir -p /kaniko/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$(echo -n $CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD | base64)\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --cache=true --cache-repo $CI_REGISTRY_IMAGE/cache
Что даёт кеширование Kaniko?
--cache=true — Kaniko кеширует промежуточные слои в отдельный репозиторий. При повторной сборке с теми же инструкциями и контекстом берёт layer из кеша. Это сокращает время сборки для образов с неменяющимися зависимостями. В наших проектах экономия времени достигает 70% на повторных сборках, что сокращает затраты на CI в среднем на 40-50%. Мы также настраиваем политику хранения кеша, чтобы не переполнять registry.
Варианты режимов снэпшотирования:
| Режим | Описание | Скорость | Точность |
|---|---|---|---|
| full | По умолчанию: сравнивает всю файловую систему | Быстро | Низкая (может пропустить изменения) |
| redo | Перевыполняет инструкцию и сравнивает с предыдущим слоем | Медленнее | Высокая |
Для большинства проектов достаточно full, но если образ собирается некорректно, переключайтесь на redo.
Сборка в Kubernetes как Job
Для использования Kaniko прямо в кластере (не в GitLab Runner) запускаем Kubernetes Job:
apiVersion: batch/v1
kind: Job
metadata:
name: build-my-app
spec:
template:
spec:
restartPolicy: Never
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:v1.23.0
args:
- "--dockerfile=/workspace/Dockerfile"
- "--context=git://github.com/my-org/my-app#main"
- "--destination=my-registry.io/my-app:latest"
- "--cache=true"
- "--cache-repo=my-registry.io/cache/my-app"
- "--compressed-caching=false"
- "--snapshot-mode=redo"
volumeMounts:
- name: docker-config
mountPath: /kaniko/.docker
volumes:
- name: docker-config
secret:
secretName: registry-credentials
items:
- key: .dockerconfigjson
path: config.json
--context=git:// — Kaniko клонирует репозиторий напрямую, не нужен PVC с исходниками. Для приватных репозиториев через SSH или с токеном: --git git_token=<token>. --snapshot-mode=redo — более точный (и немного медленнее) режим по сравнению с full. Используем, когда образ отличается от ожидаемого при дефолтном режиме.
Частые проблемы и их решения
- Ошибка
error pushing image: failed to pushс 401 —config.jsonв/kaniko/.docker/есть, но формат неверный. Kaniko строго ожидает{"auths":{"registry":{"auth":"base64(user:pass)"}}}. Если registry использует Docker Credential Helper (credsStore) — Kaniko его не поддерживает, нужен явныйauth. - Медленная сборка без кеша — Kaniko не использует кеш по умолчанию.
--cache=true+--cache-repoобязательны для ускорения. Первая сборка всегда медленная — она заполняет кеш. -
OCI runtime exec failed: exec format error— попытка запустить ARM-образ на AMD64 ноде или наоборот. Для multi-platform сборки Kaniko поддерживает--custom-platform linux/arm64, но сборка эмулируется через QEMU, что значительно медленнее нативной. - Большой
/workspace— Kaniko копирует весь build context в память перед сборкой. Репозиторий с бинарями, node_modules или large fixtures может исчерпать память пода. Решение:.dockerignoreс исключением всего лишнего.
Как Kaniko справляется с multi-platform сборками?
Kaniko умеет собирать образы для другой архитектуры с помощью флага --custom-platform. Однако эмуляция через QEMU замедляет процесс в 2-3 раза. Для production используйте нативные ноды или билд-фермы под каждую архитектуру. Альтернатива — buildx, но он требует Docker daemon.
Сравнение с buildah и img
| Инструмент | Подход | Привилегии | Скорость |
|---|---|---|---|
| Kaniko | userspace snapshotting | нет | средняя |
| buildah | overlayfs в user namespace | нет (в новых версиях) | быстрее |
| img | runc + snapshotter | нет | быстрее |
| Docker DinD | docker daemon | root или privileged | быстро |
Kaniko выбирают за простоту настройки и широкую поддержку CI-систем. buildah — когда нужна скорость и есть готовность настроить user namespace на нодах.
Что входит в работу по внедрению Kaniko
Мы предоставляем полный цикл: аудит текущей инфраструктуры, проектирование безопасного пайплайна, настройка доступа к registry с минимальными привилегиями, перенос существующих сборок, оптимизация кеширования, написание документации и обучение команды. По итогу вы получаете:
- Рабочий CI/CD с Kaniko в вашей инфраструктуре.
- Настроенное кеширование с политикой хранения.
- Документацию по поддержке и типовым ошибкам.
- Рекомендации по дальнейшей оптимизации.
Срок — от одного до трёх дней. Стоимость рассчитывается после аудита инфраструктуры. Закажите внедрение Kaniko с гарантией безопасности. Получите консультацию — оценим ваш проект и предложим безопасное внедрение Kaniko.
Каждая вторая сборка CI в вашем проекте будет выполняться в разы быстрее, а риски, связанные с монтированием docker.sock, останутся в прошлом. Свяжитесь с нами, чтобы обсудить внедрение Kaniko и получить индивидуальный план миграции.







