简体   繁体   English

Docker 划痕图像未显示为 arm64

[英]Docker scratch image not showing up as arm64

I'm building a Docker image for multiple architectures (amd64 and arm64 - both on Linux).我正在为多种架构(amd64 和 arm64 - 都在 Linux 上)构建 Docker 映像。 I'm using a multistage build - this means using go-alpine image as a builder (to compile my Go source code into an executable), and then copying the executable to a smaller secondary image.我正在使用多阶段构建 - 这意味着使用 go-alpine 映像作为构建器(将我的 Go 源代码编译为可执行文件),然后将可执行文件复制到较小的辅助映像。

Initially, I was copying the compiled program into an Alpine image, but I decided to switch to a scratch image (because of the security benefit) - this involved changing my build command so that the resultant executable is statically linked.最初,我将编译后的程序复制到 Alpine 映像中,但我决定切换到临时映像(因为安全性优势) - 这涉及更改我的构建命令,以便生成的可执行文件是静态链接的。 My Dockerfile is now:我的 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"]

When I build for amd64, I run docker build --build-arg opts="CGO_ENABLED=0 GOOS=linux GOARCH=amd64" -t myuser/example:amd64.当我为 amd64 构建时,我运行docker build --build-arg opts="CGO_ENABLED=0 GOOS=linux GOARCH=amd64" -t myuser/example:amd64. - if I inspect this image, it shows "Architecture": "amd64" as expected. - 如果我检查此图像,它会按预期显示"Architecture": "amd64"

When I build for arm64, I run docker build --build-arg opts="CGO_ENABLED=0 GOOS=linux GOARCH=arm64" -t myuser/example:arm64.当我为 arm64 构建时,我运行docker build --build-arg opts="CGO_ENABLED=0 GOOS=linux GOARCH=arm64" -t myuser/example:arm64. - if I inspect this image, it shows "Architecture": "amd64" - which isn't what I want. - 如果我检查这张图片,它会显示"Architecture": "amd64" - 这不是我想要的。

If I compile the Go code locally by running CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build , and then I run file on the compiler output, it shows that the compiled output is arm64. If I compile the Go code locally by running CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build , and then I run file on the compiler output, it shows that the compiled output is arm64. I assume that the issue is therefore a result of Docker pulling an amd64 base image (since my PC is x86), but I can't figure out how to fix the issue.因此,我认为问题是 Docker 拉取 amd64 基础映像的结果(因为我的 PC 是 x86),但我不知道如何解决这个问题。

The snippets you shared are cross-compiling your Go binary, but like you pointed out, are still using an amd64 base image.您共享的片段正在交叉编译您的 Go 二进制文件,但正如您所指出的,仍在使用amd64基础映像。 To do this, you will need to build a docker container for multiple platforms:为此,您需要为多个平台构建 docker 容器:

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

The example is something like:该示例类似于:

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

Using the docker platform route, you shouldn't need to use go-multiarch building since the go tool should infer the platform its building for.使用 docker 平台路线,您不需要使用 go-multiarch 构建,因为go工具应该推断其构建的平台。

As an alternative, you could cross-compile your binary on your host, and then have a docker image for each platform that is based off of the scratch image for that architecture and just copies your executable in.作为替代方案,您可以在主机上交叉编译二进制文件,然后为每个平台创建一个 docker 映像,该映像基于该架构的暂存映像,只需将您的可执行文件复制进去。

Because you stand on AMD machine and docker will default pull AMD golang image to build your project.因为您站在 AMD 机器上,docker 将默认拉取 AMD golang 映像来构建您的项目。 There's several way to fix it, but this case I suggest use --platform=$BUILDPLATFORM有几种方法可以修复它,但这种情况我建议使用--platform=$BUILDPLATFORM

https://docs.docker.com/buildx/working-with-buildx/ https://docs.docker.com/buildx/working-with-buildx/

So, your Dockerfile look like:因此,您的 Dockerfile 看起来像:

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

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

And the build command in your local:以及本地的构建命令:

docker build --build-arg BUILDPLATFORM=linux/arm64 --build-arg opts="CGO_ENABLED=0 GOOS=linux GOARCH=arm64" -t myuser/example:arm64 .

But if you're building your Golang image with Github Action or CircleCI, please checkout these blog post below但是,如果您使用 Github Action 或 CircleCI 构建您的 Golang 映像,请查看下面的这些博客文章

Golang multi-arch image with Github Action https://namiops.medium.com/golang-multi-arch-docker-image-with-github-action-b59a62c8d2bd带有 Github 操作的 Golang 多架构镜像 https://namiops.medium.com/golang-multi-arch-docker-image-with-github-action-b59a62c8d2bd

Golang arm image with CircleCI https://namiops.medium.com/golang-arm64-docker-image-with-circleci-arm-machine-8bebf2151b92 Golang arm 镜像与 CircleCI https://namiops.medium.com/golang-arm64-docker-image-with-circleci-arm-machine-8bebf2151b92

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM