Multi-arch docker build python arm64 命令 '('lsb_release', '-a')' 返回非零退出状态 1

Multi-arch docker build python arm64 Command '('lsb_release', '-a')' returned non-zero exit status 1

为了这个问题,我有一个名为 script.py 的 hello world python 脚本。

def hello_world():
    print("hello world")


if __name__ == "__main__":
    hello_world()

并有相应的Dockerfile:

FROM python:3.8-alpine

WORKDIR /app

COPY requirements.txt requirements.txt

RUN python3 -m pip install --upgrade pip
RUN python3 -m pip install -r requirements.txt

COPY . .

CMD [ "python3", "script.py"]

场景 #1(amd64 作为主机):

当我在这台主机上构建 amd64 架构时,我成功了。

$ docker buildx build --platform linux/amd64 -t sntshk/cotu:latest .
WARN[0000] No output specified for docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load 
[+] Building 2.6s (11/11) FINISHED                                                                                          
 => [internal] load build definition from Dockerfile                                                                   0.0s
 => => transferring dockerfile: 277B                                                                                   0.0s
 => [internal] load .dockerignore                                                                                      0.0s
 => => transferring context: 2B                                                                                        0.0s
 => [internal] load metadata for docker.io/library/python:3.8-alpine                                                   2.4s
 => [auth] library/python:pull token for registry-1.docker.io                                                          0.0s
 => [1/6] FROM docker.io/library/python:3.8-alpine@sha256:9b3ca9c8e9ec086ea825227ac6d819e46794c29590f04d775d517a48ef6  0.0s
 => => resolve docker.io/library/python:3.8-alpine@sha256:9b3ca9c8e9ec086ea825227ac6d819e46794c29590f04d775d517a48ef6  0.0s
 => [internal] load build context                                                                                      0.1s
 => => transferring context: 7.55kB                                                                                    0.1s
 => CACHED [2/6] WORKDIR /app                                                                                          0.0s
 => CACHED [3/6] COPY requirements.txt requirements.txt                                                                0.0s
 => CACHED [4/6] RUN python3 -m pip install --upgrade pip                                                              0.0s
 => CACHED [5/6] RUN python3 -m pip install -r requirements.txt                                                        0.0s
 => CACHED [6/6] COPY . .

但是 arm64 架构的构建失败:

[..output trimmed...]
#8 12.03   File "/usr/local/lib/python3.8/site-packages/pip/_vendor/distro.py", line 125, in linux_distribution
#8 12.03     return _distro.linux_distribution(full_distribution_name)
#8 12.03   File "/usr/local/lib/python3.8/site-packages/pip/_vendor/distro.py", line 681, in linux_distribution
#8 12.03     self.version(),
#8 12.03   File "/usr/local/lib/python3.8/site-packages/pip/_vendor/distro.py", line 741, in version
#8 12.03     self.lsb_release_attr('release'),
#8 12.03   File "/usr/local/lib/python3.8/site-packages/pip/_vendor/distro.py", line 903, in lsb_release_attr
#8 12.03     return self._lsb_release_info.get(attribute, '')
#8 12.03   File "/usr/local/lib/python3.8/site-packages/pip/_vendor/distro.py", line 556, in __get__
#8 12.03     ret = obj.__dict__[self._fname] = self._f(obj)
#8 12.03   File "/usr/local/lib/python3.8/site-packages/pip/_vendor/distro.py", line 1014, in _lsb_release_info
#8 12.03     stdout = subprocess.check_output(cmd, stderr=devnull)
#8 12.03   File "/usr/local/lib/python3.8/subprocess.py", line 415, in check_output
#8 12.03     return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
#8 12.03   File "/usr/local/lib/python3.8/subprocess.py", line 516, in run
#8 12.03     raise CalledProcessError(retcode, process.args,
#8 12.03 subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1.
------
Dockerfile:9
--------------------
   7 |     COPY requirements.txt requirements.txt
   8 |     
   9 | >>> RUN python3 -m pip install --upgrade pip
  10 |     RUN python3 -m pip install -r requirements.txt
  11 |     
--------------------
error: failed to solve: process "/dev/.buildkit_qemu_emulator /bin/sh -c python3 -m pip install --upgrade pip" did not complete successfully: exit code: 1

场景 #2(arm64 作为主机):

这里我就不多说了,但是在arm64上,构建arm64镜像是没有问题的。但是当我尝试在 arm64 主机上构建 amd64 图像时出现同样的错误。


我的最后一个问题是,如何在 arm64 主机上构建 amd64?

更新 1:

我正在 运行为 arm64 和 amd64 构建 arm64。

docker buildx build --push --platform linux/amd64,linux/arm64 -t me/myimage:latest .

现在的情况是我只能在arm机器上运行 arm64镜像,但是在amd64机器上,我看到这个错误:

standard_init_linux.go:228: exec user process caused: exec format error

我在 SO 上看到了这个关于 的答案。目前有什么问题吗?

您不需要文档中建议的 arm 图片吗:

Build multi-platform images

Finally, depending on your project, the language that you use may have good support for cross-compilation. In that case, multi-stage builds in Dockerfiles can be effectively used to build binaries for the platform specified with --platform using the native architecture of the build node. A list of build arguments like BUILDPLATFORM and TARGETPLATFORM is available automatically inside your Dockerfile and can be leveraged by the processes running as part of your build.

FROM --platform=$BUILDPLATFORM python:3.8-alpine AS build
...

我感谢 Corralien 的 ,这对摆脱 lsb_release 错误来说很棒。

关于您问题中的更新,请确保您正在构建的机器能够模拟您所针对的其他类型的架构。

了解这一点的最佳方法是在 buildx 构建器中检查它。

$ docker buildx create --name multiarch
$ docker buildx use multiarch
$ docker buildx inspect --bootstrap
Name:   multiarch
Driver: docker-container

Nodes:
Name:      multiarch0
Endpoint:  unix:///var/run/docker.sock
Status:    running
Platforms: linux/arm64, linux/arm/v7, linux/arm/v6

在这里您可以看到列出的 平台 仅基于 arm。而且无论您将 --platform 传递给 buildx 命令什么,都不会产生好的结果。

解决方案

软件包名称在不同的发行版上可能不同,但在 Ubuntu 上它被称为 qemu-user-static

$ apt install -y qemu-user-static

这将安装 QEMU 模拟器。如果您现在检查您的构建器,您会看到更多架构。

$ docker buildx inspect --bootstrap
Name:   multiarch
Driver: docker-container

Nodes:
Name:      multiarch0
Endpoint:  unix:///var/run/docker.sock
Status:    running
Platforms: linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6

附带说明一下,您可能需要重新启动 docker 服务才能生效。

我能够在我的 amd64 机器上重建 运行 amd64。

$ docker run --rm sntshk/cotu
Unable to find image 'sntshk/cotu:latest' locally
[...output trimmed...]
Status: Downloaded newer image for sntshk/cotu:latest
standard_init_linux.go:228: exec user process caused: exec format error

$ docker rmi sntshk/cotu
[...output trimmed...]
Deleted: sha256:07d3c46c9599a88fa81c385391300ab877b98ef71b18cce942455025657edeb5

$ docker run --rm sntshk/cotu
Unable to find image 'sntshk/cotu:latest' locally
latest: Pulling from sntshk/cotu
[...output trimmed...]
Status: Downloaded newer image for sntshk/cotu:latest
hello world

另请参阅 Artur Klauser 的 Building Multi-Architecture Docker Images With Buildx