如何检查应用程序是否在容器内部启动
我们有一个集成testing套件,在启动任何testing用例之前启动容器。 我们曾经在执行任何testing之前等待端口可用,这表示应用程序已准备好接收请求。 但是,1.7.1版本的端口在应用程序甚至在容器内部开始之前即时可用。
有没有一个选项来推迟docker端口转发,直到端口在容器内打开?
还是有其他可靠的方法来检查应用程序是否已经开始在容器内?
但是,1.7.1版本的端口在应用程序甚至在容器内部开始之前即时可用。
我不认为这是真的 – 也就是说,这取决于你如何尝试联系一个港口。 例如,考虑一个像这样的容器:
$ docker run -it -p 8888:80 alpine sh
这里我们已经build立了从主机端口8888到容器端口80的端口,但是我们还没有在容器内设置任何东西来监听。 尝试连接到localhost
上的端口8888导致成功的连接立即closures:
$ telnet localhost 8888 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Connection closed by foreign host.
这正是你正在经历的。 但是如果不是localhost
使用主机的IP地址,我们会看到不同的行为:
$ telnet 192.168.1.55 8888 Trying 192.168.1.55... telnet: connect to address 192.168.1.55: Connection refused
如果在容器内,我启动一个Web服务器:
/ # apk add mini_httpd [...] / # mini_httpd mini_httpd: started as root without requesting chroot(), warning only
然后我可以成功连接:
$ telnet 192.168.1.55 8888 Trying 192.168.1.55... Connected to 192.168.1.55. Escape character is '^]'.
发生这种情况是因为通过localhost
连接是由端口8888绑定的Docker用户级代理处理的:
# netstat -tlnp | grep 8888 tcp6 0 0 :::8888 :::* LISTEN 2809/docker-proxy
但是到另一个接口ip的连接(以及源自另一个主机的任何连接)将由iptables nat
表中的规则处理:
# iptables -t nat -S DOCKER -N DOCKER -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8888 -j DNAT --to-destination 172.17.0.138:80
还是有其他可靠的方法来检查应用程序是否已经开始在容器内?
你有几个select:
-
只需直接连接到容器IP,而不是依靠端口转发。 例如,在上面的例子中,我启动的容器被分配了地址172.17.0.138。 我可以连接到,而不是主机地址。 很容易finddocker集装箱的IP地址:
$ docker inspect –format'{{.NetworkSettings.IPAddress}}'my-container 172.17.0.138
-
等到你成功连接到你的应用程序。 在这个例子中,我最终创build了一个Web服务器,我可以等到
curl
成功连接:while ! curl -sf http://localhost:8888/; do sleep 1 done
如果无法成功获取URL,
-f
标志告诉curl退出并显示错误代码。