CDI (Container Device Interface) provides a standard mechanism for device vendors to describe what is required to provide access to a specific resource such as a GPU beyond a simple device name.
Since BuildKit 0.20.0, you can access devices using the CDI interface. This allows you to use devices like GPUs in your builds.
Note
CDI support is yet to be tested on Windows.
To use CDI with BuildKit, you need to create the CDI configuration file for your device (either JSON or YAML) and put it in one of the following locations:
/etc/cdi/var/run/cdi/etc/buildkit/cdi
Note
Location can be changed by setting the specDirs option in the cdi section
of the buildkitd.toml configuration file.
Let's create a simple CDI configuration file that injects an environment
variable into the build environment and write it to /etc/cdi/foo.yml:
cdiVersion: "0.6.0"
kind: "vendor1.com/device"
devices:
- name: foo
containerEdits:
env:
- FOO=injectedStart BuildKit and check the list of available devices for the default worker:
buildctl debug workers -v
Platforms: linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6
BuildKit: github.com/moby/buildkit v0.19.0-rc3-72-gb89ee491b.m b89ee491bc1c40b8533f098dab18e414c8b70885.m
Labels:
org.mobyproject.buildkit.worker.executor: oci
org.mobyproject.buildkit.worker.hostname: cc39352c87dd
org.mobyproject.buildkit.worker.network: host
org.mobyproject.buildkit.worker.oci.process-mode: sandbox
org.mobyproject.buildkit.worker.selinux.enabled: false
org.mobyproject.buildkit.worker.snapshotter: overlayfs
Devices:
Name: vendor1.com/device=foo
AutoAllow: true
GC Policy rule#0:
All: false
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
Keep duration: 48h0m0s
Maximum used space: 512MB
GC Policy rule#1:
All: false
Keep duration: 1440h0m0s
Reserved space: 10GB
Minimum free space: 202GB
Maximum used space: 100GB
GC Policy rule#2:
All: false
Reserved space: 10GB
Minimum free space: 202GB
Maximum used space: 100GB
GC Policy rule#3:
All: true
Reserved space: 10GB
Minimum free space: 202GB
Maximum used space: 100GBNow let's create a Dockerfile to use this device:
FROM busybox
RUN --device=vendor1.com/device=foo \
env|grep FOOAnd check if the environment variable is injected during build:
buildctl build --frontend=dockerfile.v0 --no-cache --local context=. --local dockerfile=.
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 99B done
#1 DONE 0.0s
#2 [internal] load metadata for docker.io/library/busybox:latest
#2 ...
#3 [auth] library/busybox:pull token for registry-1.docker.io
#3 DONE 0.0s
#2 [internal] load metadata for docker.io/library/busybox:latest
#2 DONE 0.8s
#4 [internal] load .dockerignore
#4 transferring context: 2B done
#4 DONE 0.0s
#5 [1/2] FROM docker.io/library/busybox:latest@sha256:a5d0ce49aa801d475da48f8cb163c354ab95cab073cd3c138bd458fc8257fbf1
#5 resolve docker.io/library/busybox:latest@sha256:a5d0ce49aa801d475da48f8cb163c354ab95cab073cd3c138bd458fc8257fbf1 0.0s done
#5 CACHED
#6 [2/2] RUN --device=vendor1.com/device=foo env|grep FOO
#6 0.062 FOO=injected
#6 DONE 0.1s