我们最近将所有 Jenkins docker 版本转换为多架构,并且通常运行良好。 他们正在基于 ARM 的实例上构建,因此 x86 构建正在通过 qemu,这需要很长时间,并且还存在一些故障(特别是对于几个 Go 项目)。
我很高兴能够启动一些专用的 x86 构建资源。 唯一棘手的一点是我们的构建代理是自动缩放的,因此我见过的一些用于配置了解特定架构的“远程”构建器的方法将需要更多代码来查找活动代理。
我们的 Docker 编排框架允许我们将任何正在运行的服务 ip/端口要求作为依赖项扩展到另一个服务的环境中,因此我可以创建一个仅包含
docker buildx create
步骤的虚拟映像。 并且它需要挂出以确定远程构建器是否已消失并被替换。 但我突然想到,直接将 buildkit 添加到我的集群清单中并以这种方式传递远程构建器会更干净。
有没有办法像
docker run
那样直接 docker buildx create
构建套件?
(旁注:如果我可以通过 haproxy 与 buildkit 对话,并且它不会假设每次连接时都会获得相同的后端,这将大大简化事情,因为我可以将遥控器指向反向代理并让服务路由规则跟踪动态后端。)
事实证明这实际上非常简单。
在我的自动缩放英特尔构建机器上,我正在做相当于
docker run moby/buildkit:latest --privileged --addr tcp://0.0.0.0:8086
我在arm构建机器上做了同样的事情,除了在不同的端口上:
docker run moby/buildkit:latest --privileged --addr tcp://0.0.0.0:8085
在我的 Jenkins JNLP 代理上,我传入(任意命名的)环境变量来定义本地和远程平台,并传入一个环境变量来定义上面列出的远程服务器。
local_name="$(echo $BUILDKIT_LOCAL_PLATFORM|sed -E 's/(.+\/)?(.*)/\2/')-builder"
docker buildx create --use --name multi-builder --node "${local_name}"\
--platform="${BUILDKIT_LOCAL_PLATFORM}"\
--driver remote "${BUILDKIT_LOCAL_SERVER}"
remote_name="$(echo $BUILDKIT_REMOTE_PLATFORM|sed -E 's/(.+\/)?(.*)/\2/')-builder"
docker buildx create --append --name multi-builder --node "${remote_name}"\
--platform="${BUILDKIT_REMOTE_PLATFORM}"\
--driver remote "${BUILDKIT_REMOTE_SERVER}"
本地服务器是
tcp://<local-ip-address>:8085
或 tcp://<ip-address>:8086
,具体取决于架构,而远程服务器......这取决于架构。 如果每个架构都有一个构建机器,那么很简单,只需使用相同的语法对名称或 IP 进行硬编码即可。 我通过将它们放在自动缩放组中的 haproxy
后面来获得奖励积分。 所以我的远程服务器地址就是我的代理的 DNS 名称。 如果有人发现这一点并希望做类似的事情,那么让构建服务器位于代理后面实际上效果出奇地好! 我的设置如下所示:
frontend buildkit-amd
bind *:8086
mode tcp
default_backend buildkit-amd
acl corp-ip src -f /bastion/haproxy/allow/corp.allow
tcp-request connection reject if !corp-ip
timeout client 60m
timeout connect 60s
frontend buildkit-arm
bind *:8085
mode tcp
default_backend buildkit-arm
acl corp-ip src -f /bastion/haproxy/allow/corp.allow
tcp-request connection reject if !corp-ip
timeout client 60m
timeout connect 60s
动态生成的后端服务器列表(我使用etcd/confd):
backend buildkit-arm
mode tcp
balance leastconn
timeout server 60m
server buildkit-arm-2ef8437b8c226e0cee4b13d1e216906fe4eda78c7147c33b79d131dbaa0f2f64 10.2.1.60:8085
server buildkit-arm-868212ff42b1dc35be162182c219f15a9df161424b5517964402750ff730407e 10.2.3.80:8085
backend buildkit-amd
mode tcp
balance leastconn
timeout server 60m
server buildkit-amd-21de68bf69b323ee5a7c4c388d878d32249f89af2abca16053b0331dc11296ce 10.2.5.13:8086
server buildkit-amd-25b06ab35f2f34b333d8f8214c11d6aecb84c3fcfca19d63c0746cafa60f5416 10.2.1.239:8086
请注意,我未能在 haproxy 的
h2
模式下使用此功能,但 tcp 模式似乎工作正常。 请注意,长期连接所需的超时时间会增加。 (我们的设置受到开发 VPN 的 IP 白名单的保护;如果您更注重安全,您会需要证书之类的。)
当我登录到构建工作程序并在 JNLP 代理内 docker 执行 shell 时,我可以像这样检查我的设置:
# docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
multi-builder* remote
\_ arm64-builder \_ tcp://10.2.3.80:8085 running v0.16.0 linux/arm64*, linux/arm/v7, linux/arm/v6
\_ amd64-builder \_ tcp://devproxy.mycorp.com:8086 running v0.16.0 linux/amd64*, linux/amd64/v2, linux/amd64/v3, linux/386
default docker
\_ default \_ default running v0.16.0 linux/arm64
如果一切正常,您将看到所有构建工作人员的“正在运行”状态。 (对我来说,一件完全令人惊讶的事情是,如果我在主机级别运行它,与在安装了
docker buildx ls
的容器内运行它,/var/run/docker.sock
显示不同的结果!大多数 docker 内容是相同的,但 buildkit 关注 docker 上下文,这这不是我探索太多的领域。)
这是一个相当小众的问答,但我希望它能对那里的人有所帮助!