我猜你正在尝试在非arm64v8平台上构建docker镜像。对于其余的答案,我会假设这一点。
提供的解决方案将特定于 Ubuntu 发行版(主机),但我想它在其他 Linux 发行版上应该类似。
解决方案1[在 Ubuntu 18.04 上工作]
From https://github.com/docker/for-linux/issues/56我们可以看到 Debian(以及 Ubuntu?)的软件包中当前存在错误。
sudo apt-get install qemu-user-static
git clone https://github.com/computermouth/qemu-static-conf.git
sudo mkdir -p /lib/binfmt.d
sudo cp qemu-static-conf/*.conf /lib/binfmt.d/
sudo systemctl restart systemd-binfmt.service
这将删除qemu-user-binfmt
解决方案 2 中的方法。但是,在该包中,提供的配置文件不在文件夹中,并且配置错误,无法使用systemd-binfmt
.
此外,我们从 git 存储库获取配置文件,并将它们放在 systemd-binfmt 查找的文件夹中:/lib/binfmt.d/
(not /var/lib/binfmts/
由 qemu-user-static 安装)
然后检查状态:
systemctl status systemd-binfmt
并尝试再次编译你的docker。它应该有效!
解决方案2[目前不适用于 Ubuntu 18.04]
以前是手动配置过程,但现在通过 apt 包支持:
sudo apt-get install qemu-user-binfmt
这样它将创建binfmt
以下所有平台的配置/proc/sys/fs/binfmt_misc/qemu-*
。当你的系统检测到可执行文件是针对arm的时,它会调用qemu而不是尝试直接执行。
这是更详细解释的链接:https://ownyourbits.com/2018/06/13/transparently-running-binaries-from-any-architecture-in-linux-with-qemu-and-binfmt_misc/ or https://ownyourbits.com/2018/06/27/running-and-building-arm-docker-containers-in-x86/
要理解它是如何工作的,最好阅读以下段落:
内核识别ARM ELF魔法,并使用解释器/usr/bin/qemu-arm-static
,这是正确的 QEMU 二进制文件
建筑学。 0x7F 'ELF' 的十六进制是7f 45 4c 46
, 所以我们可以
看看魔法和面具如何一起工作,考虑到
ELF头的结构
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* 0x7F 'ELF' four byte ELF magic for any architecture */
uint16_t e_type;
uint16_t e_machine; /* architecture code, 40=0x28 in the case of ARM */
uint32_t e_version;
ElfN_Addr e_entry;
ElfN_Off e_phoff;
ElfN_Off e_shoff;
uint32_t e_flags;
uint16_t e_ehsize;
uint16_t e_phentsize;
uint16_t e_phnum;
uint16_t e_shentsize;
uint16_t e_shnum;
uint16_t e_shstrndx;
} ElfN_Ehdr;
请注意,binfmt
配置由 docker 共享,因此它将尝试获取/usr/bin/qemu-arm-static
容器内。这就是您仍然需要复制 /usr/bin/qemu-arm-static 的原因。