我使用docker swarm和stack在docker中创建了一个服务,但不知何故,我在服务副本中运行的应用程序无法连接到其他副本。
这里有更多细节。我有三个节点:一个管理和两个工作。在与管理器相同的节点上,我运行一个注册表,这是我使用docker stack部署到工作者的映像的源。
以下是我的docker堆栈配置文件的样子:
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>
然后我尝试进行一个简单的测试。我弄清楚其他副本的IP地址是什么,并尝试通过ssh连接它们:
for i in $(seq 3 6) ; do ssh 10.0.1.$i hostname ; done
这按预期工作我看到4种不同的主机名。
所以我的下一个测试涉及到mpi。
mpirun -H 10.0.1.3,10.0.1.4,10.0.1.5,10.0.1.6 hostname
该命令应该完全相同,除了它应该使用mpirun而不是ssh。但不知怎的,这失败了。
所以我想看看使用strace确切地挂起mpirun的位置,但是使用SYS_PTRACE功能是不可能的。如果你使用swarm,似乎没有办法设置它。所以我尝试创建另一个容器,而不是swarm,它共享相同的覆盖网络:
docker run --network openmpi_openmpi-network --rm -it openmpi-docker.registry:443/openmpi bash
此处openmpi_openmpi-network
是&#34; docker stack&#34;创建的网络的名称。最初我计划用&#34; - 特权&#34;来运行它,但事实证明我不需要它。
然后我从root用户切换到普通用户并使用相同的IP地址运行完全相同的mpi命令,该命令有效。所以我不会遇到同样的问题。
在其他情况下,类似问题的解决方案只是关闭防火墙,但我很确定我没有在容器内部。我自己从debian创建了图像:9图像,我安装的唯一服务器是sshd。而且这还不能解释在群集中启动容器和使用docker run
启动容器之间的区别。
这让我很奇怪。首先我该如何调试这类问题?第二,在群组中启动服务和手动启动网络之间有什么不同呢?
如果你能帮助我回答这两个问题,我将不胜感激。
更新
我尝试用&#34;运行mpirun - mca oob_base_verbose 100&#34;得到以下结果。 logs相对较长,但关键区别在于启动通信的节点的行为。
我在启动器节点的某个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]
...
但是在非工作情况下,启动器节点停在&#34;找到2个活动传输&#34;消息,永远不会打印任何其他内容。
更新2
我还想到,如果我添加&#34; - 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
我仍然不明白为什么以及如何避免指定子网的需要。