1 背景
最近在做to G项目,node语言开发,开发团队这边服务器CPU架构基本都是x86的,最终服务要部署到私有云上,然而私有云架构是arm64的,于是就有一个问题,如何构建跨平台镜像。
2 当前解决方法
本地压缩代码包,丢到私有云打包服务器上(代码包包含node_modules,私有云是不通网络的,无法npm install),然后就地打镜像上传到镜像仓库。
不足
大部分场景是可以满足的,但是依赖的某个包依赖二进制时候,这种情况下打出来的镜像部署后有问题,因为二进制文件是不可以跨CPU架构做移植的。所以不同架构下安装的依赖可能会不同。
3 最终解决方法
先说下结论:基于腾讯coding平台构建编译流水线,提前构建好基于arm架构的业务镜像,然后直接在私有云打包服务器上上传到镜像仓库。
如果条件有限,没办法用流水线搞的话,自己在服务器里折腾下也可以,不过即使构建好的镜像已经压缩为gz.tar,从服务器导出到本地速度也还是很慢的,要有十分的耐心。coding有个收集构建产物的过程,流水线执行完,直接下载就行了,这样省去了从服务器传到本地来回传送的功夫了。
3.1 buildx插件
Docker 19.03引入了插件buildx,可以轻松构建多平台镜像。使用前,要确保docker版本不低于19.03。
3.2 创建builder
Docker默认使用不支持多CPU架构的构建器,所以我们要自己整个。
docker buildx create --use --name mybuilder
看到输出 mybuilder 即表示创建成功,使用 --use 指令将在 builder 实例创建完成时自动将其设为默认。
3.3 安装qemu多平台支持
运行下面命令,启动一个容器,该容器负责安装qemu多平台支持。
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
3.4 基于Buildx构建镜像
buildx
和docker build
命令能支持的功能差不多,我们直接用docker buildx build执行构建即可。
如果要构建多平台镜像,需要指令中加入--platform=
,后面跟着需要构建的平台,如linux/arm64,linux/amd64等。
示例1:docker buildx build --platform=linux/arm,linux/arm64,linux/amd64 -t xxx/xxx:tagname . --push
说明:Buildx 将根据以上指令自动构建三个平台的镜像并推送到远端,这三个镜像的tag标签是相同的,都是命令中指定的同一个 tag。
示例2:docker buildx build --platform linux/arm64 -t xxxx/xxx:tagname -o type=docker .
说明:如果想将构建好的镜像保存在本地,可以将 type 指定为 docker,但必须分别为不同的 CPU 架构构建不同的镜像,不能合并成一个镜像,这里指定的CPU架构是arm64,后面可以通过docker save
的命令保存镜像为tar.gz文件,然后传输到arm架构的机器上导入。
PS:指定的plarform必须是底层镜像所支持的,可以通过docker buildx ls
查看当前使用的构建器及构建器支持的CPU架构。