问题
我们在使用Alpine的时候很有可能会使用到以前在其他操作系统中编译好的一些工具,比如日志切割工具cronolog,我们将它拷贝到Alpine镜像容器中使用,但是问题来了,使用的时候说该工具找不到 not found
演示
为了更好理解,从头到尾演示一下此问题,在我的宿主机上有一个已经编译好的cronolog(日志切割工具的安装不在本文讲解,本文以cronolog演示not found问题也是为了后面文章需要做准备),拷贝到Alpine镜像容器中。
[root@node01 ~]# which cronolog
/usr/local/sbin/cronolog
# 拷贝到容器
[root@node01 ~]# docker cp /usr/local/sbin/cronolog alpine:/root
容器中查看,已经有了此文件
~ # ls
cronolog tzdata
在容器中使用cronolog,下面一段shell语句意思是每隔一秒钟打印一次test... 并且通过日志切割工具cronolog按小时保存在不同文件中。
while true; do echo 'test...';sleep 1;done|/root/cronolog /root/test-%m%d%H.log
# 报错了
~ # while true; do echo 'test...';sleep 1;done | /root/cronolog /root/test-%m%d%H.log
/bin/sh: /root/cronolog: not found
很是奇怪,明明就在这个目录,文件权限也是可执行的。就是not found。将cronolog移到path路径下试试。
mv /root/cronolog /bin
## 查找一下,没问题,已经在PATH下
~ # which cronolog
/bin/cronolog
## 再次执行 还是 not found
~ # while true; do echo 'test...';sleep 1;done | cronolog /root/test-%m%d%H.log
/bin/sh: cronolog: not found
原因
一般来说linux下编译二进制文件,所需要的动态链接库是在/lib64目录下,但是Alpine使用的是musl libc并不是标准的glibc,所以动态链接库的位置不一样,在alpine中没有lib64目录,动态链接库在lib目录下。
在centos下使用ldd查看下cronolog依赖库如下,依赖于/lib64/ld-linux-x86-64.so.2
[root@node01 cronolog]# ldd /usr/local/sbin/cronolog
linux-vdso.so.1 => (0x00007ffdceb9d000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3908f6a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3909338000)
容器中执行,明显也是依赖于 /lib64/ld-linux-x86-64.so.2
~ # ldd /bin/cronolog
/lib64/ld-linux-x86-64.so.2 (0x7f5fac40f000)
libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f5fac40f000)
解决办法
在上一篇文章我有提到过
Alpine使用的c库使用mini版的musl libc与其他Linux发行版使用的gnu libc不一样。虽说号称兼容,但也只是部分兼容了,缺啥补啥就是,通过一个软链接来关联。
## 创建一个软连接
mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
## 再次执行
~ # while true; do echo 'test...';sleep 1;done| cronolog /root/test-%m%d%H.log
## 已经生成日志文件
~ # ls
test-120617.log tzdata
~ # cat test-120617.log
test...
欢迎关注,学习不迷路!