Kubernetes 驱动

Kubernetes 驱动程序允许您将本地开发或 CI 环境连接到 Kubernetes 集群中的构建器,以便访问更强大的计算资源,可选地在多个原生架构上。

概要

运行以下命令以创建一个名为 kube 的新构建器,该构建器使用 Kubernetes 驱动程序:

$ docker buildx create \
  --bootstrap \
  --name=kube \
  --driver=kubernetes \
  --driver-opt=[key=value,...]

下表描述了可以传递给--driver-opt的可用驱动程序特定选项:

ParameterTypeDefaultDescription
imageStringSets the image to use for running BuildKit.
namespaceStringNamespace in current Kubernetes contextSets the Kubernetes namespace.
default-loadBooleanfalseAutomatically load images to the Docker Engine image store.
replicasInteger1Sets the number of Pod replicas to create. See 扩展 BuildKit
requests.cpuCPU unitsSets the request CPU value specified in units of Kubernetes CPU. For example requests.cpu=100m or requests.cpu=2
requests.memoryMemory sizeSets the request memory value specified in bytes or with a valid suffix. For example requests.memory=500Mi or requests.memory=4G
requests.ephemeral-storageStorage sizeSets the request ephemeral-storage value specified in bytes or with a valid suffix. For example requests.ephemeral-storage=2Gi
limits.cpuCPU unitsSets the limit CPU value specified in units of Kubernetes CPU. For example requests.cpu=100m or requests.cpu=2
limits.memoryMemory sizeSets the limit memory value specified in bytes or with a valid suffix. For example requests.memory=500Mi or requests.memory=4G
limits.ephemeral-storageStorage sizeSets the limit ephemeral-storage value specified in bytes or with a valid suffix. For example requests.ephemeral-storage=100M
nodeselectorCSV stringSets the pod's nodeSelector label(s). See node assignment.
annotationsCSV stringSets additional annotations on the deployments and pods.
labelsCSV stringSets additional labels on the deployments and pods.
tolerationsCSV stringConfigures the pod's taint toleration. See node assignment.
serviceaccountStringSets the pod's serviceAccountName.
schedulernameStringSets the scheduler responsible for scheduling the pod.
timeoutTime120sSet the timeout limit that determines how long Buildx will wait for pods to be provisioned before a build.
rootlessBooleanfalseRun the container as a non-root user. See rootless mode.
loadbalanceStringstickyLoad-balancing strategy (sticky or random). If set to sticky, the pod is chosen using the hash of the context path.
qemu.installBooleanfalseInstall QEMU emulation for multi platforms support. See QEMU.
qemu.imageStringtonistiigi/binfmt:latestSets the QEMU emulation image. See QEMU.

扩展 BuildKit

Kubernetes 驱动程序的主要优势之一是,您可以扩展构建器副本的数量以处理增加的构建负载。可以使用以下驱动程序选项配置扩展:

  • replicas=N

    这将BuildKit pod的数量扩展到所需的大小。默认情况下,它只创建一个pod。增加副本数量可以让您利用集群中的多个节点。

  • requests.cpu, requests.memory, requests.ephemeral-storage, limits.cpu, limits.memory, limits.ephemeral-storage

    这些选项允许根据官方Kubernetes文档请求和限制每个BuildKit pod可用的资源 这里.

例如,要创建4个副本的BuildKit pods:

$ docker buildx create \
  --bootstrap \
  --name=kube \
  --driver=kubernetes \
  --driver-opt=namespace=buildkit,replicas=4

列出这些pod,你会得到以下内容:

$ kubectl -n buildkit get deployments
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
kube0   4/4     4            4           8s

$ kubectl -n buildkit get pods
NAME                     READY   STATUS    RESTARTS   AGE
kube0-6977cdcb75-48ld2   1/1     Running   0          8s
kube0-6977cdcb75-rkc6b   1/1     Running   0          8s
kube0-6977cdcb75-vb4ks   1/1     Running   0          8s
kube0-6977cdcb75-z4fzs   1/1     Running   0          8s

此外,您可以使用loadbalance=(sticky|random)选项来控制当存在多个副本时的负载均衡行为。random从节点池中随机选择节点,提供跨副本的均匀工作负载分布。sticky(默认)尝试将多次执行的相同构建每次连接到同一节点,确保更好地利用本地缓存。

有关可扩展性的更多信息,请参阅 docker buildx create的选项。

节点分配

Kubernetes 驱动程序允许您使用 nodeSelectortolerations 驱动程序选项来控制 BuildKit pod 的调度。如果您想完全使用自定义调度程序,还可以设置 schedulername 选项。

你可以使用annotationslabels驱动选项来为托管你的构建器的部署和pod应用额外的元数据。

nodeSelector 参数的值是一个逗号分隔的键值对字符串,其中键是节点标签,值是标签文本。例如:"nodeselector=kubernetes.io/arch=arm64"

tolerations 参数是一个以分号分隔的污点列表。它接受与 Kubernetes 清单相同的值。每个 tolerations 条目指定一个污点键及其值、操作符或效果。例如: "tolerations=key=foo,value=bar;key=foo2,operator=exists;key=foo3,effect=NoSchedule"

这些选项接受以CSV分隔的字符串作为值。由于shell命令的引用规则,您必须将值用单引号括起来。您甚至可以将整个--driver-opt用单引号括起来,例如:

$ docker buildx create \
  --bootstrap \
  --name=kube \
  --driver=kubernetes \
  '--driver-opt="nodeselector=label1=value1,label2=value2","tolerations=key=key1,value=value1"'

多平台构建

Kubernetes 驱动程序支持创建 多平台镜像, 可以使用 QEMU 或利用节点的本地架构。

QEMU

docker-container驱动程序类似,Kubernetes驱动程序也支持使用 QEMU(用户 模式)为非本地平台构建镜像。包括--platform标志 并指定您想要输出的平台。

例如,为amd64arm64构建一个Linux镜像:

$ docker buildx build \
  --builder=kube \
  --platform=linux/amd64,linux/arm64 \
  -t <user>/<image> \
  --push .

警告

QEMU 对非本地平台进行全 CPU 仿真,这比本地构建要慢得多。像编译和压缩/解压缩这样的计算密集型任务可能会受到很大的性能影响。

使用自定义的BuildKit镜像或在构建中调用非本地二进制文件可能需要在创建构建器时明确使用qemu.install选项来启用QEMU:

$ docker buildx create \
  --bootstrap \
  --name=kube \
  --driver=kubernetes \
  --driver-opt=namespace=buildkit,qemu.install=true

原生

如果您可以访问不同架构的集群节点,Kubernetes 驱动程序可以利用这些节点进行本地构建。为此,请使用 docker buildx create--append 标志。

首先,创建一个明确支持单一架构的构建器,例如 amd64

$ docker buildx create \
  --bootstrap \
  --name=kube \
  --driver=kubernetes \
  --platform=linux/amd64 \
  --node=builder-amd64 \
  --driver-opt=namespace=buildkit,nodeselector="kubernetes.io/arch=amd64"

这将创建一个名为 kube 的 Buildx 构建器,其中包含一个名为 builder-amd64 的构建器节点。使用 --node 分配节点名称是可选的。如果您不提供节点名称,Buildx 将生成一个随机的节点名称。

请注意,Buildx 中的节点概念与 Kubernetes 中的节点概念不同。在这种情况下,Buildx 节点可以将相同架构的多个 Kubernetes 节点连接在一起。

使用创建的kube构建器,您现在可以使用--append将另一种架构引入组合中。例如,添加arm64

$ docker buildx create \
  --append \
  --bootstrap \
  --name=kube \
  --driver=kubernetes \
  --platform=linux/arm64 \
  --node=builder-arm64 \
  --driver-opt=namespace=buildkit,nodeselector="kubernetes.io/arch=arm64"

列出你的构建器会显示kube构建器的两个节点:

$ docker buildx ls
NAME/NODE       DRIVER/ENDPOINT                                         STATUS   PLATFORMS
kube            kubernetes
  builder-amd64 kubernetes:///kube?deployment=builder-amd64&kubeconfig= running  linux/amd64*, linux/amd64/v2, linux/amd64/v3, linux/386
  builder-arm64 kubernetes:///kube?deployment=builder-arm64&kubeconfig= running  linux/arm64*

你现在可以通过在你的构建命令中一起指定这些平台来构建多架构的amd64arm64镜像:

$ docker buildx build --builder=kube --platform=linux/amd64,linux/arm64 -t <user>/<image> --push .

您可以重复使用buildx create --append命令来支持尽可能多的架构。

无根模式

Kubernetes 驱动程序支持无根模式。有关无根模式的工作原理及其要求的更多信息,请参见这里

要在您的集群中启用它,您可以使用rootless=true驱动程序选项:

$ docker buildx create \
  --name=kube \
  --driver=kubernetes \
  --driver-opt=namespace=buildkit,rootless=true

这将创建没有securityContext.privileged的pods。

需要Kubernetes版本1.19或更高版本。建议使用Ubuntu作为主机内核。

示例:在Kubernetes中创建Buildx构建器

本指南向您展示如何:

  • 为您的Buildx资源创建一个命名空间
  • 创建一个Kubernetes构建器。
  • 列出可用的构建器
  • 使用您的Kubernetes构建器构建一个镜像

先决条件:

  • 您已经有一个现有的Kubernetes集群。如果还没有,您可以通过安装minikube来跟随操作。
  • 您想要连接的集群可以通过kubectl命令访问, 使用KUBECONFIG环境变量 适当设置 如果需要。
  1. 创建一个buildkit命名空间。

    创建一个单独的命名空间有助于将您的Buildx资源与集群中的其他资源分开。

    $ kubectl create namespace buildkit
    namespace/buildkit created
    
  2. 使用Kubernetes驱动程序创建一个新的构建器:

    $ docker buildx create \
      --bootstrap \
      --name=kube \
      --driver=kubernetes \
      --driver-opt=namespace=buildkit
    

    注意

    记得在驱动选项中指定命名空间。

  3. 使用docker buildx ls列出可用的构建器

    $ docker buildx ls
    NAME/NODE                DRIVER/ENDPOINT STATUS  PLATFORMS
    kube                     kubernetes
      kube0-6977cdcb75-k9h9m                 running linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
    default *                docker
      default                default         running linux/amd64, linux/386
    
  4. 使用kubectl检查由构建驱动程序创建的正在运行的pods。

    $ kubectl -n buildkit get deployments
    NAME    READY   UP-TO-DATE   AVAILABLE   AGE
    kube0   1/1     1            1           32s
    
    $ kubectl -n buildkit get pods
    NAME                     READY   STATUS    RESTARTS   AGE
    kube0-6977cdcb75-k9h9m   1/1     Running   0          32s
    

    构建驱动程序在指定的命名空间(在本例中为buildkit)中在您的集群上创建必要的资源,同时将您的驱动程序配置保留在本地。

  5. 使用您的新构建器时,在运行 buildx 命令时包含 --builder 标志。例如:

    # Replace <registry> with your Docker username
    # and <image> with the name of the image you want to build
    docker buildx build \
      --builder=kube \
      -t <registry>/<image> \
      --push .
    

就是这样:你现在已经使用Buildx从Kubernetes pod构建了一个镜像。

进一步阅读

有关Kubernetes驱动程序的更多信息,请参阅 buildx参考