最近有一个用户反馈, 他使用 golang:1.13.1-alpine3.10 这个镜像来编译的可执行程序无法在云函数的环境运行, 报错信息如下:
fork/exec /var/user/main: no such file or directory在 macOS 下编译则没有这个问题
还未来得及定位问题, 用户便反馈说换了一个镜像就没问题了, 于是没能获得更多信息
过了几天, 有一个同事在群里贴出了 Go 程序链接出错的信息, 看起来也是在 Alpine Linux 下编译的, 有人回复道 Alpine Linux 使用的不是 glibc
啊哈, 终于有线索了, 写代码验证一下
package main
import "fmt"
func main() {
fmt.Println("hello world")
}在 CentOS 上编译后, 使用 ldd 查看一下程序依赖哪些 .so(也可以使用 readelf -d)
$ ldd main
not a dynamic executable程序太简单了, 没有依赖动态库
搜索了一下, 发现 Go 的仓库有一个 issue #33019, 和我们的问题很类似
package main
import (
"net"
"fmt"
"os"
)
func main() {
ips, err := net.LookupIP("localhost")
if err != nil {
fmt.Fprintf(os.Stderr, "Could not get IPs: %v\n", err)
os.Exit(1)
}
for _, ip := range ips {
fmt.Printf("localhost. IN A %s\n", ip.String())
}
}编译这段代码, 再次使用 ldd 查看一下程序依赖哪些 .so
$ ldd main
linux-vdso.so.1 => (0x00007ffca89c9000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f6c4b4bd000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6c4b0f9000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f6c4aef5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6c4b6d9000)终于和 glibc 扯上关系了
使用 golang:1.13.1-alpine3.10 这个镜像重新编译一下这段代码, 看看结果有什么不同
$ docker run -v $PWD:/go/src/test -w /go/src/test golang:1.13.1-alpine3.10 go build -o main-alpine
$ ldd main-alpine
linux-vdso.so.1 => (0x00007ffe0055e000)
libc.musl-x86_64.so.1 => not found
libdl.so.2 => /lib64/libdl.so.2 (0x00007f2512754000)
libc.so.6 => /lib64/libc.so.6 (0x00007f2512390000)
/lib/ld-musl-x86_64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f2512958000)可以看到, 缺失了 libc.musl-x86_64.so.1, 运行一下程序
$ ./main-alpine
-bash: ./main-alpine: /lib/ld-musl-x86_64.so.1: bad ELF interpreter: No such file or directoryNo such file or directory 正是本文一开始提到的出错信息
(完整的出错信息可通过使用 Go 的 os/exec 包启动 main-alpine 获得)
问题的原因在于云函数的运行环境(CentOS)提供的是 glibc, 而 Alpine Linux 却是 musl libc. 因而使用 golang:1.13.1-alpine3.10 这个镜像编译出来的程序如果依赖于 musl libc, 则会在程序加载的时候找不到所需的动态库
解决问题的方法很简单, 只需将镜像换成 golang:<version> 的版本(如golang:1.12)即可
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。