Prérequis de choix : démon Docker, rootless et surface d'attaque
Le critère principal est le modèle de confiance : Kaniko évite le socket Docker et convient aux politiques « pas de démon sur le runner » ; buildx exploite BuildKit pour le cache registry, les traces BUILDKIT_PROGRESS=plain et le multi-plateforme linux/amd64 / linux/arm64 depuis Apple Silicon. Les deux chemins exigent la même discipline sur le digest de l'image de base : un tag mobile suffit à effondrer le taux de hit du cache distant.
docker build afin que BuildKit ne multiplie pas les lectures WAN sur chaque instruction COPY.cache-repo sans préfixe logique : les collisions d'empreintes sont rares mais les races de publication peuvent corrompre vos métriques de hit ; isolez par produit.Matrice décisionnelle Kaniko vs docker buildx (cache registre)
| Critère | Kaniko (executor) | docker buildx + BuildKit | Signal de choix |
|---|---|---|---|
| Démon Docker | Non requis ; contexte dir:// ou tarball. |
Requis ; accès au socket ou remote driver. | Interdiction explicite du démon ⇒ Kaniko. |
| Cache à couches distant | --cache=true + --cache-repo dédié. |
--cache-to type=registry + --cache-from. |
Équipes déjà sur BuildKit cache manifest v2 ⇒ buildx. |
| Concurrence interne | Pipeline séquentiel classique ; parallélisme surtout au niveau registre. | BUILDKIT_MAX_PARALLELISM pilote les nœuds du graphe. |
Beaucoup de RUN indépendants ⇒ buildx mieux amorti. |
| Observabilité | Journaux Kaniko verbeux ; moins d'outils GUI. | BUILDKIT_PROGRESS=plain ; traces buildctl. |
Besoin d'exporter des traces vers votre SIEM ⇒ buildx. |
Rsync du contexte et plafond de concurrence des couches
Copiez le dépôt vers de l'APFS local par job ; refusez le build sous 25 Go libres. RSYNC_BW=20000 (kilo-octets/s) limite l'affamement du pool lorsque plusieurs équipes poussent des images en parallèle. Les options -aH --delete --numeric-ids gardent horodatages et liens durs cohérents avec ce que BuildKit hash ; évitez --inplace sur filer distant pour ne pas fragmenter les écritures observées pendant les phases COPY.
export SRC="${CI_PROJECT_DIR:-$PWD}"
export DST="${WORKSPACE:-/tmp/buildctx}/${CI_JOB_ID:?}"
mkdir -p "$DST"
rsync -aH --delete --numeric-ids --partial \
--exclude '.git/objects' \
--info=stats2,misc2 \
${RSYNC_BW:+--bwlimit=$RSYNC_BW} \
"$SRC/" "$DST/"
# Plafond BuildKit (shell du job avant buildx)
export BUILDKIT_MAX_PARALLELISM="${BUILDKIT_MAX_PARALLELISM:-4}"
Concurrence : deux buildx avec BUILDKIT_MAX_PARALLELISM=4 sur ~36 Go RAM ; Kaniko : un executor lourd ou --cache-repo par équipe.
Authentification registre, jetons et timeouts réseau
ECR : AWS_RETRY_MODE=adaptive, AWS_MAX_ATTEMPTS=10, renouvelez le jeton si le build dépasse la moitié de la TTL. GHCR : GITHUB_TOKEN avec write:packages. Lecture WAN : 120 s puis +30 s ; Kaniko --push-retry=3. Sur registre interne derrière reverse proxy, vérifiez que le Mac distant et le proxy partagent la même horloge NTP : un décalage de quelques minutes suffit à produire des 401 intermittents difficiles à distinguer d'une saturation.
# Exemple Kaniko minimal (adapter image et chemins)
/kaniko/executor \
--context "dir://${DST}" \
--dockerfile "${DST}/Dockerfile" \
--destination "${REGISTRY}/${IMAGE}:${TAG}" \
--cache=true \
--cache-repo "${REGISTRY}/${CACHE_REPO_PREFIX}/kaniko-cache" \
--compressed-caching=false \
--push-retry=3
# Exemple buildx avec cache registre
docker buildx build \
--builder "${BUILDX_BUILDER:-default}" \
--cache-to "type=registry,ref=${REGISTRY}/${CACHE_REPO_PREFIX}/buildx:cache,mode=max" \
--cache-from "type=registry,ref=${REGISTRY}/${CACHE_REPO_PREFIX}/buildx:cache" \
--push -t "${REGISTRY}/${IMAGE}:${TAG}" "${DST}"
Clés de cache CI, digest de base et backoff sur échec
Clé de cache = digest FROM + shasum Dockerfile + toolchain + région Mac. Backoff : max 4 tentatives, 2 · 4 · 8 s ; 429 ⇒ Retry-After d'abord. Pas de retry sur mismatch digest. Dans GitLab CI ou GitHub Actions, encodez ces composants dans le nom du cache distant ou dans une variable CI_CACHE_KEY versionnée pour que la promotion d'une branche release ne vide pas le cache de la branche principale par simple collision de préfixe.
Cinq étapes pour stabiliser vos builds transfrontaliers
1 Mesurer latence Mac→registre. 2 rsync scripté, échec si code ≠ 0. 3 Cache-repo par produit, pas de latest sur le cache. 4 Plafonds concurrence + métriques disque une semaine. 5 Alerte si hit rate −15 pts vs médiane.
FAQ
compressed-caching ? Souvent désactivé sur NVMe rapide pour libérer du CPU ; sur SSD modeste mesurez avant de trancher. NFS comme contexte ? Préférez rsync local si les métadonnées dépassent quinze millisecondes au p90. Builder buildx personnalisé ? Utile surtout pour pinner une version BuildKit différente de Docker Desktop. TLS intermédiaire ? Comparez la chaîne présentée par le registre avec celle attendue par le proxy sortant du Mac distant et archivez la rotation dans le runbook réseau.