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

see*_*ode 35 macos docker google-cloud-run

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

\n

观察到的行为:

\n

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

\n
    \n
  1. `git克隆git@github.com:seenickcode/trivial-go-api.git\'
  2. \n
  3. cd trivial-go-api
  4. \n
  5. docker build -t gcr.io/<YOUR GCR PROJECT ID>/example .
  6. \n
  7. docker push -t gcr.io/<YOUR GCR PROJECT ID>/example
  8. \n
  9. 转到console.cloud.google.comGoogle Cloud Run > 创建新服务 > 选择推送的 Docker 映像(包含所有默认选项)> 运行
  10. \n
  11. 显示错误:
  12. \n
\n
Cloud Run error: Container failed to start. \nFailed to start and then listen on the port defined by the PORT environment variable. \nLogs for this revision might contain more information.\n
Run Code Online (Sandbox Code Playgroud)\n

日志:

\n
2021-04-02 09:35:40.045 EDT\nCloud Run ReplaceService example hello@redactedforso.com {@type: type.googleapis.com/google.cloud.audit.AuditLog, authenticationInfo: {\xe2\x80\xa6}, authorizationInfo: [\xe2\x80\xa6], methodName: google.cloud.run.v1.Services.ReplaceService, request: {\xe2\x80\xa6}, requestMetadata: {\xe2\x80\xa6}, resourceLocation: {\xe2\x80\xa6}, resourceName: namespaces/myprojectforso-282419/services/example, response: {\xe2\x80\xa6}, servi\xe2\x80\xa6\nError\n2021-04-02 09:35:49.034 EDT\nterminated: Application failed to start: Failed to create init process: failed to load /app/main: exec format error\nWarning\n2021-04-02 09:35:49.174 EDT\nApplication exec likely failed\nNotice\n2021-04-02 09:57:43.102 EDT\nCloud Run ReplaceService example hello@redactedforso.com {@type: type.googleapis.com/google.cloud.audit.AuditLog, authenticationInfo: {\xe2\x80\xa6}, authorizationInfo: [\xe2\x80\xa6], methodName: google.cloud.run.v1.Services.ReplaceService, request: {\xe2\x80\xa6}, requestMetadata: {\xe2\x80\xa6}, resourceLocation: {\xe2\x80\xa6}, resourceName: namespaces/myprojectforso-282419/services/example, response: {\xe2\x80\xa6}, servi\xe2\x80\xa6\nError\n2021-04-02 09:57:50.657 EDT\nterminated: Application failed to start: Failed to create init process: failed to load /app/main: exec format error\n
Run Code Online (Sandbox Code Playgroud)\n

有关我正在构建图像的位置的系统详细信息:

\n
    \n
  • 操作系统:macOS 11.2.3
  • \n
  • 芯片:苹果M1
  • \n
  • Docker 版本:适用于 macOS 的 Docker Desktop v3.3.0 (62345)
  • \n
\n

重要笔记:

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

Bep*_*e C 57

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

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

docker buildx build --platform linux/amd64 -t myapp .
Run Code Online (Sandbox Code Playgroud)

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

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

  • 说得通。虽然“buildx”方法适用于上面引用的简单 Go 示例,但当我将其用于中型 Rust Web 应用程序时,随机库无法编译。我收到退出代码 101,失败发生在随机 Rust 库的编译过程中。有任何想法吗? (2认同)

N.B*_*ans 19

从 docker API version 1.40开始,您可以使用该选项指定需要构建映像的平台--platform,而无需使用 buildx。

docker build --platform=linux/amd64 -t myapp .
Run Code Online (Sandbox Code Playgroud)

  • 我试过这个并且有效。无需使用“buildx”。 (2认同)