我可以设置 arm64 docker 映像,但无法运行任何东西

Joh*_*son 3 x86-64 qemu docker arm64

我有一个 CentOS 7 x86_64 虚拟机。我需要在 Oracle Linux 8 arm64 docker 容器中执行一些操作。

我安装了 docker 和 qemu:

$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 
$ sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin \
 qemu-system-arm qemu qemu-user qemu-kvm qemu-kvm-tools libvirt virt-install \
 libvirt-python libguestfs-tools-c
Run Code Online (Sandbox Code Playgroud)

然后我启动 docker 并设置 qemu-user-static:

$ sudo systemctl start docker
$ docker run --rm --privileged multiarch/qemu-user-static --reset
Run Code Online (Sandbox Code Playgroud)

我的 Dockerfile 是:

FROM oraclelinux:8.5
ENV container docker
RUN dnf -y install sssd nscd unzip zip xz which file
RUN useradd --uid 1001 -ms /bin/bash cm
RUN uname -m
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令创建 x86_64 和 arm64 映像:

docker buildx create --name ol8_builder
docker buildx --builder ol8_builder build -t frickson/oracle8 . --platform=linux/amd64 --load --progress=plain
docker buildx --builder ol8_builder build -t frickson/oracle8arm . --platform=linux/arm64 --load --progress=plain
Run Code Online (Sandbox Code Playgroud)

在构建两个镜像的过程中,RUN useradd会创建作品和用户。这RUN uname -m适用于两个系统,产生正确的输出(分别为x86_64aarch64)。

x86_64机器正常工作:

$ docker run --rm --privileged frickson/oracle8 uname -m
x86_64
Run Code Online (Sandbox Code Playgroud)

但arm64机器没有:

$ docker run --platform linux/arm64 --rm --privileged frickson/oracle8arm uname -a
exec /usr/bin/uname: no such file or directory
Run Code Online (Sandbox Code Playgroud)

我猜它没有找到一个或多个库,因为它在图像构建过程中起作用。尝试运行任何命令(bashlstrue)都会导致相同的错误消息。

我有什么想法吗?谢谢!

编辑:回应@JosephSible-ReinstateMonica:

它不起作用。而且我无法访问 ARM 主机来检查我的映像。

$ sudo docker run --platform linux/arm64 -it --rm --privileged oraclelinux:8 /bin/bash
Unable to find image 'oraclelinux:8' locally
8: Pulling from library/oraclelinux
e12ce518ed4b: Pull complete 
Digest: sha256:cad3a3dc2dd9f03dec02642dce1f194562e7f21820bc36ceb9f7b070d337fb45
Status: Downloaded newer image for oraclelinux:8
exec /bin/bash: no such file or directory
Run Code Online (Sandbox Code Playgroud)

lar*_*sks 6

当您运行时docker run --rm --privileged multiarch/qemu-user-static --reset,它将 aarch64 二进制文件的处理程序设置为:

\n
[root@localhost ~]# cat /proc/sys/fs/binfmt_misc/qemu-aarch64\nenabled\ninterpreter /usr/bin/qemu-aarch64-static\nflags:\noffset 0\nmagic 7f454c460201010000000000000000000200b700\nmask ffffffffffffff00fffffffffffffffffeffffff\n
Run Code Online (Sandbox Code Playgroud)\n

不幸的是,CentOS 7 没有-static这些二进制文件的版本:

\n
[root@localhost ~]# ls /usr/bin/qemu-aarch64*\n/usr/bin/qemu-aarch64\n
Run Code Online (Sandbox Code Playgroud)\n

幸运的是,multiarch/qemu-user-static容器包含镜像中必要的二进制文件;您可以像这样复制到您的主机上:

\n
$ docker run --rm  --entrypoint tar multiarch/qemu-user-static \\\n    -C /usr/bin -cf- . | tar -C /usr/bin -xf-\n
Run Code Online (Sandbox Code Playgroud)\n

现在我们有:

\n
[root@localhost bin]# ls /usr/bin/qemu-aarch64*\n/usr/bin/qemu-aarch64  /usr/bin/qemu-aarch64_be-static  /usr/bin/qemu-aarch64-static\n
Run Code Online (Sandbox Code Playgroud)\n

这让我们如此接近,但我们需要将静态二进制文件安装到图像中,如multiarch/qemu-user-static 文档中所述:

\n
[root@localhost bin]# docker run --platform linux/arm64 --rm -v /usr/bin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static  oraclelinux:8.5 uname -a\nLinux 2d7e2e0ce6d7 3.10.0-1160.66.1.el7.x86_64 #1 SMP Wed May 18 16:02:34 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux\n
Run Code Online (Sandbox Code Playgroud)\n

(或者您需要将解释器构建到图像中。)

\n

我们需要qemu-aarch64-static在 CentOS 7 上挂载到容器内,因为内核似乎不支持解释器F标志binfmt_misc。该F旗帜的含义是:

\n
\n

F - 修复二进制文件

\n

binfmt_misc 的通常行为是在调用 Misc 格式文件时延迟生成二进制文件。然而,面对挂载命名空间和更改根目录,这并不能很好地工作,因此 F 模式在安装仿真后立即打开二进制文件,并使用打开的图像来生成仿真器,这意味着它始终是安装后可用,无论环境如何变化。

\n
\n

(来自内核文档

\n

multiarch/qemu-user-static如果您在命令行上F设置\n ,则会设置该标志,但在 CentOS 7 上,此操作会失败并显示:--persistent yes

\n
$ docker run --rm --privileged multiarch/qemu-user-static --reset\n--persistent yes\n...\nSetting /usr/bin/qemu-aarch64-static as binfmt interpreter for aarch64\nsh: write error: Invalid argument\n
Run Code Online (Sandbox Code Playgroud)\n
\n

对于最近的 Fedora 发行版(可能还有其他发行版),您只需安装该qemu-user-static软件包,一切就可以正常工作(无需使用multiarch/qemu-user-static图像):

\n
$ cat /etc/fedora-release\nFedora release 34 (Thirty Four)\n$ rpm -q qemu-user-static\nqemu-user-static-5.2.0-9.fc34.x86_64\n$ uname -m\nx86_64\n$ docker run --platform linux/arm64 --rm oraclelinux:8.5 uname -a\nLinux 6f04d17234f5 5.17.6-100.fc34.x86_64 #1 SMP PREEMPT Mon May 9 14:41:31 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux\n
Run Code Online (Sandbox Code Playgroud)\n

该软件包会为您qemu-user-static安装所有\n注册。binfmt_misc

\n