首页 > 解决方案 > Docker 暂存图像未显示为 arm64

问题描述

我正在为多种架构(amd64 和 arm64 - 都在 Linux 上)构建 Docker 映像。我正在使用多阶段构建 - 这意味着使用 go-alpine 映像作为构建器(将我的 Go 源代码编译为可执行文件),然后将可执行文件复制到较小的辅助映像。

最初,我将编译后的程序复制到 Alpine 映像中,但我决定切换到临时映像(出于安全考虑)——这涉及更改我的构建命令,以便生成的可执行文件是静态链接的。我的 Dockerfile 现在是:

FROM golang:1.16 AS builder
WORKDIR /go/src/
RUN go get -d -v ./...
COPY . .
RUN env ${opts} go build -a -installsuffix cgo -o app .

FROM scratch
WORKDIR /root/
COPY --from=builder /go/src/app .
CMD ["./app"]

当我为 amd64 构建时,我运行 docker build --build-arg opts="CGO_ENABLED=0 GOOS=linux GOARCH=amd64" -t myuser/example:amd64 . - 如果我检查这个图像,它会"Architecture": "amd64"按预期显示。

当我为 arm64 构建时,我运行 docker build --build-arg opts="CGO_ENABLED=0 GOOS=linux GOARCH=arm64" -t myuser/example:arm64 . - 如果我检查这个图像,它会显示"Architecture": "amd64"- 这不是我想要的。

如果我通过运行在本地编译Go代码CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build,然后file在编译器输出上运行,它显示编译输出是arm64。因此,我认为问题是 Docker 拉取 amd64 基础映像的结果(因为我的 PC 是 x86),但我不知道如何解决这个问题。

标签: linuxdockergoarm

解决方案


您共享的片段正在交叉编译您的 Go 二进制文件,但正如您所指出的,仍在使用amd64基础映像。为此,您需要为多个平台构建一个 docker 容器:

https://www.docker.com/blog/multi-arch-build-and-images-the-simple-way/

该示例类似于:

docker buildx build \
--platform linux/arm64/v8,linux/amd64 \ 
--tag your-username/multiarch-example:buildx-latest .

使用 docker 平台路由,您不需要使用 go-multiarch 构建,因为该go工具应该推断其构建的平台。

作为替代方案,您可以在您的主机上交叉编译您的二进制文件,然后为每个平台创建一个 docker 镜像,该镜像基于该架构的暂存镜像,并将您的可执行文件复制进去。


推荐阅读