我目前正在使用分子测试Ansible角色。 基本上,Molecule会启动一个与Ansible兼容的容器并在其上运行角色。
为了测试容器,分子还使用Testinfra嵌入了单元测试。 python单元测试从容器内运行,因此您可以检查角色的符合性。
当我在基于Nginx的角色上工作时,单元测试之一就是发出一个curl http://localhost:80
我的确收到以下错误消息:
卷曲:(7)无法连接到本地主机端口80:连接被拒绝
当我:
vagrant ssh
curl http://localhost
命令nginx正确回答。
因此,我相信:
我的问题如下:
答案 0 :(得分:1)
默认情况下,Docker容器在其自己的网络名称空间中启动。该名称空间包括一个单独的回送接口(127.0.0.1),该接口与主机和任何其他容器上的同一接口不同。如果要从另一个容器或通过主机上已发布的端口访问应用程序,则需要侦听所有接口(0.0.0.0),而不是回送接口。
我经常看到的另一个问题是在连接的某一层(主机或容器内部),“ localhost”名称映射到/ etc / host中的::1
的IPv6值。文件,并且在该连接中的某个位置只有IPv4值有效(端口发布的位置,应用程序正在侦听或者主机或docker引擎上未启用IPv6)。因此,请确保尝试直接连接到IPv4地址127.0.0.1,以消除任何潜在的IPv6问题。
关于curl
命令及其纠正方法,如果没有更多有关如何运行curl(在单独的容器中),如何运行应用程序以及如何进行卷曲的详细信息,我将无法回答。两个在网络上连接(您是否在docker中创建了一个新网络以供您的应用程序和单元测试运行)。典型的解决方案是在docker中创建一个新网络,在该网络上运行两个容器,然后通过docker包含的DNS连接到目标的容器或服务名称,例如curl http://my_app/
。
编辑:根据注释,如果您的应用程序和curl命令都在同一个容器中运行,那么curl http://127.0.0.1/
应该可以工作。我知道curl
并不需要进行任何更改,以使其可以在容器内运行而不是在VM上运行。您看到的错误很可能是由于应用程序未按预期启动和侦听端口,可能是在curl命令运行得太早的竞争条件下,或者该工具的工作原理基本假设不正确。首先更改单元测试以验证应用程序已启动并运行,并使用ps -ef
和ss -lt
之类的命令在端口上进行监听。
答案 1 :(得分:0)
实际上,它与Docker和Vagrant之间的差异(即容器与VM)无关。
testInfra代码实际上是从容器/ VM外部运行的,因此subprocess.call(['curl', 'http://localhost'])
失败。
为了从容器/ VM运行命令,我应该使用:
host.check_output('curl http://localhost')