Kaniko est un outil de build d’images OCI (Docker) qui fonctionne entièrement en userspace, sans daemon Docker. Conçu par Google puis repris par la communauté open source, il résout les problèmes de sécurité liés au Docker-in-Docker (DinD) en permettant de construire des images directement dans des conteneurs standard, sans privilèges root. C’est la solution de référence pour les builds dans Kubernetes Pods et les pipelines CI/CD sécurisés (GitLab CI, GitHub Actions, Tekton).
Cas d’usage principal : Vous avez besoin de construire des images dans Kubernetes ou GitLab CI, mais vous ne pouvez pas (ou ne voulez pas) exposer le socket Docker ou utiliser le mode privileged. Kaniko s’exécute comme un simple conteneur, lit votre Dockerfile, build les layers OCI, et push directement vers un registry — tout cela sans daemon.
Pourquoi Kaniko (vs Docker build)
Section intitulée « Pourquoi Kaniko (vs Docker build) »Docker build classique nécessite un daemon Docker qui s’exécute avec des privilèges root et expose un socket Unix (/var/run/docker.sock). Dans Kubernetes ou en CI/CD, cette architecture pose des problèmes critiques de sécurité et de complexité.
Comparaison Docker build vs Kaniko
Section intitulée « Comparaison Docker build vs Kaniko »| Critère | Docker build | Kaniko |
|---|---|---|
| Daemon requis | ✅ Oui (dockerd) | ❌ Non (userspace pur) |
| Privilèges root | ✅ Requis | ❌ Utilisateur standard |
| Socket Docker | ✅ /var/run/docker.sock | ❌ Aucun socket |
| Kubernetes | ❌ DinD complexe (privileged) | ✅ Pod standard non-root |
| Sécurité | ⚠️ Risque escalade privilèges | ✅ Isolation complète |
| CI/CD | ⚠️ Docker-in-Docker (nested) | ✅ Conteneur simple |
| Performance | 🚀 Très rapide (cache daemon) | 🏃 Rapide (cache registry) |
| Compatibilité Dockerfile | ✅ 100% | ✅ ~95% (limitations mineures) |
Cas d’usage recommandés
Section intitulée « Cas d’usage recommandés »Kaniko excelle dans les environnements où la sécurité et l’absence de daemon sont critiques, tandis que Docker build reste pertinent pour le développement local avec infrastructure Docker existante.
| Situation | Outil recommandé | Raison |
|---|---|---|
| Build dans Kubernetes Pod | Kaniko | Pas de daemon, pas de privileged |
| Pipeline GitLab CI / GitHub Actions | Kaniko | Conteneur simple, sécurisé |
| Build Tekton / Argo Workflows | Kaniko | Natif Kubernetes |
| Développement local (Docker installé) | Docker build | Plus rapide, cache local |
| Multi-platform builds complexes | Docker buildx | Support ARM64 + cache avancé |
| Environnement sans Docker disponible | Kaniko | Fonctionne partout (userspace) |
Installation et premiers builds
Section intitulée « Installation et premiers builds »Kaniko ne s’installe pas comme un outil CLI classique : il s’exécute toujours en tant que conteneur. Vous lancez l’image gcr.io/kaniko-project/executor:v1.26.4, montez votre code source et Dockerfile, et Kaniko build + push l’image.
Build local avec Docker (test rapide)
Section intitulée « Build local avec Docker (test rapide) »-
Créer un Dockerfile de test
Fenêtre de terminal mkdir -p /tmp/kaniko-test && cd /tmp/kaniko-testcat <<'EOF' > DockerfileFROM alpine:3.21RUN apk add --no-cache curlCMD ["/bin/sh"]EOF -
Lancer Kaniko executor en conteneur
Cette commande monte le répertoire courant dans le conteneur, build l’image, mais ne la push pas (
--no-push).Fenêtre de terminal docker run --rm \-v "$PWD":/workspace \martizih/kaniko:v1.26.4 \--context=/workspace \--dockerfile=/workspace/Dockerfile \--destination=test-kaniko:1.0.0 \--no-pushComprendre les options de la commande : Kaniko executor accepte plusieurs paramètres critiques qui déterminent où trouver le code source, quel Dockerfile utiliser, et où pousser l’image finale. Voici les options essentielles à maîtriser :
--context: Répertoire contenant le Dockerfile et le build context--dockerfile: Chemin vers le Dockerfile (si différent deDockerfile)--destination: Tag de l’image finale (formatregistry/image:tag)--no-push: Empêche le push vers le registry (utile pour tester)
-
Vérifier le build réussi
Kaniko affiche les logs de build (layers, étapes FROM/RUN/CMD). Sortie attendue :
INFO[0002] Retrieving image manifest alpine:3.21INFO[0002] Retrieving image alpine:3.21 from registry index.docker.ioINFO[0003] Built cross stage deps: map[]INFO[0003] Retrieving image manifest alpine:3.21INFO[0003] FROM alpine:3.21INFO[0003] Unpacking rootfs as cmd RUN apk add --no-cache curl requires it.INFO[0003] RUN apk add --no-cache curlINFO[0003] Taking snapshot of full filesystem...INFO[0003] CMD ["/bin/sh"]INFO[0003] Skipping push to container registry due to --no-push flagL’image est construite mais non persistée (car Kaniko s’exécute dans un conteneur isolé). Contrairement à Docker build qui stocke l’image dans le daemon local, Kaniko build l’image en mémoire puis la détruit. Pour la récupérer et l’utiliser, vous avez deux options principales :
- Push vers un registry :
--destination ghcr.io/user/test-kaniko:1.0.0(sans--no-push) — l’image devient accessible à tous vos environnements - Export en tar local :
--tarPath /output/image.tar(voir section Gestion des images) — utile pour charger l’image avecdocker load
- Push vers un registry :
Build avec Podman (alternative rootless)
Section intitulée « Build avec Podman (alternative rootless) »Si vous utilisez Podman au lieu de Docker :
podman run --rm \ -v "$PWD":/workspace:Z \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --dockerfile=/workspace/Dockerfile \ --destination=test-kaniko:1.0.0 \ --no-pushL’option :Z applique le contexte SELinux correct pour le volume monté.
Authentification et push vers un registry
Section intitulée « Authentification et push vers un registry »Pour pousser des images vers un registry privé (GHCR, Harbor, GCR, ECR), Kaniko a besoin d’accéder au fichier de credentials Docker standard (~/.docker/config.json).
Créer le fichier config.json
Section intitulée « Créer le fichier config.json »-
Créer un Personal Access Token GitHub
Allez dans Settings → Developer settings → Personal access tokens → Generate new token (classic).
Permissions nécessaires : Pour que Kaniko puisse pousser des images vers GitHub Container Registry (GHCR), votre token GitHub doit avoir les scopes suivants :
write:packages: Permet de pousser de nouvelles imagesread:packages: Permet de lire/télécharger des images existantesdelete:packages: Permet de supprimer des versions d’images (optionnel, mais recommandé pour le nettoyage)
-
Login Docker pour générer config.json
Fenêtre de terminal echo "$GITHUB_TOKEN" | docker login ghcr.io -u USERNAME --password-stdinCela crée/met à jour
~/.docker/config.jsonavec les credentials encodés. -
Monter config.json dans Kaniko
Fenêtre de terminal docker run --rm \-v "$PWD":/workspace \-v ~/.docker/config.json:/kaniko/.docker/config.json:ro \martizih/kaniko:v1.26.4 \--context=/workspace \--dockerfile=/workspace/Dockerfile \--destination=ghcr.io/USERNAME/test-kaniko:1.0.0L’image est buildée et poussée automatiquement vers GHCR.
# Loginecho "$DOCKERHUB_TOKEN" | docker login -u USERNAME --password-stdin
# Build + Push avec Kanikodocker run --rm \ -v "$PWD":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=USERNAME/test-kaniko:1.0.0# Login Harborecho "$HARBOR_PASSWORD" | docker login harbor.example.com -u admin --password-stdin
# Build + Pushdocker run --rm \ -v "$PWD":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=harbor.example.com/library/test-kaniko:1.0.0Authentification avec variables d’environnement
Section intitulée « Authentification avec variables d’environnement »Alternative au fichier config.json : passer directement les credentials via variables d’environnement.
docker run --rm \ -v "$PWD":/workspace \ -e REGISTRY_USERNAME=myuser \ -e REGISTRY_PASSWORD=mytoken \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=ghcr.io/myuser/test-kaniko:1.0.0Intégration CI/CD
Section intitulée « Intégration CI/CD »Kaniko est conçu pour les pipelines CI/CD modernes. Voici des exemples production-ready pour GitLab CI, GitHub Actions et Tekton.
GitLab CI
Section intitulée « GitLab CI »Créez .gitlab-ci.yml à la racine de votre projet :
stages: - build
build-image: stage: build image: name: martizih/kaniko:v1.26.4-debug entrypoint: [""]
before_script: # Créer config.json pour authentification registry - mkdir -p /kaniko/.docker - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
script: - /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}" --cache=true --cache-repo="${CI_REGISTRY_IMAGE}/cache"
only: - main - tagsComprendre la configuration GitLab CI : Cette configuration exploite les variables CI/CD intégrées de GitLab pour authentifier automatiquement Kaniko auprès du Container Registry. Voici les éléments critiques à comprendre :
image.entrypoint: [""]: Nécessaire pour permettre à GitLab CI d’exécuter des commandes custom (sinon Kaniko démarre automatiquement)- Variables CI/CD intégrées :
$CI_REGISTRY,$CI_REGISTRY_USER,$CI_REGISTRY_PASSWORD— GitLab les fournit automatiquement, pas besoin de les configurer --cache=true+--cache-repo: Active le cache pour accélérer les builds suivants (jusqu’à 70% de gain de temps)- Tag avec commit SHA :
${CI_COMMIT_SHORT_SHA}garantit l’unicité et la traçabilité de chaque image
Vérifier le build : Allez dans Build → Container Registry, votre image doit apparaître.
GitHub Actions
Section intitulée « GitHub Actions »Créez .github/workflows/build.yml :
name: Build and Push Image
on: push: branches: [main] tags: ['v*']
env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }}
jobs: build: runs-on: ubuntu-latest permissions: contents: read packages: write
steps: - name: Checkout code uses: actions/checkout@v4.2.2
- name: Login to GHCR uses: docker/login-action@v3.3.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata id: meta uses: docker/metadata-action@v5.5.1 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha,prefix={{branch}}-
- name: Build and push with Kaniko uses: int128/kaniko-action@v1.47.0 with: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache: true cache-repository: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/cache kaniko-args: | --snapshot-mode=redo --use-new-runComprendre le workflow GitHub Actions : Cette configuration utilise des actions communautaires pour simplifier le build et automatiser le tagging des images. GitHub fournit automatiquement un token d’authentification temporaire, ce qui évite de gérer manuellement les secrets. Voici les composants principaux :
- Action
int128/kaniko-action: Wrapper qui simplifie l’utilisation de Kaniko (gère le montage des volumes, la config Docker, etc.) docker/metadata-action: Génère automatiquement les tags selon les conventions (semver pour les releases, SHA pour les commits, branch name pour les PR)secrets.GITHUB_TOKEN: Token automatique avec permissionspackages: write— GitHub le fournit à chaque workflow, durée de vie 1h--snapshot-mode=redo: Améliore la performance du cache en comparant uniquement les fichiers modifiés (vsfullqui scanne tout)--use-new-run: Utilise l’exécution optimisée des commandes RUN (meilleure gestion des permissions et performance)
Alternative sans action (exécution directe) :
- name: Build with Kaniko executor run: | docker run --rm \ -v "${{ github.workspace }}":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --dockerfile=/workspace/Dockerfile \ --destination=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} \ --cache=true \ --cache-repo=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/cacheTekton (Kubernetes natif)
Section intitulée « Tekton (Kubernetes natif) »Tekton est un framework CI/CD natif Kubernetes. Voici une Task Tekton pour builder avec Kaniko :
apiVersion: tekton.dev/v1kind: Taskmetadata: name: kaniko-buildspec: params: - name: IMAGE description: Name (reference) of the image to build - name: DOCKERFILE description: Path to the Dockerfile to build default: ./Dockerfile - name: CONTEXT description: The build context used by Kaniko default: ./
workspaces: - name: source description: Holds the code to build - name: dockerconfig description: Docker config.json for registry auth
steps: - name: build-and-push image: martizih/kaniko:v1.26.4 env: - name: DOCKER_CONFIG value: /kaniko/.docker command: - /kaniko/executor args: - --dockerfile=$(params.DOCKERFILE) - --context=$(workspaces.source.path)/$(params.CONTEXT) - --destination=$(params.IMAGE) - --cache=true - --cache-repo=$(params.IMAGE)/cache - --snapshot-mode=redo volumeMounts: - name: $(workspaces.dockerconfig.volume) mountPath: /kaniko/.dockerUtilisation dans un Pipeline :
apiVersion: tekton.dev/v1kind: Pipelinemetadata: name: build-appspec: params: - name: image-name type: string default: ghcr.io/myorg/myapp
workspaces: - name: shared-workspace - name: docker-credentials
tasks: - name: fetch-repository taskRef: name: git-clone workspaces: - name: output workspace: shared-workspace params: - name: url value: https://github.com/myorg/myapp.git
- name: build-image taskRef: name: kaniko-build runAfter: - fetch-repository workspaces: - name: source workspace: shared-workspace - name: dockerconfig workspace: docker-credentials params: - name: IMAGE value: $(params.image-name):$(tasks.fetch-repository.results.commit)Créer le Secret Kubernetes pour l’authentification :
kubectl create secret docker-registry regcred \ --docker-server=ghcr.io \ --docker-username=USERNAME \ --docker-password=TOKEN \ --namespace=tekton-pipelinesKubernetes : Build natif dans des Pods
Section intitulée « Kubernetes : Build natif dans des Pods »Kaniko brille dans Kubernetes car il ne nécessite aucun privilège spécial, contrairement au Docker-in-Docker qui demande privileged: true ou le montage du socket Docker.
Pod Kubernetes simple
Section intitulée « Pod Kubernetes simple »Créez un Pod qui build et push une image :
apiVersion: v1kind: Podmetadata: name: kaniko-builder namespace: ci-cdspec: restartPolicy: Never
initContainers: # Clone du code source depuis Git - name: git-clone image: alpine/git:2.45.2 command: - git - clone - --depth=1 - --branch=main - https://github.com/myorg/myapp.git - /workspace volumeMounts: - name: workspace mountPath: /workspace
containers: - name: kaniko-executor image: martizih/kaniko:v1.26.4 args: - --context=/workspace - --dockerfile=/workspace/Dockerfile - --destination=ghcr.io/myorg/myapp:$(date +%Y%m%d-%H%M%S) - --cache=true - --cache-repo=ghcr.io/myorg/myapp/cache - --snapshot-mode=redo - --use-new-run volumeMounts: - name: workspace mountPath: /workspace - name: docker-config mountPath: /kaniko/.docker/
# Kaniko s'exécute en tant qu'utilisateur non-root (UID 1000) securityContext: runAsUser: 1000 runAsNonRoot: true allowPrivilegeEscalation: false
volumes: - name: workspace emptyDir: {}
- name: docker-config secret: secretName: regcred items: - key: .dockerconfigjson path: config.jsonCréer le Secret pour le registry :
kubectl create secret docker-registry regcred \ --docker-server=ghcr.io \ --docker-username=myuser \ --docker-password=ghp_xxxxxxxxxxxxx \ --namespace=ci-cdLancer le build :
kubectl apply -f kaniko-pod.yaml -n ci-cd
# Suivre les logs en temps réelkubectl logs -f kaniko-builder -c kaniko-executor -n ci-cdVérifier le succès : À la fin des logs, vous devez voir Pushing image to ghcr.io/myorg/myapp:<tag> suivi de Pushed.
CronJob : Builds automatiques périodiques
Section intitulée « CronJob : Builds automatiques périodiques »Pour rebuilder automatiquement des images (ex: images de base mise à jour toutes les nuits) :
apiVersion: batch/v1kind: CronJobmetadata: name: nightly-rebuild namespace: ci-cdspec: schedule: "0 2 * * *" # Tous les jours à 2h du matin jobTemplate: spec: template: spec: restartPolicy: OnFailure
initContainers: - name: git-clone image: alpine/git:2.45.2 command: - git - clone - --depth=1 - https://github.com/myorg/myapp.git - /workspace volumeMounts: - name: workspace mountPath: /workspace
containers: - name: kaniko image: martizih/kaniko:v1.26.4 args: - --context=/workspace - --destination=ghcr.io/myorg/myapp:nightly-$(date +%Y%m%d) - --cache=true - --cache-repo=ghcr.io/myorg/myapp/cache volumeMounts: - name: workspace mountPath: /workspace - name: docker-config mountPath: /kaniko/.docker/
volumes: - name: workspace emptyDir: {} - name: docker-config secret: secretName: regcred items: - key: .dockerconfigjson path: config.jsonOptions avancées
Section intitulée « Options avancées »Kaniko offre de nombreuses options pour optimiser les builds, gérer le cache et résoudre des cas d’usage spécifiques.
Cache de layers
Section intitulée « Cache de layers »Le cache améliore drastiquement les temps de build en réutilisant les layers inchangés entre deux builds. Kaniko stocke le cache dans un registry OCI.
Activer le cache :
docker run --rm \ -v "$PWD":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=ghcr.io/user/myapp:1.0.0 \ --cache=true \ --cache-repo=ghcr.io/user/myapp/cache \ --cache-ttl=168hParamètres de configuration du cache : Le cache Kaniko fonctionne en stockant chaque layer OCI dans un registry dédié. Au prochain build, si le Dockerfile et le contexte sont identiques pour une instruction, Kaniko télécharge le layer depuis le cache au lieu de le reconstruire. Voici les options à maîtriser :
--cache=true: Active le cache (désactivé par défaut)--cache-repo: Registry où stocker les layers cachés (doit être différent de l’image finale, utilisez un suffixe/cache)--cache-ttl: Durée de validité du cache (défaut: 2 semaines = 336h, au-delà Kaniko ignore les layers et les reconstruit)
Comment ça fonctionne : Kaniko push chaque layer dans cache-repo. Au prochain build, si le Dockerfile et le contexte sont identiques pour une instruction, Kaniko réutilise le layer depuis le cache au lieu de le reconstruire.
Multi-stage builds optimisés
Section intitulée « Multi-stage builds optimisés »Kaniko supporte les Dockerfile multi-stage comme Docker build. Utilisez --target pour builder une étape spécifique.
Dockerfile multi-stage :
# Étape de buildFROM golang:1.23-alpine3.21 AS builderWORKDIR /appCOPY go.mod go.sum ./RUN go mod downloadCOPY . .RUN CGO_ENABLED=0 go build -o server .
# Étape production (image minimale)FROM alpine:3.21 AS productionRUN apk add --no-cache ca-certificatesCOPY --from=builder /app/server /usr/local/bin/CMD ["server"]
# Étape debug (avec shell pour troubleshooting)FROM production AS debugRUN apk add --no-cache bash curlBuilder l’étape production :
docker run --rm \ -v "$PWD":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=ghcr.io/user/myapp:1.0.0 \ --target=productionBuilder l’étape debug :
docker run --rm \ -v "$PWD":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=ghcr.io/user/myapp:1.0.0-debug \ --target=debugBuild args et variables
Section intitulée « Build args et variables »Passez des variables dynamiques au Dockerfile avec --build-arg.
Dockerfile avec ARG :
ARG PYTHON_VERSION=3.12FROM python:${PYTHON_VERSION}-slim
ARG APP_VERSION=devLABEL version="${APP_VERSION}"
COPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt
COPY . /appWORKDIR /appCMD ["python", "app.py"]Build avec args personnalisés :
docker run --rm \ -v "$PWD":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=ghcr.io/user/myapp:2.1.0 \ --build-arg PYTHON_VERSION=3.11 \ --build-arg APP_VERSION=2.1.0Gestion des images buildées
Section intitulée « Gestion des images buildées »Par défaut, Kaniko push les images vers un registry. Pour sauvegarder localement en tar :
Exporter en tar (sans push) :
docker run --rm \ -v "$PWD":/workspace \ -v "$PWD":/output \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=myapp:1.0.0 \ --no-push \ --tarPath=/output/myapp-1.0.0.tarCela crée myapp-1.0.0.tar (environ 6-10 MB pour une image Alpine de base) que vous pouvez charger avec :
docker load < myapp-1.0.0.tar# Sortie : Loaded image: myapp:1.0.0
# Vérifier que l'image est disponibledocker images | grep myapp# myapp:1.0.0 ed5911d3a023 21.5MB 6.51MBPush vers plusieurs registries simultanément :
docker run --rm \ -v "$PWD":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=ghcr.io/user/myapp:1.0.0 \ --destination=docker.io/user/myapp:1.0.0 \ --destination=harbor.example.com/library/myapp:1.0.0Modes snapshot (optimisation performance)
Section intitulée « Modes snapshot (optimisation performance) »Le mode snapshot détermine comment Kaniko détecte les changements du filesystem entre les layers. C’est un paramètre critique qui impacte directement la performance et la fiabilité du build. Kaniko doit savoir quels fichiers ont changé entre deux instructions RUN pour créer les bons layers OCI.
Modes disponibles (par ordre de fiabilité décroissante) :
full(défaut) : Analyse complète du filesystem à chaque layer (lent mais sûr) — scanne tous les fichiers, garantit la précisionredo(recommandé production) : Compare uniquement les fichiers modifiés depuis le dernier layer — 20-40% plus rapide quefull, fiabilité ~99%time: Compare les timestamps des fichiers (très rapide mais moins fiable) — risque de manquer des changements si les timestamps ne sont pas mis à jour
Utiliser le mode redo (recommandé production) :
docker run --rm \ -v "$PWD":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ --context=/workspace \ --destination=ghcr.io/user/myapp:1.0.0 \ --snapshot-mode=redoGain de performance : Le mode redo réduit le temps de build de 20-40% sur des projets moyens/grands.
Utilisation de .dockerignore
Section intitulée « Utilisation de .dockerignore »Kaniko respecte le fichier .dockerignore pour exclure des fichiers/dossiers du build context. Placer ce fichier à la racine de votre projet permet de réduire drastiquement la taille du context envoyé à Kaniko (parfois de 500 MB à 50 MB), ce qui accélère le build de plusieurs minutes. Voici un exemple complet couvrant les cas courants :
.dockerignore :
# Fichiers de développement.git/.github/*.mdLICENSE
# Dépendances localesnode_modules/__pycache__/*.pyc.venv/
# Logs et artifacts*.log*.tmpdist/build/Cela réduit la taille du contexte envoyé à Kaniko et accélère le build.
Dépannage
Section intitulée « Dépannage »Kaniko étant un outil userspace sans daemon, les erreurs sont généralement liées aux permissions, à l’authentification registry ou aux limitations du Dockerfile.
Problèmes courants et solutions
Section intitulée « Problèmes courants et solutions »| Symptôme | Cause probable | Solution |
|---|---|---|
error pushing to registry: UNAUTHORIZED | Credentials registry invalides | Vérifier config.json, refaire docker login, vérifier les permissions du token |
error building image: error resolving dockerfile path | Context ou Dockerfile path incorrect | Vérifier --context et --dockerfile, utiliser des chemins absolus dans le conteneur |
COPY failed: stat /workspace/file: no such file or directory | Fichier manquant dans le context | Vérifier que le fichier existe, vérifier .dockerignore |
error saving layer: error uploading layer: 413 Request Entity Too Large | Layer trop volumineux (> 1GB) | Optimiser le Dockerfile (supprimer caches dans la même instruction RUN), utiliser multi-stage build |
unsupported platform: linux/arm64 | Image de base non disponible pour l’architecture | Utiliser --customPlatform ou changer l’image de base pour une variante multi-arch |
| Build très lent (> 10 min) | Cache désactivé ou mode snapshot full | Activer --cache=true, utiliser --snapshot-mode=redo |
panic: runtime error: invalid memory address | Bug Kaniko (rare) ou Dockerfile invalide | Mettre à jour vers la dernière version v1.26.x, vérifier la syntaxe Dockerfile |
Commandes de diagnostic
Section intitulée « Commandes de diagnostic »Avant de debugger un problème, collectez les informations de base pour comprendre la configuration Kaniko et l’environnement d’exécution.
# Version de Kanikodocker run --rm martizih/kaniko:v1.26.4 version# Sortie : Kaniko version : v1.26.4
# Test d'authentification registrydocker run --rm \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4 \ /kaniko/executor --help | grep "registry"
# Vérifier le contenu du contextdocker run --rm \ -v "$PWD":/workspace \ martizih/kaniko:v1.26.4-debug \ /busybox/ls -laR /workspace
# Logs verbeux (mode debug)docker run --rm \ -v "$PWD":/workspace \ -v ~/.docker/config.json:/kaniko/.docker/config.json:ro \ martizih/kaniko:v1.26.4-debug \ --context=/workspace \ --destination=ghcr.io/user/myapp:debug \ --verbosity=debug \ --log-format=textImage -debug : Contient des outils supplémentaires (shell, busybox) pour debugger interactivement :
docker run --rm -it \ -v "$PWD":/workspace \ --entrypoint=/busybox/sh \ martizih/kaniko:v1.26.4-debugErreur UNAUTHORIZED (authentification registry)
Section intitulée « Erreur UNAUTHORIZED (authentification registry) »Symptôme : error pushing image to ghcr.io/user/myapp:1.0.0: UNAUTHORIZED: authentication required
Diagnostic : Cette erreur signifie que Kaniko n’arrive pas à s’authentifier auprès du registry. Les causes possibles sont nombreuses : credentials manquants, token expiré, permissions insuffisantes, ou Secret Kubernetes mal configuré. Voici les vérifications à effectuer dans l’ordre :
-
Vérifier que
config.jsonexiste et contient les credentials :Fenêtre de terminal cat ~/.docker/config.jsonVous devez voir une entrée
authsavec votre registry. -
Tester le login manuellement :
Fenêtre de terminal docker login ghcr.io -u USERNAME -
Vérifier les permissions du token GitHub :
- Allez dans Settings → Developer settings → Personal access tokens
- Vérifiez que les scopes
write:packagesetread:packagessont activés
-
Si vous utilisez un Secret Kubernetes, vérifier qu’il est correctement monté :
Fenêtre de terminal kubectl get secret regcred -n ci-cd -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d | jq
Optimiser les builds lents
Section intitulée « Optimiser les builds lents »Si vos builds Kaniko prennent plus de 5-10 minutes alors que Docker build est rapide, plusieurs optimisations sont possibles. La cause la plus fréquente est le cache désactivé ou mal configuré, suivi d’un Dockerfile non optimisé pour le cache et d’un context trop volumineux. Voici les actions à mener dans l’ordre de priorité (du plus impactant au moins impactant) :
Checklist d’optimisation :
-
Activer le cache (gain 40-70% sur builds incrémentaux) :
Fenêtre de terminal --cache=true --cache-repo=ghcr.io/user/myapp/cache -
Utiliser le mode snapshot redo :
Fenêtre de terminal --snapshot-mode=redo -
Optimiser le Dockerfile : Réduire le nombre de layers, grouper les commandes
RUN:# ❌ Lent : 3 layersRUN apt-get updateRUN apt-get install -y curlRUN apt-get clean# ✅ Rapide : 1 layerRUN apt-get update && \apt-get install -y curl && \apt-get clean && \rm -rf /var/lib/apt/lists/* -
Vérifier la taille du context : Utiliser
.dockerignorepour exclurenode_modules/,.git/, etc. -
Utiliser des images de base Alpine : Plus légères et plus rapides à télécharger.
Bonnes pratiques
Section intitulée « Bonnes pratiques »Ces recommandations vous aideront à maximiser la sécurité, la performance et la maintenabilité de vos builds Kaniko en production.
Sécurité
Section intitulée « Sécurité »La sécurité est l’avantage principal de Kaniko par rapport au Docker-in-Docker. Suivez ces pratiques pour renforcer davantage l’isolation et limiter les risques.
-
Toujours utiliser des images versionnées
# ❌ Risqué : version flottanteimage: martizih/kaniko:debug# ✅ Production : version pinnéeimage: martizih/kaniko:v1.26.4Cela garantit des builds reproductibles et évite les surprises lors des mises à jour.
-
Configurer securityContext dans Kubernetes
securityContext:runAsUser: 1000runAsNonRoot: trueallowPrivilegeEscalation: falsecapabilities:drop:- ALLreadOnlyRootFilesystem: false # Kaniko écrit dans /kaniko et /workspace -
Stocker les credentials dans des Secrets Kubernetes
Fenêtre de terminal # Créer le secretkubectl create secret docker-registry regcred \--docker-server=ghcr.io \--docker-username=myuser \--docker-password=ghp_token \--namespace=ci-cd# Référencer dans le Podvolumes:- name: docker-configsecret:secretName: regcred -
Scanner les images après le build
Intégrez Trivy ou Grype pour détecter les vulnérabilités :
# Dans GitLab CI après le build Kanikoscan-vulnerabilities:stage: securityimage: aquasec/trivy:0.58.1script:- trivy image --severity HIGH,CRITICAL ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}allow_failure: false
Performance
Section intitulée « Performance »Les builds Kaniko peuvent être aussi rapides que Docker build avec les bonnes optimisations. Voici comment maximiser la vitesse et réduire l’utilisation des ressources.
-
Activer le cache registry
Fenêtre de terminal --cache=true \--cache-repo=ghcr.io/user/myapp/cache \--cache-ttl=336hGain mesuré : 40-70% de réduction du temps sur les builds incrémentaux.
-
Utiliser le mode snapshot optimisé
Fenêtre de terminal --snapshot-mode=redo \--use-new-run--use-new-runaméliore l’exécution des commandesRUNen utilisant un mode d’exécution optimisé. -
Paralléliser les builds multi-images
Si vous avez plusieurs images à builder (frontend, backend, worker), lancez les builds Kaniko en parallèle dans des Pods différents ou des jobs CI/CD séparés.
-
Limiter la taille du context avec .dockerignore
Un context de 500 MB vs 50 MB peut faire la différence de 2-3 minutes sur le temps de copie.
-
Utiliser des multi-stage builds
Séparez les étapes de compilation et d’exécution pour réduire la taille de l’image finale et améliorer le cache.
FROM golang:1.23-alpine AS builderWORKDIR /appCOPY go.mod go.sum ./RUN go mod download # ← Layer caché si go.mod/go.sum inchangésCOPY . .RUN go build -o server .FROM alpine:3.21COPY --from=builder /app/server /usr/local/bin/CMD ["server"]
Maintenabilité
Section intitulée « Maintenabilité »Des builds reproductibles et bien documentés facilitent le debugging, la collaboration et l’évolution du projet au fil du temps.
-
Versionner les images de base
# ❌ Non reproductibleFROM python:3-slim# ✅ ReproductibleFROM python:3.12.8-slim-bookworm -
Ajouter des labels OCI pour la traçabilité
LABEL org.opencontainers.image.source="https://github.com/myorg/myapp"LABEL org.opencontainers.image.version="1.2.0"LABEL org.opencontainers.image.created="2026-01-22T10:00:00Z"LABEL org.opencontainers.image.revision="${GIT_COMMIT}"Dans GitLab CI, passez le commit SHA dynamiquement :
script:- /kaniko/executor--context "${CI_PROJECT_DIR}"--destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}"--build-arg GIT_COMMIT="${CI_COMMIT_SHA}" -
Documenter les builds dans un README ou ADR
Expliquez pourquoi Kaniko a été choisi, quelles sont les configurations spécifiques, et comment reproduire les builds localement.
-
Centraliser la configuration dans un Makefile ou script
# MakefileIMAGE := ghcr.io/myorg/myappVERSION := $(shell git describe --tags --always).PHONY: buildbuild:docker run --rm \-v $(PWD):/workspace \-v ~/.docker/config.json:/kaniko/.docker/config.json:ro \martizih/kaniko:v1.26.4 \--context=/workspace \--destination=$(IMAGE):$(VERSION) \--cache=true \--cache-repo=$(IMAGE)/cache \--snapshot-mode=redo.PHONY: build-debugbuild-debug:docker run --rm \-v $(PWD):/workspace \martizih/kaniko:v1.26.4-debug \--context=/workspace \--destination=$(IMAGE):debug \--no-push \--verbosity=debugUsage :
make buildoumake build-debug.
À retenir
Section intitulée « À retenir »- Kaniko build des images OCI sans daemon Docker, éliminant les risques de sécurité du Docker-in-Docker
- Fork actif osscontainertools/kaniko (v1.26.4, janvier 2026) après l’archivage de GoogleContainerTools/kaniko en juin 2025
- Idéal pour Kubernetes et CI/CD (GitLab CI, GitHub Actions, Tekton) : Pods standard, pas de privilèges root
- Cache registry obligatoire pour des builds rapides :
--cache=true --cache-repo=registry/image/cache - Authentification via config.json monté en volume ou Secret Kubernetes
- Snapshot mode
redo+--use-new-runpour optimiser la performance - Multi-stage builds supportés avec
--targetpour builder des étapes spécifiques - Limitations mineures : ~5% des Dockerfiles complexes (ONBUILD, certains hérédités) non supportés
- Alternative à Buildah : Kaniko = userspace pur, Buildah = rootless natif (plus flexible mais nécessite vfs ou fuse-overlayfs)