Golang二进制文件在Docker容器内构建,仍然是Mach-O可执行文件格式吗?

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

Golang binary built inside Docker container, still Mach-O executable format?

问题

我真的需要一些帮助。我正在尝试使用标准的golang:1.5 Docker镜像构建一个Go二进制文件,然后将该二进制文件从容器中复制出来,并放入一个基于busybox的新的最小化Docker容器中。使用Docker挂载卷从容器中提取二进制文件。到目前为止,我遇到了两个问题。

  1. 主机上生成的二进制文件(随后复制到第二个容器中)在运行file命令时仍然显示为Mach-O 64位可执行文件。Docker容器是否以某种方式从主机获取GOOS和GOARCH?

  2. 当手动运行带有bash的容器并构建Go二进制文件时,它现在显示为ELF可执行文件,但是它是动态链接的。我以为默认情况下构建的是静态链接的二进制文件?也许我在这个假设上错了。

非常感谢您提供的任何帮助。

编辑:以下是我使用的命令。希望这样更清楚一些。

## golang:1.5基础镜像,WORKDIR设置为$GOPATH/src/myproject,项目的源代码在创建'mybuild_img' Docker镜像时添加进去了
## GOPATH在golang镜像中自动设置。
docker run -i -v `pwd`/jenkins/out:$GOPATH/src/myproject/jenkins/out mybuild_img:latest bash -c 'go build && cp myproject ./jenkins/out'

容器运行完成后,我在./jenkins/out/中得到了一个Mach-O 64位可执行文件。我不确定这是否是docker-machine/boot2docker之类的奇怪行为。看起来非常奇怪。我已经确认在执行go build命令之前设置GOOS=linux GOARCH=amd64,然后我确实得到了正确类型的可执行文件。只是想弄清楚这里发生了什么。

英文:

I could really use some help here. What I am trying to do is use the standard golang:1.5 Docker image to build a Go binary, then copy that binary out of the container and into a new minimal Docker container based on busybox. The binary is pulled out of the container using a Docker mounted volume. There are two problems so far that I have run into.

  1. The resulting binary on the host (and subsequently copied into the second container) still seems to be a Mach-O 64-bit executable when running the file command. Is the Docker container somehow getting GOOS and GOARCH from the host?

  2. When manually running the container with bash and building the Go binary, it now says it is an ELF executable but it is dynamically linked. I thought by default built statically linked binaries? I could just be wrong in this assumption.

Thanks in advance for any help you can provide.

EDIT: Here are the commands I am using. Hopefully this makes it a bit more clear

## golang:1.5 base image with WORKDIR set to $GOPATH/src/myproject the source
## for the project was added in when creating the 'mybuild_img' docker image
## GOPATH is set automatically in the golang image.
docker run -i -v `pwd`/jenkins/out:$GOPATH/src/myproject/jenkins/out mybuild_img:latest bash -c 'go build && cp myproject ./jenkins/out'

Once the container is done running I have a Mach-O 64-bit executable in ./jenkins/out/. I'm not sure if this is some kind of weird behavior with docker-machine/boot2docker or anything like that. Just seems really weird. I have confirmed that if i set GOOS=linux GOARCH=amd64 before the go build command, then I do get an executable of the correct type. Just trying to figure out what is going on here.

答案1

得分: 3

看起来你仍然在绑定一些C库。当将Go可执行文件移动到超小型容器时,这是一个常见的问题。你可以通过将这些绑定的库合并到可执行文件中来解决这个问题,方法是将
go build
改为
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . 你可以在Codeship的博客上找到更多关于这个问题以及它与最小化Docker构建的相关信息。

英文:

It looks like you are still binding to some C libraries. This is a common problem when moving a Go executable to a super minimal container. You can roll these bound libraries into your executable by changing
go build
to
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . You can find some more information on this problem and how it relates to minimal docker builds at Codeship's blog.

huangapple
  • 本文由 发表于 2015年11月6日 04:17:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/33553993.html
匿名

发表评论

匿名网友

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

确定