【发布时间】:2023-02-01 05:03:46
【问题描述】:
要求: 应用程序必须容器化为 docker 镜像,并且需要支持 arm64 和 amd64 架构。
代码库: 这是一个需要使用git2go库的golang应用程序,并且必须有CGO_ENABLED=1才能构建项目。可以找到最小的可重现示例here on github。
主机:我正在使用 arm64 M1 mac 和 docker 桌面构建应用程序,但在我们的 amd64 Jenkins CI 构建系统上结果相似。
文件:
FROM golang:1.17.6-alpine3.15 as builder
WORKDIR /workspace
COPY go.mod go.mod
COPY go.sum go.sum
RUN apk add --no-cache libgit2 libgit2-dev git gcc g++ pkgconfig
RUN go mod download
COPY main.go main.go
ARG TARGETARCH TARGETOS
RUN CGO_ENABLED=1 GO111MODULE=on GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -tags static,system_libgit2 -a -o gitoperations main.go
FROM alpine:3.15 as runner
WORKDIR /
COPY --from=builder /workspace/gitoperations .
ENTRYPOINT ["/gitoperations"]
这就是我构建图像的方式:
docker buildx create --name gitops --use
docker buildx build --platform=linux/amd64,linux/arm64 --pull .
此设置有效,但在为不同的拱门构建时构建时间太长。此特定构建步骤之间的时间差:
RUN CGO_ENABLED=1 GO111MODULE=on GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -tags static,system_libgit2 -a -o gitoperations main.go 在构建不同的拱门时总是长 10 倍:
例子:
- 在 arm64 M1 mac(没有 rossetta)上:构建 arm64 可执行文件需要大约 30 秒,而 amd64 需要大约 300 秒。
- 在我们的 amd64 Jenkins CI 系统上:构建 arm64 可执行文件比构建 amd64 可执行文件花费的时间长 10 倍。
可以通过查看
docker buildx build命令输出来了解此构建时间。
我相信(而且我肯定是错的)它的发生是因为 docker 在构建与主机的 cpu arch 不同的 cpu 架构时使用qemu仿真。所以我想利用 golang 的交叉编译功能来加快构建时间。我试过的:我想通过尝试以下语法在这个 dockerfile 中为 arm 和 amd arch 设置一个
builder阶段:FROM --platform=$BUILDPLATFORM golang:1.17.6-alpine3.15 as builder。 但是在对 dockerfile 进行此更改后使用相同的 docker 构建命令会产生构建错误,这是我在 arm64 M1 mac 上运行时得到的结果:> [linux/arm64->amd64 builder 9/9] RUN CGO_ENABLED=1 GO111MODULE=on GOOS=linux GOARCH=amd64 go build -tags static,system_libgit2 -a -o gitoperations main.go: #0 1.219 # runtime/cgo #0 1.219 gcc: error: unrecognized command-line option '-m64'阅读golang CGO documentation后,我认为发生此错误是因为
go没有选择能够为两种架构构建的正确c编译器,我需要设置CC环境变量来指示goc编译器使用。问题:我假设
qemu导致构建时间差异并且可以通过使用 golang 的本机交叉编译功能来减少它是否正确?
我如何使用 docker desktop 从任何主机为 amd64 和 arm64 编译go build,因为我没有任何使用C代码和gcc的经验,而且我不确定我应该为CC标志设置什么值在go build命令中是否需要支持linux/amd64和linux/arm64?
【问题讨论】: