运行使用 Apple M1 芯片(基于 ARM 的系统)构建的容器时出现“执行格式错误”

Posted

技术标签:

【中文标题】运行使用 Apple M1 芯片(基于 ARM 的系统)构建的容器时出现“执行格式错误”【英文标题】:"exec format error" when running containers build with Apple M1 Chip (ARM based systems) 【发布时间】:2021-06-29 09:41:37 【问题描述】:

预期行为:我可以运行使用 Apple M1 芯片构建的容器。

观察到的行为:

假设您有一个 Google Cloud Run 帐户并且可以将 Docker 映像推送到 Google Container Registry。我在这个例子中使用https://github.com/seenickcode/trivial-go-api。

    `git clone git@github.com:seenickcode/trivial-go-api.git' cd trivial-go-api docker build -t gcr.io/<YOUR GCR PROJECT ID>/example . docker push -t gcr.io/<YOUR GCR PROJECT ID>/example 转到console.cloud.google.com,Google Cloud Run > 创建新服务 > 使用所有默认选项选择您推送的 Docker 映像 > 运行 显示错误:
Cloud Run error: Container failed to start. 
Failed to start and then listen on the port defined by the PORT environment variable. 
Logs for this revision might contain more information.

日志:

2021-04-02 09:35:40.045 EDT
Cloud Run ReplaceService example hello@redactedforso.com @type: type.googleapis.com/google.cloud.audit.AuditLog, authenticationInfo: …, authorizationInfo: […], methodName: google.cloud.run.v1.Services.ReplaceService, request: …, requestMetadata: …, resourceLocation: …, resourceName: namespaces/myprojectforso-282419/services/example, response: …, servi…
Error
2021-04-02 09:35:49.034 EDT
terminated: Application failed to start: Failed to create init process: failed to load /app/main: exec format error
Warning
2021-04-02 09:35:49.174 EDT
Application exec likely failed
Notice
2021-04-02 09:57:43.102 EDT
Cloud Run ReplaceService example hello@redactedforso.com @type: type.googleapis.com/google.cloud.audit.AuditLog, authenticationInfo: …, authorizationInfo: […], methodName: google.cloud.run.v1.Services.ReplaceService, request: …, requestMetadata: …, resourceLocation: …, resourceName: namespaces/myprojectforso-282419/services/example, response: …, servi…
Error
2021-04-02 09:57:50.657 EDT
terminated: Application failed to start: Failed to create init process: failed to load /app/main: exec format error

关于我在哪里构建图像的系统详细信息:

操作系统:macOS 11.2.3 芯片:苹果M1 Docker 版本:Docker Desktop for macOS v3.3.0 (62345)

重要提示:

当我使用其他架构(即通过 Google Container Build 或我的家庭 Windows (WSL) 桌面)时,这一切对我来说完全正常。 当使用 Apple M1 芯片构建时,这也不适用于其他代码库,例如我用 Rust 和 Dart 编写的另一个项目。似乎与语言无关。 我已经使用 Google Cloud Run 多年了,在使用配备 Apple M1 芯片的新笔记本电脑时出现了这个问题。

【问题讨论】:

您正在 ARM 平台上构建代码并尝试在 x86_64 平台上运行它。查看this doc,Google Cloud 似乎并未提供 ARM 平台。您将需要在与您的目标环境兼容的平台上构建图像。 【参考方案1】:

您正在构建 Google Cloud 不支持的与 ARM 兼容的映像。

我在将 Mac M1 构建的映像推送到 Heroku 时遇到了类似的问题,我使用 buildx 解决了这个问题并设置了预期的平台

docker buildx build --platform linux/amd64 -t myapp .

我写了一个Medium的帖子来解释问题并提出2个解决方案。

Docker 在设计上是多平台的,可以在不同的架构上运行,但是,镜像必须与它们将运行的平台相匹配。这不是我们的情况。

【讨论】:

有道理。虽然buildx 方法适用于上面引用的简单 Go 示例,但当我将它用于中型 Rust webapp 时,随机库无法编译。我得到一个退出代码 101,失败是在编译随机 Rust 库期间。有什么想法吗? 很难说没有看到错误,我会尝试其他选项(设置 DOCKER_DEFAULT_PLATFORM) 不幸的是,DOCKER_DEFAULT_PLATFORM 方法产生了同样的错误。要么我的系统不够强大,要么使用 buildx 编译某些 Rust 库可能很脆弱。目前,我保留了一个廉价的计算优化 AWS 现货实例作为我的构建服务器。 不错的选择,我使用 GitHub 操作来构建我的 docker 镜像并将它们推送到 Heroku。如果您有兴趣,我的 GitHub 存储库中有一个示例。 这仍然完美。

以上是关于运行使用 Apple M1 芯片(基于 ARM 的系统)构建的容器时出现“执行格式错误”的主要内容,如果未能解决你的问题,请参考以下文章

苹果芯片(M1/Apple Chip)通过UTM安装x86架构虚拟机指南/性能测试(以ubuntu18.04为例)

MacOS(M1芯片 arm架构)下如何安装tensorflow

Apple M1 - macosx-arm64 尚不可用的 Maven Java 依赖项

苹果 m1 芯片下运行 flink 程序使用 rocksdb 状态后端兼容性问题

苹果 m1 芯片下运行 flink 程序使用 rocksdb 状态后端兼容性问题

ARM64架构(M1芯片):无法安装pg gem(使用PostgresApp)