docker container vs swarm communication issue

时间:2016-08-10 20:25:20

标签: docker neo4j docker-swarm

我有几个docker容器可以在一台机器上一起运行。一个绑定到端口80,另一个连接到也旋转的neo4j容器。其他的是集装箱间的工作(我没有建造它们,但我必须托管它们)。我有一个docker swarm设置与docker引擎1.12和一个progrium / consul集群跨越swarm中的3台机器。 consul集群可以看到所有容器,并且只使用run -d(在所提到的每个主机上)它们都可以工作。一旦我将它们中的任何一个作为"服务",它们就无法再进行通信。我尝试过创建一个新的覆盖网络,但没有任何影响。

我还尝试将一个绑定到端口80的容器作为单个容器运行在其他系统上,其他系统作为服务运行。 Docker inspect在同一个172.17.0.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" container

当我使用docker run -d代替docker create service时,期望的是如果我用192.168.2.201替换neo4j IP,它应该可以工作。

我也尝试过使用覆盖网络:

docker network create -d overlay my-net

并在docker service命令中包含了--net = my-net。我不知道我什么时候有时间进一步调试,但如果这足以告诉我我做错了什么就会很好。如果没有,我会在时间允许的情况下尝试获取更多信息。

1 个答案:

答案 0 :(得分: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"

注意:此时我们创建的容器并没有真正做任何事情,但我们会登录它,以便我们可以互动探索,看看是什么正在继续。

上找到运行demo-alpine服务的节点
docker service ps demo-alpine #this will report which node is running the container

SSH进入运行demo-alpine的节点并附加到它的shell

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)

从您的demo-alpine容器中运行脚本

python test.py

请注意,我已经通过其容器/服务名称而不是IP引用了redis服务,因为它可能位于群集的任何位置。您应该开始看到增量值打印到屏幕。

为了获得额外的乐趣,如果它适合您,请扩展redis服务以使其扩展到已经运行的Python脚本。

ssh从另一个终端会话进入经理节点,因此您不会停止您的演示 - 高山会议

docker service scale demo-redis=3

您应该开始看到从新扩展的redis服务打印到屏幕的新增量值,并且群集应该对每个新创建的redis服务进行循环请求。同步这些数据是另一个故事 - 但这不是快速演示的重点。

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