Запускати 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 або великими 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 та отримати індивідуальний план міграції.







