2016-08-10 44 views
1

我有几个码头集装箱,可以在一台机器上一起运行。一个绑定到端口80,另一个连接到一个neo4j容器,它也被启动。其他的是为了容器间的工作(我没有建立它们,但我必须承载它们)。我有一个docker swarm setup,其中有docker engine 1.12和一个progrium/consul cluster,它们在群体中的3台机器上。 consul集群可以看到所有的容器,并且它们在使用刚刚运行的-d(在提到的每个主机上)时都可以工作。只要我把它们中的任何一个作为“服务”出现,它们就不能再进行交流。我试过创建一个新的覆盖网络,但它没有影响。码头集装箱与群体通信问题

我也尝试运行绑定到端口80的一个容器作为所有其他系统作为服务运行的系统上的单独容器。 Docker inspect将它们全部显示在同一个172.17.0.0网络上。

我真的可以使用一些想法来看看。谢谢。


首先,我加载的Neo4j与:

docker run -d -e "CONSULJOIN=172.17.0.2" -e "NEO4J_HOST=172.17.0.4" \ 
    -e "NEO4J_PASSWORD=$NEO4J_PASS" container 

当代替docker run -d我使用:

docker run -d -p 192.168.2.201:7474:7474 \ 
    --volume=$HOME/neo4j/data:/data neo4j:3.0 

接着,随后的容器上的搬运工群使用加入一个领事簇docker create service,期望的是,如果我用192.168.2.201替换neo4j IP,它应该可以工作。

我还使用了覆盖网络的尝试:

docker network create -d overlay my-net 

而且包括--net =我网在泊坞窗服务命令。我不知道什么时候我会有时间进一步调试,但如果这足以至少告诉我我做错了什么会很好。如果没有,我会尽量在时间允许的情况下获取更多信息。

+0

请包括您正在运行的命令,包括网络和服务创建命令以及任何调试输出。 – BMitch

+0

所以这些系统在内部虚拟机上。首先,我加载neo4j:docker run -d -p 192.168.2.201:7474:7474 --volume = $ HOME/neo4j/data:/ data neo4j:3.0。然后,后续容器加入docker swarm上的consul集群,使用:docker run -d -e“CONSULJOIN = 172.17.0.2”-e“NEO4J_HOST = 172.17.0.4”-e“NEO4J_PASSWORD = $ NEO4J_PASS”容器。当代替docker运行-d我使用docker创建服务时,期望的是如果我用192.168.2.201替换neo4j IP,它应该可以工作。对不起,我也应该说,虽然我已经在Linux管理一段时间了,但我对docker很陌生。 –

+0

我已经用上面的评论更新了问题。你还可以使用你尝试的网络创建命令进行编辑吗?在封面之下,Docker正在创建桥接网络,并使用iptables控制访问,因此您应该可以使用标准Linux工具集进行调试。使用'docker exec -it /bin/bash'连接到任何容器中的bash shell以进一步调试。 – BMitch

回答

2

您不应该指定IP地址来查找群集上的服务。它可能位于群集中的任何机器上,除非您添加约束以将其放置在特定机器上。

创建网络覆盖图之后,您可以通过容器/服务名称而不是特定IP地址来引用服务。例如,在返回到您的应用程序之前,通过一个简单的示例工作。

这是假设你已经创建了群群已经:

创建网络覆盖

docker network create --driver overlay my-app-network 

启动一个简单的Redis服务

docker service create --replicas 1 --network my-app-network \ 
    --name demo-redis redis 

创建一个虚拟服务我们将登录进一步探索:

docker service create --replicas 1 --network my-app-network \ 
--name demo-alpine alpine /bin/sh -c "trap 'exit 0' INT TERM; while true; do echo Hello World; sleep 10; done" 

注:在这一点上,我们已经创建了一个容器,它并没有真正做什么,但我们会登录到它,所以我们可以探索交互式看看是怎么回事。

找到演示高山服务上

docker service ps demo-alpine #this will report which node is running the container 

SSH到节点运行的运行演示高山,重视它节点的外壳

docker ps #lists all the running containers on that node, find the container ID of demo-alpine 

docker exec -i -t <container id> /bin/sh 

#install python,pip and redis(for python) in your demo-alpine container 
apk update 
apk add python 
apk add py-pip 
pip install redis 

创建通过容器/服务名称打你的redis服务的脚本 vi test.py并粘贴如下所示的内容:

import redis 
import time 

loopy = True 

while loopy == True: 
    # I'm creating the connection each time so we can see the change when we scale the Redis service 
    # and the new service is brought online; connections should start rotating through the scaled Redis servers. 
    # If one uses a Redis connection scoped outside of the loop then it would remain connected to the first Redis 
    # service and we wouldn't see the new one come online. 

    r = redis.StrictRedis(host='demo-redis', port=6379, db=0) 
    r.incr('counter') 
    print(r.get('counter')) 
    time.sleep(3) 

运行从您的演示高山容器

python test.py 

请注意,我已经通过它的容器/服务名称不受IP引用Redis的服务,因为它可以在任何地方内的脚本在集群上。你应该开始看到增加的值打印到屏幕上。

为了更好玩,如果它为您工作,请缩放redis服务以查看它是否扩展到已经运行的Python脚本。

SSH从另一终端会话管理器节点,这样你就不会停止您的演示高山会议

docker service scale demo-redis=3 

你应该看到一个新的增量来自新缩放redis的服务价值打印屏幕并且群集应该将请求循环到每个新创建的redis服务。同步数据是另一回事 - 但这不是快速演示的重点。

此时,您应该可以返回到您的应用程序并使其在集群上运行。您可能必须更改代码才能引用容器名称而不是IP地址,但这是在集群上运行它的要点;它可能在任何地方。

+1

谢谢!我们将分析这一点并试图改变我们如何对其他容器进行调用。我是一个老派的庞然大物的系统家伙,所以我只是花点时间来围绕集装箱式的做事方式。 –

+0

我的荣幸。我总是欣赏一个相对端到端的例子,因为通过一个简单的例子,后面的例子可以更轻松地整合自己的工作。请注意,我只是在修改服务的最后一个声明中修正了一个错误。我最初把命令的输出而不是命令 - 现在已经修复了。我还在Github账户上写下了这些信息,并计划扩展它。 https://github.com/ctownsen357/docker-swarm-demo –