Golang distroless Docker在启用CGO时执行失败:找不到文件或目录。

huangapple go评论108阅读模式
英文:

Golang distroless Docker exec failed: No such file or directory when CGO is enabled

问题

我正在尝试在 Docker 容器中运行一个最简化的 Go 应用程序示例。但是当我运行容器时,一直出现 exec /app: no such file or directory 的错误。

我检查了在构建和复制应用程序数据的镜像中的所有路径,甚至使用交互式 shell 在容器内部查看,以验证我的 app 是否存在,但是什么都没有起作用。

我的 Dockerfile:

# syntax=docker/dockerfile:1
# BUILD-STAGE
FROM golang:1.17-alpine as build

WORKDIR /go/app

COPY . .

RUN go mod download

RUN go build -o /go/bin/app

# RUN-STAGE
FROM gcr.io/distroless/static-debian11

COPY --from=build /go/bin/app .

EXPOSE 8080

CMD ["./app"]

经过几个小时的尝试和错误,最后我尝试在 go build 命令中添加了 CGO_ENABLED=0,然后它成功了!

我的问题是...为什么会发生这种情况呢?
在使用 CGO 隐式启用时,构建镜像时没有出现错误,我甚至验证了二进制文件是否被复制到了第二阶段!为什么在使用 CGO 构建时,运行时会说找不到文件,但是在禁用 CGO 构建时却可以轻松找到呢?

英文:

I was trying to get a minimal example go app running inside a docker container.
But I kept getting exec /app: no such file or directory when running the container.

I checked and double checked all my paths in the image where I built and copied my application data, even looked inside the container with interactive shell to verify my app was there but nothing worked.

My Dockerfile:

# syntax=docker/dockerfile:1
# BUILD-STAGE
FROM golang:1.17-alpine as build

WORKDIR /go/app

COPY . .

RUN go mod download

RUN go build -o /go/bin/app

# RUN-STAGE
FROM gcr.io/distroless/static-debian11

COPY --from=build /go/bin/app .

EXPOSE 8080

CMD ["./app"]

After several hours of try and error I finally tried to add CGO_ENABLED=0 to my go build command.... and it worked!

My question is now.... why exactly does this happen?
There was no error when I built my image with CGO implicitly enabled and I even verified that the binary was copied into my second stage!
Why does the runtime say there is no such file when it was built using CGO, but can find it easily when it was built with CGO disabled?

答案1

得分: 11

你正在使用的镜像不包含libc 1,而你在使用CGO_ENABLED=1时构建你的go应用程序时需要libc。
1所建议,你可以使用gcr.io/distroless/base代替gcr.io/distroless/static
在构建你的应用程序时没有出现错误,因为golang:1.17-alpine包含musl libc(类似于libc但更小)。
然后你尝试在一个不再具有libc的环境中运行需要libc的应用程序,所以出现了no such file错误。

google container tools

英文:

The image that you are using does not contain libc 1 which you build your go app against when using CGO_ENABLED=1.
As suggested in 1 you can use gcr.io/distroless/base instead of gcr.io/distroless/static.
There was no error when building your app because golang:1.17-alpine contains musl libc (something like libc but smaller).
Then you tried running the app that required libc in an environment that does not have it anymore. So the no such file error.

google container tools

huangapple
  • 本文由 发表于 2022年6月23日 15:28:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/72726192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定