Docker 基于 Mac OSX 构建的映像不会 运行 在 AWS EC2 实例上

Docker Image built on Mac OSX won't run on AWS EC2 instance

基于 Mac OSX 使用 M1 处理器构建的图像,部署到 EC2 实例。但是当脚本是 运行 时,它会产生错误:

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

在 Whosebug 的其他地方,这被解释为 OS 架构不匹配。果然 运行 EC2 实例上的“uname -m”显示它是 x86_64,而“docker image inspect”显示容器具有架构 arm64。

这是我不明白的地方。我的 Mac 上的“uname -m”显示也是 x86_64。那么容器如何继承不同的架构呢?

更重要的是,如何在我的 Mac 上构建可以在 EC2 上 运行 的映像?

Docker 文件就是

FROM python
WORKDIR /
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY src /src

src 当前包含一些简单的 python 脚本,因此执行:

docker run container/name python test.py

这在我的 Mac 上运行良好,但在 AWS 上执行时出现上述错误。

我不确定你为什么会收到这个错误,但如果你愿意并且不介意你的代码和图像被 public .我猜这只是家里的东西,所以可能还不错。

  1. 将您的代码放入 github。
  2. 配置存储库 hub.docker.com 为您的映像配置自动构建 github
  3. ssh 到您的 ec2 实例并直接拉取您的镜像 来自 docker 枢纽

另一种方法是从第 1 步开始,然后使用 ssh 登录到您的 ec2,并在该机器上克隆存储库。然后您可以直接在真正的 linux 机器上构建它(您的 osx 机器没有 运行 Linux,这与 docker 立即不匹配)。如果您在服务器上构建它,您应该能够 运行 那里没有问题。

尝试 运行 与 CMD ["lscpu"] 或容器中的 cat /proc/cpuinfo 等相关内容,比较架构

另一件事:您可能在构建时拉 arm 图像的 python 架构,并尝试 运行 它在 x86_64 (EC2)

好的。这是正在发生的事情。我的 Mac 有新的 M1 芯片,我正在 运行 安装 Tech Preview version of Docker Desktop。在引擎盖下,芯片具有 arm64 架构,但通过 iTerm 和 VSCode 查询它,它声称是 x86_64,因此我在发布问题时感到困惑。这可能是因为这两个应用程序都在幕后通过 Intel 模拟器悄悄地 运行,这就是对 uname 命令的响应。

但是,因为处理器真的是 arm64,所以当我从 Docker 中提取 Python 图像时,这是基本架构(我尝试了很多不同的版本 Python - 所有结果相同)。

为了强制使用 amd64 AWS 兼容图像,我将 Docker 文件的第一行更改为:

FROM --platform=linux/x86-64 python.

当此映像中的容器 运行 在 Mac 上时会导致警告

WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested

但这只是一个警告和脚本 运行s(大概是通过英特尔模拟器重定向回来的。脚本现在 运行 在 EC2 实例上没有问题(或警告) .

除了上面分享的内容,您还可以使用 Buildx 构建 multi-arch 图像。

基本上,最近的 Docker 版本带有一个名为 buildx 的 CLI 命令。您可以在 Docker 桌面上使用 buildx 命令为 Mac 和 Windows 构建 multi-arch 图像,link 它们连同清单文件,并使用单个命令将它们全部推送到注册表。

以下是适合我的方法:

创建一个新的构建器来访问新的 multi-arch结构特征。

docker buildx create --name mybuilder --use

使用 buildx 构建 Docker 文件,传递要构建的架构列表:

 docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t username/demo:latest --push .
 => pushing layers                                                             2.7s
 => pushing manifest for docker.io/username/demo:latest                       2.2

其中,用户名 是有效的 Docker 用户名。

备注: --platform 标志通知 buildx 为 AMD 64 位、Arm 64 位和 Armv7 架构生成 Linux 图像。
--push 标志生成 multi-arch 清单并将所有图像推送到 Docker Hub。

要检查图像,请使用以下命令

docker buildx imagetools inspect username/demo:latest