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 або великими 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
    1543
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142