远程驱动程序

Buildx 远程驱动程序允许更复杂的自定义构建工作负载,允许您连接到外部管理的 BuildKit 实例。这对于需要手动管理 BuildKit 守护程序或 BuildKit 守护程序从其他来源公开的场景很有用。

概要

$ docker buildx create \
  --name remote \
  --driver remote \
  tcp://localhost:1234

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

参数类型默认值描述
key字符串设置 TLS 客户端密钥。
cert字符串要向buildkitd 提供的 TLS 客户端证书的绝对路径。
cacert字符串用于验证的 TLS 证书颁发机构的绝对路径。
servername字符串端点主机名。请求中使用的 TLS 服务器名称。
default-load布尔值false自动将镜像加载到 Docker Engine 镜像存储中。

示例:通过 Unix 套接字进行远程 BuildKit

本指南向您展示如何创建一个在 Unix 套接字上侦听 BuildKit 守护程序的设置,并让 Buildx 通过它进行连接。

  1. 确保已安装BuildKit

    例如,您可以使用以下命令启动 buildkitd 实例:

    $ sudo ./buildkitd --group $(id -gn) --addr unix://$HOME/buildkitd.sock
    

    或者,请参见此处了解如何在无根模式下运行 buildkitd,或此处了解将其作为 systemd 服务运行的示例。

  2. 检查您是否有可以连接的 Unix 套接字。

    $ ls -lh /home/user/buildkitd.sock
    srw-rw---- 1 root user 0 May  5 11:04 /home/user/buildkitd.sock
    
  3. 使用远程驱动程序将 Buildx 连接到它

    $ docker buildx create \
      --name remote-unix \
      --driver remote \
      unix://$HOME/buildkitd.sock
    
  4. 使用docker buildx ls列出可用的构建器。然后,您应该在其中看到remote-unix

    $ docker buildx ls
    NAME/NODE           DRIVER/ENDPOINT                        STATUS  PLATFORMS
    remote-unix         remote
      remote-unix0      unix:///home/.../buildkitd.sock        running linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/386
    default *           docker
      default           default                                running linux/amd64, linux/386
    

您可以使用docker buildx use remote-unix将其切换为此新的构建器作为默认构建器,或者使用--builder在每次构建时指定它。

$ docker buildx build --builder=remote-unix -t test --load .

请记住,如果您想将构建结果加载到 Docker 守护程序中,则需要使用--load标志。

示例:Docker 容器中的远程 BuildKit

本指南将向您展示如何创建类似于docker-container驱动程序的设置,方法是手动启动 BuildKit Docker 容器并使用 Buildx 远程驱动程序连接到它。此过程将手动创建一个容器并通过其公开的端口访问它。(您可能最好只使用通过 Docker 守护程序连接到 BuildKit 的docker-container驱动程序,但这仅用于说明目的。)

  1. 为 BuildKit 生成证书。

    您可以使用此bake 定义作为起点。

    SAN="localhost 127.0.0.1" docker buildx bake "https://github.com/moby/buildkit.git#master:examples/create-certs"
    

    请注意,虽然可以在不使用 TLS 的情况下通过 TCP 公开 BuildKit,但不推荐这样做。这样做允许在没有凭据的情况下任意访问 BuildKit。

  2. .certs/中生成证书后,启动容器

    $ docker run -d --rm \
      --name=remote-buildkitd \
      --privileged \
      -p 1234:1234 \
      -v $PWD/.certs:/etc/buildkit/certs \
      moby/buildkit:latest \
      --addr tcp://0.0.0.0:1234 \
      --tlscacert /etc/buildkit/certs/daemon/ca.pem \
      --tlscert /etc/buildkit/certs/daemon/cert.pem \
      --tlskey /etc/buildkit/certs/daemon/key.pem
    

    此命令启动 BuildKit 容器并将守护程序的端口 1234 公开到 localhost。

  3. 使用 Buildx 连接到此正在运行的容器

    $ docker buildx create \
      --name remote-container \
      --driver remote \
      --driver-opt cacert=${PWD}/.certs/client/ca.pem,cert=${PWD}/.certs/client/cert.pem,key=${PWD}/.certs/client/key.pem,servername=<TLS_SERVER_NAME> \
      tcp://localhost:1234
    

    或者,使用docker-container://URL 方案连接到 BuildKit 容器,无需指定端口

    $ docker buildx create \
      --name remote-container \
      --driver remote \
      docker-container://remote-container
    

示例:Kubernetes 中的远程 BuildKit

本指南将向您展示如何通过手动创建 BuildKit Deployment来创建类似于kubernetes驱动程序的设置。虽然kubernetes驱动程序会在后台执行此操作,但有时可能需要手动扩展 BuildKit。此外,当从 Kubernetes Pod 内部执行构建时,需要在每个 Pod 内重新创建 Buildx 构建器或在它们之间复制。

  1. 按照这里的说明创建buildkitd的Kubernetes部署。

    按照指南,使用create-certs.sh为BuildKit守护进程和客户端创建证书,并创建一个包含连接到它们的服务的BuildKit Pod部署。

  2. 假设服务名为buildkitd,在Buildx中创建一个远程构建器,确保列出的证书文件存在。

    $ docker buildx create \
      --name remote-kubernetes \
      --driver remote \
      --driver-opt cacert=${PWD}/.certs/client/ca.pem,cert=${PWD}/.certs/client/cert.pem,key=${PWD}/.certs/client/key.pem \
      tcp://buildkitd.default.svc:1234
    

请注意,这仅在集群内部有效,因为BuildKit设置指南仅创建ClusterIP服务。要远程访问构建器,您可以设置和使用 Ingress,但这不在本指南的范围内。

调试 Kubernetes 中的远程构建器

如果您在访问Kubernetes中部署的远程构建器时遇到问题,可以使用kube-pod:// URL方案通过Kubernetes API直接连接到BuildKit Pod。请注意,此方法仅连接到部署中的单个Pod。

$ kubectl get pods --selector=app=buildkitd -o json | jq -r '.items[].metadata.name'
buildkitd-XXXXXXXXXX-xxxxx
$ docker buildx create \
  --name remote-container \
  --driver remote \
  kube-pod://buildkitd-XXXXXXXXXX-xxxxx

或者,使用kubectl的端口转发机制。

$ kubectl port-forward svc/buildkitd 1234:1234

然后您可以将远程驱动程序指向tcp://localhost:1234