

使用buildx构建多平台可用Docker镜像
source link: https://xiaozhou.net/buildx-and-multi-cpu-architecture-support-2020-04-07.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用buildx构建多平台可用Docker镜像
在日常的开发中,我们会有让程序在不同平台运行的需求。除了常用的Windows系统,Linux系统以及Mac OS系统外,我们甚至还希望让程序运行在以树莓派为代表的ARM平台下,或者是跑在嵌入式设备的路由器上。要构建出适合不同平台的镜像并不是一件容易的事情,除非你直接到目标平台下构建,或者模拟出目标平台下的环境来进行构建。
最近我的开源项目GoDNS就有用户提了个issue,GoDNS的Docker镜像在树莓派平台下运行失败,从错误提示来看,就知道是镜像的问题。之前只考虑了镜像在Linux或者Mac OS下运行,完全没考虑兼容树莓派平台。解决的办法,最直接的就是在树莓派中去打包和构建镜像。不过,我手头又没有树莓派,难道要去买一个?这成本也有点太高了点。
幸好,新版的Docker从版本19.03后已经开始支持一个新的命令行工具,叫做buildx
,目地就是为了解决我们在一个平台下,一次性构建出多个平台可用镜像的需求。buildx
是一个基于命令行的Docker扩展插件。在MacOS下,如果你使用桌面版的Docker,非常容易启用这个插件,只需要打开Experimental features
这个选项即可。
启用这个新特性之后,需要重启Docker,然后在命令行进行验证:
> docker buildx version
github.com/docker/buildx v0.3.1-tp-docker 6db68d029599c6710a32aa7adcba8e5a344795a7
看到显示的版本号,表示buildx已经启用成功。默认情况下,Docker不会启用多平台架构的构建器,需要我们自己创建一个新的构建器,并激活和启动这个新的构建器:
> docker buildx create --name mybuilder
创建完成后,启用新的构建器:
> docker buildx inspect mybuilder --bootstrap
最后,再次验证构建器是否正常运行:
docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
mybuilder * docker-container
mybuilder0 unix:///var/run/docker.sock stopped
default docker
default default running linux/amd64, linux/arm64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
在此可以看到,新的构建器已经支持其他多种平台。接下来,我们需要实战操作一下,用新的构建器,构建支持多系统平台的多个镜像。以我的项目GoDNS为例,Dockerfile如下:
FROM golang:alpine AS builder
RUN mkdir /godns
ADD . /godns/
WORKDIR /godns
RUN go build -o godns cmd/godns/godns.go
FROM alpine
RUN apk add --update ca-certificates
RUN mkdir /usr/local/godns
COPY --from=builder /godns/godns /usr/local/godns
RUN chmod +x /usr/local/godns/godns
RUN rm -rf /var/cache/apk/*
WORKDIR /usr/local/godns
ENTRYPOINT ["./godns", "-c", "/usr/local/godns/config.json"]
Dockerfile使用多步构建并打包镜像。随后,我们使用docker buildx一次性构建出多CPU平台的镜像,并push到DockerHub:
docker buildx build --platform linux/amd64,linux/386,linux/arm64,linux/arm/v7 -t timothyye/godns:latest . --push
在DockerHub上,我们能看到同一个版本的镜像下,用digest区分出了基于不同平台版本的镜像:
而当不同系统的用户,通过docker pull命令去拉取镜像的时候,docker会自动pull跟当前系统所匹配的镜像。这样一来,我们再也不用为构建不同CPU架构的镜像而犯愁了。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK