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 .我猜这只是家里的东西,所以可能还不错。
- 将您的代码放入 github。
- 配置存储库
hub.docker.com 为您的映像配置自动构建
github
- 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
基于 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 .我猜这只是家里的东西,所以可能还不错。
- 将您的代码放入 github。
- 配置存储库 hub.docker.com 为您的映像配置自动构建 github
- 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