使用 docker buildx 实现多平台编译 - 案例篇
使用 docker buildx 实现多平台编译 - 案例篇
之前的文章中 使用 docker buildx 实现多平台编译 - 环境篇 介绍了如何部署 docker buildx 环境。
笔者本文将要分享自身在使用中的几个比较有意义的案例
0x00 先说结论
docker buildx
本身运行于容器环境, 所以 scheduler 和 builder 本机配置(ex,/etc/hosts
,/etc/docker/daemon.json
) 的大部分配置和场景 其实是不可用的。- 使用
ssh://user@host
可以方便的执行远程构建, 尤其是在构建最基础的镜像,需要海外镜像时。 docker buildx
现在仍然处于实验阶段,在不断的更新。 尤其是在 Dockerfile 的使用上有很多新特性, 可以参考 dockerfile experimental- 转存和合并镜像非常方便, 结合
github action
可以完全托管。
0x01 远端 builder
之前的文章中, 我们通过 qemu
模拟了多架构的环境。 但实际在使用中, 在模拟架构中执行工作效率是特别低的, 如果已经执行某些项目编译, 那你就应该感同身受了。
如笔者之前维护的 opencv 双架构的项目, 通过 github action 进行跨平台编译, 长达三四小时。而在本架构下只需要短短的10几分钟。
因此, 在同架构下执行编译或其他工作的需求就特别迫切了。
- 好在
docker buildx
可以支持 专机专用 - 根据机器架构执行对应的任务。 - 另外,
docker
本身也支持基于ssh://user@host
协议的远程调用。 通过免密码证书, 非常容易管理。
执行环境
假设有三台机器, 且 scheduler 能通过证书免密码登录两台 builder。
用途 | 主机地址 | CPU 架构 |
---|---|---|
scheduler | 10.100.100.10 | - |
arm64 builder | 192.168.100.101 | arm64 / aarch64 |
amd64 builder | 192.168.100.102 | amd64 / x86_64 |
创建 remotebuilder
在 scheduler(10.100.100.10) 创建 remotebuilder , 命令如下
|
|
到此位置, remote builder
及创建成功了。
当我们在本地执行 docker buildx build ...
任务的时候, 任务就会分发到对应 cpu 架构的主机上。
执行镜像构建
- 创建 Dockerfile
这里 Dockerfile
非常简单, 仅仅就是拉取 centos:8
镜像。
|
|
- 使用
docker buildx
命令拉取镜像。
注意: 这里我们没有使用
--tag
指定目标镜像名称。
|
|
- 重新执行
docker buildx
命令。
注意: 这次我们使用了
--tag
和--push
, 在构建完成后,会推送到目标docker registry
注意2: 如果要执行
--push
成功, 只需要在 scheduler 主机上执行docker login
即可, builder 上并无登录需求。
|
|
注意红框位置, 这次直接结果 , 多了 exporting
和 merging
当任务执行换成之后,所构建的 layer
缓存会存在与 remote builder
上, 同时 scheduler 上会保存多架构的 manifest 信息。
输出结果 tangx/centos:8 可以在 dockerhub 上看到。
0x02 配置优化
在国内使用 docker buildx
有一个最大的问题,就是网络。
由于 driver
是有运行在容器中, 参考官方文档
buildx - github.com
, 很多本机的配置因此而不能生效。
诸如 docker.io
这样国外官方镜像, 拉取速度就非常不理想了。
使用镜像加速优化
- 新建配置文件
buildkitd.toml
|
|
并创建本地 builder
|
|
- 新建
Dockerfile
|
|
并构建镜像
### build a image
docker buildx build --platform=linux/amd64,linux/arm64 .
结果如上图所示, 耗时约 14s 左右
使用默认参数,不使用镜像优化
- 创建不使用镜像优化的 mirror, 并执行构建
|
|
从图片中可以看到, 在没有 mirror 的情况下, 出现了网络问题。
这是因为 builder 运行在容器类, 并没有使用宿主机的
/etc/docker/daemon.json
配置 (假设宿主机已经配置了 mirror), 即相当于国内直连docker.io
拉去镜像。
0x03 Dockerfile 案例
如果你实现阅读了
Dockerfile ARG
使用及作用域的分析
, 那么以下两个 Dockerfile
就很简单了。
sync
唯一作用: 对镜像重命名, 通过参数的方式实现了不通镜像的同步。
|
|
|
|
combine
这里通过 多阶 构建中 别名
及 ${TARGETARCH}
的方式, 将两个独立 tag 镜像合并成一个。
例如
minio/minio
的镜像。
|
|
注意,
TARGETARCH
在FROM
中使用不需要预先声明ARG TARGETARCH
。TARGETARCH
在 body 中使用必须预先声明ARG TARGETARCH
。
|
|
- 原文链接:https://typonotes.com/posts/2020/11/07/docker-buildx-examples/
- 本文为原创文章,转载注明出处。
- 欢迎 扫码关注公众号
Go与云原生
或 订阅网站 https://typonotes.com/ 。 - 第一时间看后续精彩文章。觉得好的话,请猛击文章右下角「在看」,感谢支持。