序
docker-compose 编排多个容器启动的时候,depends_on 只能影响容器的启动顺序,如果一个容器的程序必须依赖另外一个,就有可能出现依赖的程序还未启动而导致的问题...
问题描述
我遇到此问题是因为有一个.net的项目要一同部署到我们的集群中,此项目需要连接到我们eureka注册中心,但是它启动时只会连接一次注册中心,如果没有连接上就会报错停止工作,但是我无法修改此程序的代码。
所以就要想其他的办法解决。
首先docker中的程序启动必然会配置容器启动时执行的命令,这样才能启动容器中的程序,所以首先查看容器启动时候执行的内容。
inspect 可以查看容器的细节,找到 "Entrypoint" 这个属性。
docker inspect imageName
效果:
发现 Entryponint 只有一句
dotnet ***.dll --server.urls ...
大概是通过.dll动态库文件直接启动的。
要让命令在eureka工作后再启动,肯定要用shell脚本来解决了,查了下各种方案,比较靠谱的就是,利用nc命令判定eureka端口启动成功后再执行,nc 就是 netcat的缩写。
为了方便扩展,我创建了启动用的 start.sh脚本。
测试脚本
写了个非常简单的测试脚本
- 首先定义了waitPort方法
- 然后执行了waitPort方法 参数$1为地址,参数$2为端口
- waitPort方法中会检测 nc -vz $1 $2 的结果
- nc -vz $1 $2 的结果 为 不通则2秒后再试
- nc -vz可以检测这个地址的端口有没有通
- 通了就会往下走 echo 打印 ok!
#!/bin/bash
function waitPort() {
while ! nc -vz $1 $2; do
sleep 2
done
}
waitPort www.baidu.com 80
echo 'ok!'
设置sh的执行权限
chmod 744 start.sh
执行测试
./start.sh
放个错误域名测试不通的情况
#!/bin/bash
function waitPort() {
while ! nc -vz $1 $2; do
sleep 2
done
}
waitPort www.baidu.com22 80
echo 'ok!'
两秒重复一次, 工作正常.
改造start.sh和DockerFile
完全体start.sh
启动脚本做好了, 首先查看了此镜像的DockerFile , ENTRYPOINT 从原来的 dotnet ***.dll 替换为
ENTRYPOINT ["./start.sh"]
镜像的工作目录中放入了start.sh (记得设好执行权限)
执行测试了下,发现容器没有nc命令,所以还要再DockerFile中安装下
这边使用apt-get安装的 DockerFile 中 加上 RUN 配置。
RUN apt-get update
&& DEBIAN_FRONTEND=noninteractive apt-get install -y
netcat
完全体DockerFile
启动测试成功 后面就不展示啦~
本文由 考拉 创作,采用 知识共享署名4.0
国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Sep 16,2021