如何检查应用程序是否在容器内部启动

我们有一个集成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退出并显示错误代码。