对于我的一个家庭项目,我决定使用docker容器和fig进行编排(第一次使用这些工具)。
这是我的fig.yaml:
rabbitmq:
image: dockerfile/rabbitmq:latest
mongodb:
image: mongo
app:
build: .
command: python /code/app/main.py
links:
- rabbitmq
- mongodb
volumes:
- .:/code
Rabbitmq的开始时间比我的应用程序的加载时间慢得多。即使rabbitmq容器首先开始加载(因为它在应用程序链接中),当我的应用程序尝试连接到rabbitmq服务器时,它还没有可用(它肯定会加载计时问题,因为如果我只是插入睡眠连接到rabbitmq之前的5秒钟 - 一切正常)是否有一些解决加载时间同步问题的标准方法?
感谢。
答案 0 :(得分:6)
我认为没有一种标准方法可以解决这个问题,但这是一个已知问题,有些人有可接受的解决方法。
Docker问题跟踪器上有a proposal关于在正在侦听暴露的端口之前没有将容器视为已启动的问题。然而,由于其他地方会产生其他问题,它可能不会被接受。同一主题也有fig proposal。
简单的解决方案是像@jcortejoso所说的那样睡觉。来自http://blog.chmouel.com/2014/11/04/avoiding-race-conditions-between-containers-with-docker-and-fig/的示例:
function check_up() {
service=$1
host=$2
port=$3
max=13 # 1 minute
counter=1
while true;do
python -c "import socket;s = socket.socket(socket.AF_INET, socket.SOCK_STREAM);s.connect(('$host', $port))" \
>/dev/null 2>/dev/null && break || \
echo "Waiting that $service on ${host}:${port} is started (sleeping for 5)"
if [[ ${counter} == ${max} ]];then
echo "Could not connect to ${service} after some time"
echo "Investigate locally the logs with fig logs"
exit 1
fi
sleep 5
(( counter++ ))
done
}
然后在启动应用服务器之前使用check_up "DB Server" ${RABBITMQ_PORT_5672_TCP_ADDR} 5672
,如上面的链接所述。
另一种选择是使用docker-wait。在fig.yml
。
rabbitmq:
image: dockerfile/rabbitmq:latest
mongodb:
image: mongo
rabbitmqready:
image: aanand/wait
links:
- rabbitmq
app:
build: .
command: python /code/app/main.py
links:
- rabbitmqready
- mongodb
volumes:
- .:/code
答案 1 :(得分:1)
我遇到的类似问题我使用CMD
中设置为Dockerfiles
的自定义脚本解决了这个问题。然后,您可以运行您希望的任何检查命令(sleep
一段时间,或等待服务正在监听,例如)。我认为没有一种标准的方法可以做到这一点,无论如何我认为最好的方法是应用程序运行可以要求外部服务启动并运行,并连接到它们,但这在大多数情况下是不可能的例。
答案 2 :(得分:0)
为了测试我们的CI,我们构建了一个small utility,可以在Docker容器中使用,以等待链接服务准备就绪。它会自动从其环境变量中查找所有链接的TCP服务,并重复并同时尝试建立TCP连接,直到成功或超时为止。
我们还写了blog post describing why we built it and how we use it。