Docker exec /xxx: no such file or directory 与动态链接
问题描述
今天在更新 Docker 镜像,想着指定工作目录,这样方便后续挂载 VOLUMN 后可以方便地备份容器数据。
于是就加了一条:WORKDIR /data
之后离谱的事情就来了,容器启动不了了,报错:exec /gin-template: no such file or directory
由于网络问题,我本地没构建成功,只能用 GitHub Actions 去构建,每次调试都要花好久,真的烦。
原本的容器镜像用的还是 scratch
,没有 shell,还没办法进去调试。
无奈之下只得又改成 alpine,进去调试:
docker run -it -p 3000:3000 --entrypoint /bin/sh -v /home/ubuntu/tmp:/data justsong/gin-template
然后就出现了下面这种离谱的事情:
/data # cd ..
/ # ls
bin etc lib opt run sys var
data gin-template media proc sbin tmp
dev home mnt root srv usr
/ # ./gin-template
/bin/sh: ./gin-template: not found
/ # /gin-template
/bin/sh: /gin-template: not found
/ # /bin/ls
bin etc lib opt run sys var
data gin-template media proc sbin tmp
dev home mnt root srv usr
/ #
问题解决
实际上这根本不是容器的问题,而是程序不是静态链接,因为缺乏动态链接库导致的问题。
这都要怪 /bin/sh
的报错太误导人了。
查看文件类型:
$ file gin-template
gin-template: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked,
interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=adee9e6b844a3a13f24ef4a93a558e807ac8ff28, for GNU/Linux 3.2.0, stripped
而 Go File 之所以能运行是因为是静态链接:
$ file go-file
go-file: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked,
BuildID[sha1]=3a3e8e78bcbf29aad42138cf5332f6024c8df02f, for GNU/Linux 3.2.0, stripped
使用 ldd 查看具体的依赖:
$ ldd gin-template
linux-vdso.so.1 (0x00007fff1512d000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f3ae53c5000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f3ae53c0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3ae5198000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3ae53d6000)
解决方法就是静态链接打包可执行文件,或者运行镜像不要选 scratch
。