Docker群集networkingdebugging

我已经在使用docker swarm和stack的docker中创build了一个服务,但是我的应用程序运行在一个服务副本上不能连接到其他副本。

这里是更多的细节。 我有三个节点:一个pipe理员和两个工人。 在与pipe理器相同的节点上,我运行一个registry,这是我使用docker stack部署到worker的映像的源代码。

以下是我的Docker堆栈configuration文件的外观:

version: "3.2" services: compute: image: openmpi-docker.registry:443/openmpi ports: - "2222:22" deploy: replicas: 4 restart_policy: condition: none placement: constraints: [node.role != manager] networks: - openmpi-network networks: openmpi-network: driver: overlay attachable: true 

正如你可以猜到的图像包含openmpi分布。 它启动sshd并打开端口22。

我可以使用以下命令连接到其中一个服务:

 ssh -p 2222 -i ./user-ssh/docker_id <worker node> 

然后我尝试运行一个简单的testing。 我想知道其他副本的IP地址是什么,并尝试通过ssh连接它们:

 for i in $(seq 3 6) ; do ssh 10.0.1.$i hostname ; done 

这工作正如所料,我看到4个不同的主机名。

所以我的下一个testing涉及mpi。

 mpirun -H 10.0.1.3,10.0.1.4,10.0.1.5,10.0.1.6 hostname 

这个命令应该完全一样,除了它应该使用mpirun而不是ssh。 但不知何故,这失败了。

所以我想看看mpirun使用strace挂起的位置,但是使用SYS_PTRACEfunction是不可能的。 如果你使用swarm,似乎没有办法设置它。 所以我尝试创build另一个容器,不在swarm中,它共享相同的覆盖networking:

 docker run --network openmpi_openmpi-network --rm -it openmpi-docker.registry:443/openmpi bash 

这里openmpi_openmpi-network是由“docker stack”创build的networking名称。 原来我打算用“–privileged”来运行它,但事实certificate,我并不需要它。

然后,我从根目录切换到普通用户,并使用相同的IP地址运行相同的mpi命令,命令工作。 所以我不会遇到同样的问题。

在其他情况下,类似的问题的解决scheme只是closures防火墙,但我敢肯定,我没有它在容器内。 我从debian:9镜像中自己创build了镜像,我安装的唯一服务器是sshd。 而这仍然不能解释在swarm中启动容器和使用docker run启动容器的区别。

这让我感到惊讶。 首先,我该如何debugging这样的问题? 其次,在群体中启动服务和在networking上手动启动它们之间有什么不同?

如果你能帮我回答这两个问题,我将不胜感激。

更新

我试着用“–mca oob_base_verbose 100”运行mpirun,得到如下结果。 日志比较长,但关键的区别在于发起通信的节点的行为。

我在启动器节点的某个mpirun的工作日志打印下面:

 ... [3365816c2c1e:00033] [[39982,0],2] oob:tcp:init adding 10.0.1.4 to our list of V4 connections [3365816c2c1e:00033] [[39982,0],2] TCP STARTUP [3365816c2c1e:00033] [[39982,0],2] attempting to bind to IPv4 port 0 [3365816c2c1e:00033] [[39982,0],2] assigned IPv4 port 57161 [3365816c2c1e:00033] mca:oob:select: Adding component to end [3365816c2c1e:00033] mca:oob:select: checking available component usock [3365816c2c1e:00033] mca:oob:select: Querying component [usock] [3365816c2c1e:00033] oob:usock: component_available called [3365816c2c1e:00033] [[39982,0],2] USOCK STARTUP [3365816c2c1e:00033] SUNPATH: /tmp/openmpi-sessions-1000@3365816c2c1e_0/39982/0/usock [3365816c2c1e:00033] mca:oob:select: Inserting component [3365816c2c1e:00033] mca:oob:select: Found 2 active transports <Log output from other nodes> [3365816c2c1e:00033] [[39982,0],2]: set_addr to uri 2620260352.0;usock;tcp://10.0.1.7,172.18.0.5:48695 [3365816c2c1e:00033] [[39982,0],2]:set_addr checking if peer [[39982,0],0] is reachable via component usock [3365816c2c1e:00033] [[39982,0],2]: peer [[39982,0],0] is NOT reachable via component usock [3365816c2c1e:00033] [[39982,0],2]:set_addr checking if peer [[39982,0],0] is reachable via component tcp [3365816c2c1e:00033] [[39982,0],2] oob:tcp: ignoring address usock [3365816c2c1e:00033] [[39982,0],2] oob:tcp: working peer [[39982,0],0] address tcp://10.0.1.7,172.18.0.5:48695 [3365816c2c1e:00033] [[39982,0],2] PASSING ADDR 10.0.1.7 TO MODULE [3365816c2c1e:00033] [[39982,0],2]:tcp set addr for peer [[39982,0],0] [3365816c2c1e:00033] [[39982,0],2] PASSING ADDR 172.18.0.5 TO MODULE [3365816c2c1e:00033] [[39982,0],2]:tcp set addr for peer [[39982,0],0] ... 

但是在非工作情况下,发起者节点在“发现2主动传输”消息处停止并且从不打印其他东西。

更新2

我还发现,如果添加“–mca oob_tcp_if_include 10.0.1.0/24”,则主机名可以工作,以便完整的命令是:

 mpirun -H 10.0.1.3,10.0.1.4,10.0.1.5,10.0.1.6 --mca oob_tcp_if_include 10.0.1.0/24 hostname 

我仍然不明白为什么以及如何避免指定子网的需要。