Kaniko для сборки Docker-образов в Kubernetes: настройка и безопасность

Сборка Docker-образов в Kubernetes через Docker-in-Docker открывает доступ к хостовой системе, что создаёт серьёзные риски безопасности. Мы используем Kaniko — инструмент, который собирает образы без Docker daemon, полностью в userspace. Наша команда настраивает Kaniko под ключ, обеспечивая изоляцию, скорость и последующую поддержку.
Часто задаваемые вопросы

Запускать 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

  1. Подготовьте Secret с credentials. Создайте Kubernetes Secret типа docker-registry или соберите config.json с авторизацией к вашему registry.
  2. Определите образ Kaniko в CI. Используйте gcr.io/kaniko-project/executor:v1.23.0-debug и передайте ему необходимые аргументы.
  3. Включите кеширование. Добавьте флаги --cache=true и --cache-repo для ускорения повторных сборок.
  4. Запустите сборку. 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 и получить индивидуальный план миграции.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142