doc-locale/fr-fr/ci/docker/using_buildkit.md
{{< details >}}
{{< /details >}}
BuildKit est le moteur de build utilisé par Docker et fournit des builds multi-plateformes ainsi que la mise en cache des builds.
BuildKit propose les méthodes suivantes pour créer des images Docker :
| Méthode | Exigence de sécurité | Commandes | À utiliser quand vous avez besoin de |
|---|---|---|---|
| BuildKit rootless | Aucun conteneur privilégié | buildctl-daemonless.sh | Une sécurité maximale ou un remplacement de Kaniko |
| Docker Buildx | Nécessite docker:dind | docker buildx | Workflow Docker familier |
| BuildKit natif | Nécessite docker:dind | buildctl | Contrôle avancé de BuildKit |
DockerfileBuildKit en mode standalone fournit des builds d'images rootless sans dépendance au démon Docker. Cette méthode élimine entièrement les conteneurs privilégiés et constitue un remplacement direct pour les builds Kaniko.
Différences clés par rapport aux autres méthodes :
moby/buildkit:rootlessBUILDKITD_FLAGS: --oci-worker-no-process-sandbox pour le fonctionnement rootlessbuildctl-daemonless.sh pour gérer le démon BuildKit automatiquementGitLab CI/CD fournit une authentification automatique pour le registre de conteneurs GitLab via des variables prédéfinies. Pour BuildKit rootless, vous devez créer manuellement le fichier de configuration Docker.
GitLab fournit automatiquement ces variables prédéfinies :
CI_REGISTRY : URL du registreCI_REGISTRY_USER : Nom d'utilisateur du registreCI_REGISTRY_PASSWORD : Mot de passe du registrePour configurer l'authentification pour les builds rootless, ajoutez une configuration before_script à vos jobs. Par exemple :
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
Pour vous authentifier auprès d'autres registres de conteneurs, combinez les entrées d'authentification dans votre section before_script. Par exemple :
before_script:
- mkdir -p ~/.docker
- |
echo "{
\"auths\": {
\"${CI_REGISTRY}\": {
\"auth\": \"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"
},
\"docker.io\": {
\"auth\": \"$(printf "%s:%s" "${DOCKER_HUB_USER}" "${DOCKER_HUB_PASSWORD}" | base64 | tr -d '\n')\"
}
}
}" > ~/.docker/config.json
Pour extraire des images via le proxy de dépendances GitLab, configurez l'authentification dans votre section before_script. Par exemple :
before_script:
- mkdir -p ~/.docker
- |
echo "{
\"auths\": {
\"${CI_REGISTRY}\": {
\"auth\": \"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"
},
\"$(echo -n $CI_DEPENDENCY_PROXY_SERVER | awk -F[:] '{print $1}')\": {
\"auth\": \"$(printf "%s:%s" ${CI_DEPENDENCY_PROXY_USER} "${CI_DEPENDENCY_PROXY_PASSWORD}" | base64 | tr -d '\n')\"
}
}
}" > ~/.docker/config.json
Pour plus d'informations, voir s'authentifier dans CI/CD.
Pour créer des images sans dépendance au démon Docker, ajoutez un job similaire à cet exemple :
build-rootless:
image:
name: moby/buildkit:rootless
entrypoint: [""]
stage: build
variables:
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
script:
- |
buildctl-daemonless.sh build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--output type=image,name=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA,push=true
Pour créer des images pour plusieurs architectures en mode rootless, configurez votre job afin de spécifier les plateformes cibles. Par exemple :
build-multiarch-rootless:
image:
name: moby/buildkit:rootless
entrypoint: [""]
stage: build
variables:
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
script:
- |
buildctl-daemonless.sh build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--opt platform=linux/amd64,linux/arm64 \
--output type=image,name=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA,push=true
Pour activer la mise en cache basée sur le registre afin d'accélérer les builds ultérieurs, configurez l'import et l'export du cache dans votre job de build. Par exemple :
build-cached-rootless:
image:
name: moby/buildkit:rootless
entrypoint: [""]
stage: build
variables:
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
CACHE_IMAGE: $CI_REGISTRY_IMAGE:cache
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
script:
- |
buildctl-daemonless.sh build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--export-cache type=registry,ref=$CACHE_IMAGE \
--import-cache type=registry,ref=$CACHE_IMAGE \
--output type=image,name=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA,push=true
Les miroirs de registre permettent des extractions d'images plus rapides et peuvent aider en cas de limite de débit ou de restrictions réseau.
Pour configurer des miroirs de registre, créez un fichier buildkit.toml qui spécifie les points de terminaison du miroir. Par exemple :
build-mirror-rootless:
image:
name: moby/buildkit:rootless
entrypoint: [""]
stage: build
variables:
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox --config /tmp/buildkit.toml
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
- cat <<'EOF' > /tmp/buildkit.toml
[registry."docker.io"]
mirrors = ["mirror.example.com"]
EOF
script:
- |
buildctl-daemonless.sh build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--output type=image,name=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA,push=true
Dans cet exemple, remplacez mirror.example.com par l'URL de votre miroir de registre.
Si votre GitLab Runner fonctionne derrière un proxy HTTP(S), configurez les paramètres de proxy en tant que variables dans votre job. Par exemple :
build-behind-proxy:
image:
name: moby/buildkit:rootless
entrypoint: [""]
stage: build
variables:
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
http_proxy: <your-proxy>
https_proxy: <your-proxy>
no_proxy: <your-no-proxy>
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
script:
- |
buildctl-daemonless.sh build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--build-arg http_proxy=$http_proxy \
--build-arg https_proxy=$https_proxy \
--build-arg no_proxy=$no_proxy \
--output type=image,name=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA,push=true
Dans cet exemple, remplacez <your-proxy> et <your-no-proxy> par votre configuration de proxy.
Pour envoyer vers un registre en utilisant des certificats CA personnalisés, ajoutez le certificat au magasin de certificats du conteneur avant le build. Par exemple :
build-with-custom-certs:
image:
name: moby/buildkit:rootless
entrypoint: [""]
stage: build
variables:
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
before_script:
- export SSL_CERT_FILE="$HOME/ca_chain.pem"
- cat /etc/ssl/certs/ca-certificates.crt > "$SSL_CERT_FILE"
- echo "$MY_CA_CERT" >> "$SSL_CERT_FILE"
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
script:
- |
buildctl-daemonless.sh build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--output type=image,name=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA,push=true
Dans cet exemple, renseignez la variable MY_CA_CERT avec le contenu complet de votre certificat CA, incluant à la fois le certificat racine et tout certificat intermédiaire.
BuildKit rootless est une alternative sécurisée à Kaniko. Il offre des performances améliorées, une meilleure mise en cache et des fonctionnalités de sécurité renforcées tout en maintenant le fonctionnement rootless.
Mettez à jour votre configuration Kaniko existante pour utiliser la méthode BuildKit rootless. Par exemple :
Avant, avec Kaniko :
build:
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
- /kaniko/executor
--context $CI_PROJECT_DIR
--dockerfile $CI_PROJECT_DIR/Dockerfile
--destination $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
Après, avec BuildKit rootless :
build:
image:
name: moby/buildkit:rootless
entrypoint: [""]
variables:
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
script:
- |
buildctl-daemonless.sh build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--output type=image,name=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA,push=true
Si vous n'avez pas besoin de builds rootless, BuildKit propose des méthodes supplémentaires qui nécessitent le service docker:dind mais offrent des workflows familiers ou des fonctionnalités avancées.
Docker Buildx étend les capacités de build Docker avec les fonctionnalités de BuildKit tout en conservant une syntaxe de commande familière. Cette méthode nécessite le service docker:dind.
Pour créer des images Docker avec Buildx, configurez votre job avec le service docker:dind et créez un builder buildx. Par exemple :
variables:
DOCKER_TLS_CERTDIR: "/certs"
build-image:
image: docker:cli
services:
- docker:dind
stage: build
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker buildx create --use --driver docker-container --name builder
- docker buildx inspect --bootstrap
script:
- docker buildx build --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --push .
after_script:
- docker buildx rm builder
Les builds multi-plateformes créent des images pour différentes architectures en une seule commande de build. Le manifeste résultant prend en charge plusieurs architectures, et Docker sélectionne automatiquement l'image appropriée pour chaque cible de déploiement.
Pour créer des images pour plusieurs architectures, ajoutez le flag --platform pour spécifier les architectures cibles. Par exemple :
variables:
DOCKER_TLS_CERTDIR: "/certs"
build-multiplatform:
image: docker:cli
services:
- docker:dind
stage: build
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker buildx create --use --driver docker-container --name multibuilder
- docker buildx inspect --bootstrap
script:
- docker buildx build
--platform linux/amd64,linux/arm64
--tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
--push .
after_script:
- docker buildx rm multibuilder
La mise en cache basée sur le registre stocke les couches de build dans un registre de conteneurs pour les réutiliser entre les builds.
L'option mode=max exporte toutes les couches vers le cache et offre un potentiel de réutilisation maximal pour les builds ultérieurs.
Pour utiliser la mise en cache de build, ajoutez des options de cache à votre commande de build. Par exemple :
variables:
DOCKER_TLS_CERTDIR: "/certs"
CACHE_IMAGE: $CI_REGISTRY_IMAGE:cache
build-with-cache:
image: docker:cli
services:
- docker:dind
stage: build
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker buildx create --use --driver docker-container --name cached-builder
- docker buildx inspect --bootstrap
script:
- docker buildx build
--cache-from type=registry,ref=$CACHE_IMAGE
--cache-to type=registry,ref=$CACHE_IMAGE,mode=max
--tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
--push .
after_script:
- docker buildx rm cached-builder
Utilisez les commandes BuildKit natives buildctl pour un meilleur contrôle du processus de build. Cette méthode nécessite le service docker:dind.
Pour utiliser BuildKit directement, configurez votre job avec l'image BuildKit et le service docker:dind. Par exemple :
variables:
DOCKER_TLS_CERTDIR: "/certs"
build-with-buildkit:
image: moby/buildkit:latest
services:
- docker:dind
stage: build
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > ~/.docker/config.json
script:
- |
buildctl build \
--frontend dockerfile.v0 \
--local context=. \
--local dockerfile=. \
--output type=image,name=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA,push=true
Si vous rencontrez des échecs d'authentification au registre :
CI_REGISTRY_USER et CI_REGISTRY_PASSWORD sont disponibles.Pour les problèmes liés aux permissions en mode rootless :
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox est défini.Dockerfile.Si vous recevez [rootlesskit:child ] error: failed to share mount point: /: permission denied sur un runner Kubernetes, AppArmor bloque l'appel système de montage requis par BuildKit.
Pour résoudre ce problème, ajoutez ce qui suit à la configuration de votre runner :
[runners.kubernetes.pod_annotations]
"container.apparmor.security.beta.kubernetes.io/build" = "unconfined"
invalid local: stat path/to/image/Dockerfile: not a directory {#error-invalid-local-stat-pathtoimagedockerfile-not-a-directory}Vous pourriez recevoir une erreur indiquant invalid local: stat path/to/image/Dockerfile: not a directory.
Ce problème survient lorsque vous spécifiez un chemin de fichier au lieu d'un chemin de répertoire pour le paramètre --local dockerfile=. BuildKit attend un chemin de répertoire contenant un fichier nommé Dockerfile.
Pour résoudre ce problème, utilisez le chemin du répertoire au lieu du chemin complet du fichier. Par exemple :
--local dockerfile=path/to/image--local dockerfile=path/to/image/DockerfilePour les problèmes de build multi-plateformes :
Dockerfile prennent en charge les architectures cibles.Dockerfile pour la logique spécifique à l'architecture.