1、跨 CPU 架构编译程序的方法
在 Linux 上,QEMU 除了可以模拟完整的操作系统之外,还有另外一种模式叫用户态模式(User mod)。该模式下 QEMU 将通过 binfmt_misc 在 Linux 内核中注册一个二进制转换处理程序,并在程序运行时动态翻译二进制文件,根据需要将系统调用从目标 CPU 架构转换为当前系统的 CPU 架构。最终的效果看起来就像在本地运行目标 CPU 架构的二进制文件。
通过 QEMU 的用户态模式,我们可以创建轻量级的虚拟机(chroot 或容器),然后在虚拟机系统中编译程序,和本地编译一样简单轻松。后面我们就会看到,跨平台构建 Docker 镜像用的就是这个方法。
2、下载buildx编译工具
传送门:https://github.com/docker/buildx,使用最新版即可
wget https://github.com/docker/buildx/releases/download/v0.11.2/buildx-v0.11.2.linux-amd64 -O /usr/bin/buildx chmod 755 /usr/bin/buildx
3、启用 binfmt_misc
如果你使用的是 Docker 桌面版(MacOS 和 Windows),默认已经启用了 binfmt_misc,可以跳过这一步。
如果你使用的是 Linux,需要手动启用 binfmt_misc。大多数 Linux 发行版都很容易启用,不过还有一个更容易的办法,直接运行一个特权容器,容器里面写好了设置脚本:
docker run --rm --privileged tonistiigi/binfmt --install all
installing: s390x OK
installing: ppc64le OK
installing: mips64le OK
installing: arm OK
installing: riscv64 OK
installing: 386 OK
installing: mips64 OK
installing: amd64 OK
{
"supported": [
"linux/arm64",
"linux/amd64",
"linux/riscv64",
"linux/ppc64le",
"linux/s390x",
"linux/386",
"linux/mips64le",
"linux/mips64",
"linux/arm/v7",
"linux/arm/v6"
],
"emulators": [
"qemu-arm",
"qemu-i386",
"qemu-mips64",
"qemu-mips64el",
"qemu-ppc64le",
"qemu-riscv64",
"qemu-s390x",
"qemu-x86_64"
]
}
4、构建并上传镜像
#创建dockerfile FROM --platform=$TARGETPLATFORM openjdk:8u342-jdk-slim MAINTAINER ae COPY ./rocketmq-dashboard.jar / ENTRYPOINT ["sh","-c","java $JAVA_OPTS -jar /rocketmq-dashboard.jar"] #通过platform指定要构建的环境,通过push推到远程仓库即可 buildx build --platform linux/arm64,linux/amd64 -t congcong126/openvpn-ldap-otp:v1.5 . --push
5、故障排查
#报错ERROR: Multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use"),可能是低版本不支持,高版本可执行 buildx create --name multi-platform --use --platform linux/amd64,linux/arm64 --driver docker-container