standard_init_linux.go:211:exec 用户进程导致 "no such file or directory" with alpine linux and python

standard_init_linux.go:211:exec user process caused "no such file or directory" with alpine linux and python

我有一个目录,其中包含 docker 文件、一个 attack.py 和一个 requirements.txt。

使用它,我创建了以下 docker 文件:

FROM arm64v8/python:3.7-alpine

COPY qemu-arm-static /usr/bin

COPY ./ app-ids
WORKDIR /app-ids

RUN pip install --no-cache-dir -r requirements.txt

CMD["python","./attack.py"]

但是,pip 安装行抛出: standard_init_linux.go:211:exec 用户进程导致 "no such file or directory"

我不明白为什么。使用 ls、pwd 等命令尝试对此进行调试会产生相同的错误。

谁能解释一下我到底做错了什么?

我猜您正在尝试在非 arm64v8 平台上构建 docker 映像。对于其余的答案,我会假设。

提供的解决方案将特定于 Ubuntu 发行版(主机),但我想它应该与其他 linux 发行版类似。

解决方案 1 [正在处理 Ubuntu 18.04]

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

这将从解决方案 2 中删除 qemu-user-binfmt 方法。但是在该包中,提供的配置文件不在文件夹中,并且配置错误,供 systemd-binfmt 使用。

此外,我们从 git 存储库中获取配置文件,并将它们放在 systemd-binfmt 查找的文件夹中:/lib/binfmt.d/(不是 /var/lib/binfmts/,因为 qemu 安装-用户静态)

然后查看状态:

systemctl status systemd-binfmt

并再次尝试编译您的 docker。应该有用!

解决方案 2 [目前未在 Ubuntu 18.04 上工作]

之前是手动配置,现在通过apt包支持:

sudo apt-get install qemu-user-binfmt

它会为 /proc/sys/fs/binfmt_misc/qemu-* 下的所有平台创建 binfmt 配置。当您的系统检测到可执行文件是针对 arm 的时,它会调用 qemu 而不是尝试直接执行。

这里有一个link更详细的解释: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/

要了解它是如何工作的,最好看下面一段:

The kernel recognizes the ARM ELF magic, and uses the interpreter /usr/bin/qemu-arm-static , which is the correct QEMU binary for the architecture. 0x7F 'ELF' in hexadecimal is 7f 45 4c 46, so we can see how the magic and the mask work together, considering the structure of the ELF header

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.

的原因