可以在 Windows 上的 Docker 中运行 ARM/rpi 映像,但不能在 Linux 上运行

问题描述 投票:0回答:6

我能够在 Windows(64 位)上的 Docker 中运行 ARM 映像(例如 hypriot/rpi-node),但在我尝试过的所有 Linux x86/64 机器(Debian、CoreOS、Alpine 等)中,我得到了以下错误 - 这对我来说很有意义,但我不明白为什么它会在 Windows 上的 Docker 中运行,我想知道我是否错过了一些使用 x86 机器作为 ARM 映像构建服务器的机会(即 in谷歌/AWS云/天蓝色)。有什么想法我可以怎样做吗?

docker run -ti hypriot/rpi-node ls
standard_init_linux.go:175: exec user process caused "exec format error"
linux docker raspberry-pi arm
6个回答
5
投票

Windows 版 Docker(和 Mac 版 docker)都使用 Linux 虚拟机来托管容器。然而,他们使用的 linux 虚拟机和你的 linux 机器之间的区别在于,他们的虚拟机有一个名为 binfmt_misc setup 的内核系统,每当遇到外国架构的二进制文件时就会调用 qemu (https://github.com/linuxkit /linuxkit/blob/1c552f7a9db7f0660d3c83362d241e54142323ca/pkg/binfmt/etc/binfmt.d/00_linuxkit.conf

如果您要正确配置您的 Linux 计算机,它可以用作 ARM 映像的构建服务器。 Google

qemu-user-static
了解一些如何设置的想法。

请注意,linuxkit 虚拟机使用“F”标志,在配置典型的 Linux 环境时这似乎不是标准的。如果没有它,您需要将 qemu 二进制文件放入容器中。我不确定为什么在更多地方使用“F”不是标准做法(似乎确实有一个 debian bug 这样做https://bugs.debian.org/cgi-bin/bugreport.cgi ?bug=868030


0
投票

在 Windows 和 Mac 上,docker 在 Linux VM 下工作。所以,我认为,Windows 下的容器启动了 ARM Linux VM。但在原生Linux下使用原生架构。


0
投票

“exec 格式错误”确认您没有在正确的架构上运行 docker 映像。 我尝试在 Raspberry Pi 2(适用于 ARM 架构)上运行 x86 docker 映像时遇到此错误。我很确定当你反过来做时可能会出现同样的错误。

所以,正如 Kulti 所说,Windows/MAC 一定启动了 ARM Linux VM。 如果您希望在 Linux 上使用 ARM docker 映像,您可能需要尝试手动运行 Linux docker VM。我认为你甚至可以在 Linux 上使用“docker-machine”来做到这一点:docker-machine的 Docker 文档。 (我自己没做过所以不确定)

希望这有帮助。


0
投票

Windows 上的 Docker 使用 Linux VM,该 VM 已配置为可以通过 Qemu 用户模式模拟运行其他架构的映像。您可以以类似的方式配置本机 Linux,然后它也将运行 ARM 映像。有一个写得很好的三部分系列,详细描述了这一切

第 1 部分 中学到的主要内容是 Linux 上的任何文件都是通过解释器执行的(甚至是二进制文件)。解释器的选择是可配置的,通过 binfmt_misc,基于文件开头或文件扩展名等的字节模式。

第 2 部分 基于第 1 部分构建,展示如何配置 Linux 内核(安装在任何架构上)以使用 Qemu 用户仿真解释 ARM 二进制文件。

最后第 3 部分展示了如何将相同的技巧应用于 docker 容器中的 Linux 设置,这意味着 linux docker 容器(可以适用于任何架构)将能够执行 ARM 二进制文件。

这里需要注意的重要一点是,docker 实现或容器化并没有什么特别之处,可以让 Windows 上的 docker 能够执行 ARM 二进制文件。相反,任何 Linux 设置(无论是在裸机上还是在容器中)都可以配置为通过 Qemu 的 ARM cpu 用户模式模拟来执行 ARM 二进制文件。


0
投票

您需要为 qemu 的

binfmt_misc
模块配置内核,并且容器需要在容器文件系统内提供 qemu 使用的静态二进制文件。

您可以使用

hyperiot/qemu-register
映像加载主机上的文件,但我更喜欢可用的发行版供应商包(确保更新时获得补丁)。对于 Debian,重要的软件包是
qemu-user-static
,您可以使用 root 身份安装:

apt-get update && apt-get install qemu-user-static

确保内核模块已加载(以 root 身份):

modprobe binfmt_misc

然后,在运行容器时,您可以将静态 qemu 二进制文件挂载到容器中,而不是将它们打包到映像中,例如对于臂弓:

docker run -it --rm \
  -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static:ro \
  hypriot/rpi-node /bin/sh

Docker 在 Docker for Desktop 上使用的嵌入式 Linux VM 中包含

binfmt_misc
,并且似乎有一些附加功能可以避免需要在容器内手动挂载静态 qemu 文件。


0
投票

我知道这篇文章已经过时了,但我会在这里发布我的解决方案,以防有人通过 Google 来到这里。

发生这种情况是因为您的 Docker 主机无法运行 ARM 架构的映像。要在 Docker 中启用此功能,只需运行:

docker run --rm --privileged hypriot/qemu-register

您可以在这篇post上找到更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.