如何在 docker 容器中为 arm 安装 qemu 模拟器

How to install qemu emulator for arm in a docker container

我的目标是构建一个 Docker Build 图像,可以用作 CI 能够构建多架构图像的阶段。

FROM public.ecr.aws/docker/library/docker:20.10.11-dind

# Add the buildx plugin to Docker
COPY --from=docker/buildx-bin:0.7.1 /buildx /usr/libexec/docker/cli-plugins/docker-buildx

# Create a buildx image builder that we'll then use within this container to build our multi-architecture images
RUN docker buildx create --platform linux/amd64,linux/arm64 --name=my-builder --use

^构建我需要的容器,但不包括arm64的模拟器。这意味着当我尝试使用它通过像 docker buildx build --platform=$SUPPORTED_ARCHITECTURES --build-arg PHP_VERSION=8.0.1 -t my-repo:latest . 这样的命令构建多体系结构图像时,我收到错误:

error: failed to solve: process "/dev/.buildkit_qemu_emulator /bin/sh -c apt-get update && apt-get -y install -q ....

解决方案是 运行 docker run --rm --privileged tonistiigi/binfmt --install arm64 作为 CI 步骤的一部分,它使用我之前构建的 buildx 容器。但是,真的想通过在 Dockerfile 中添加类似这样的内容来理解为什么模拟器似乎无法安装在容器中

# Install arm emulator
COPY --from=tonistiigi/binfmt /usr/bin/binfmt /usr/bin/binfmt
RUN /usr/bin/binfmt --install arm64

I'd really like to understand why the emulator cannot seem to be installed in the container

因为当您执行 RUN 命令时,结果是捕获该步骤的文件系统更改,并将它们保存到映像中的新层。但是 qemu setup 命令并没有真正修改文件系统,它正在修改主机内核,这就是为什么它需要 --privileged 到 运行。配置 qemu 后,您将在主机上的 /proc/sys/fs/binfmt_misc/ 中看到这些内核更改的证据。不可能将该标志指定为容器构建的一部分,Dockerfile 中的所有步骤 运行 都是无特权的,无法访问主机设备或更改主机内核。

CI 系统中的标准做法是预先配置主机,然后 运行 docker 构建。在 GitHub 操作中,这是在 运行 构建步骤之前使用 setup-qemu-action 完成的。