docker alpine镜像中遇到 sh: xxx: not found
如题,在docker-compose 编排Go应用的时候alphine容器出现可执行文件不存在的问题。猜测:一:难道文件在容器中没有执行权限?针对这个操作,我在command命令中加入了chmod 700运行结果:not found …二:由于可执行文件是通过volume映射过去的,莫非哪里出了问题导致容器中不存在该文件?为了验证上面的想法于是在command命令中加上了ls -l,运行结果显示是
如题,在docker-compose 编排Go应用的时候alphine容器出现可执行文件不存在的问题。
猜测:
一:难道文件在容器中没有执行权限?
针对这个操作,我在command命令中加入了chmod 700
运行结果:not found …
二:由于可执行文件是通过volume映射过去的,莫非哪里出了问题导致容器中不存在该文件?
为了验证上面的想法于是在command命令中加上了ls -l,运行结果显示是存在该文件的。
三:莫非是alphine的问题??
于是我直接将整个alphine镜像换成的golang,运行发现没有再报not fount异常。
这样基本就可以断定是alphine镜像的问题了,但是为什么会这样呢,经过一番搜索引擎操作,发现这样的原因:
Alpine 使用的标准库与大多数发行版不同,它使用的是 musl libc,这个库相比于 glibc 更小、更简单、更安全,但是与大家常用的标准库 glibc 并不兼容。
我们知道正常的golang应用的编译一般上会将大部分的依赖打包进二进制文件,但是某些包是需要依赖系统标准库的,只要代码中有使用到这样类似的包,应用就会去调用系统中对应的库,Golang使用cgo(允许go调用c)机制去实现这样的调取过程。
解决办法
所以在知道原因后我们也就有些解决办法了。
一:不要直接使用alpine:latest镜像,而是使用官方给我们提供的golang:alpine版本(没有解决,照样会报not found异常-2021.6.14更新)
二:使用静态编译,静态编译将不使用动态链接库,所以可以在alpine:latest中使用。
三:增加软连接
mkdir /lib64
ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
其实在第三点的时候我们知道musl跟glic是兼容的所以采取增加软连接后就可以使用。那么如何增加软连接呢,难道是在容器创建了之后像第三点一样进入容器手动创建?如果有多个那不是得麻烦死。所以最好的办法是我们使用Dockerfile创建一个符合要求的镜像,然后我们再使用这个二次创建的镜像来开发。如:
//Dockerfile文件
FROM alpine:3.14
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
创建好Dockerfile文件后编译成镜像:
sudo docker build -t my-alpine:v1.0 .
然后在docker-compose中使用
//docker-compose.yml文件
version: "3"
services:
app:
image: my-alpine:v1.0
volumes:
- /work/testmysql/:/app
working_dir: /app
command: ./app
ports:
- 5885:5885
这样就以后就可以直接使用这个编译好的镜像了。
当然也可以直接使用我打包好的镜像:
docker pull nelsonjs/glibc-alpine:v1.0
更多推荐
所有评论(0)