事情是这样的,我用了别人的一个Go语言写的程序,魔改了一下,在ubuntu上编译,丢到alpine里跑。
本来应该是一切顺利,可以我把容器运行起来后直接退出了,查看log发现报错”命令未找到“。情况如下:1
2
3
4
5
6
7
8
9
10
11/app # ls -l
total 17856
-rw-r--r-- 1 root root 871 Jun 11 17:30 config.json
-rwxr-xr-x 1 root root 73 Jun 11 17:19 deploy.sh
-rwxr-xr-x 1 root root 18276352 Jun 11 18:19 v
/app # file v
v: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, stripped
/app # ./v
sh: ./v: not found
/app # /app/v
sh: /app/v: not found
这不是见了鬼了吗?这个程序明明在这里啊,怎么没找到呢?最开始被这迷惑的报错信息给影响了,都没往编译问题上去想。我以为是文件损坏了,计算一下校验和发现并不是。然后我以“golang alpine not found” 为关键词搜索,发现有人说是sh脚本文件中crlf换行符的问题。
照着别人说的把deploy.sh中crlf改成unix的lf,问题依旧,于是我翻到搜索结果的第二页,有人说是alpine库文件的问题,又照着别人说的运行命令:1
2/app # mkdir /lib64
/app # ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
终于,错误信息变了,变成了:1
2
3/app # ./v
Error relocating ./v: __vfprintf_chk: symbol not found
Error relocating ./v: __fprintf_chk: symbol not found
这下我就确定了,是编译环境和运行环境库不一致的问题。然后仔细对比了我和原作者构建脚本的差异,果然粗心大意少配置了个环境变量:1
2env:
CGO_ENABLE: 0
至此,问题解决,花了两个多小时。回顾一下,这么简单的问题本应该是分分钟解决的,花了这么久不应该,但这也并不全是我的粗心,主要还是被报错信息误导了。
记录一下,方便同样“粗心”的朋友^_^。