我试图在macOS上使用ZeroMQ和Docker网络设置一个玩具示例,其中
以下是我的设置:
1.我使用
serverd.py
向clientd.py
发送一条消息,客户端只需使用PUSH/PULL显示它。如果我在容器外部运行它们,它们可以正常工作,但是当我在单独的容器中运行时,我遇到了通信问题。尽管它们在同一桥接网络中,但似乎我的clientd.py
无法连接到容器名称。我尝试用serverd_dev_1
的分配IP地址替换主机名,但这也不起作用。以下是我的设置:
1.我使用
docker network create -d bridge mynet
创建了一个新网络。这是来自docker network inspect mynet
的输出:{
"Name": "mynet",
"Id": "cec7f8037c0ef173d9a9a66065bb46cb6a631fea1c0636876ccfe5a792f92412",
"Created": "2017-08-19T09:52:44.8034344Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"5fa8dc2f8059d675dfd3dc4f2e50265be99361cd8a8f2730eb273772c0148742": {
"Name": "serverd_dev_1",
"EndpointID": "3a62e82b1b34d5c08f2a9f340ff93aebd65c0f3dfde70e354819befe21422d0b",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"ec1e5f8c525ca8297611e02bcd3a64198fda3a07ce8ed82c0c4298609ba0357f": {
"Name": "clientd_dev_1",
"EndpointID": "a8ce6f178a225cb2d39ac0009e16c39abdd2dae02a65ba5fd073b7900f059bb8",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
我创建了像这样的serverd.py
和clientd.py
,并将它们与其Dockerfiles和docker-compose.yml文件放在不同的文件夹中:
serverd.py:
import zmq
import time
context = zmq.Context()
socket = context.socket(zmq.PUSH)
address = "tcp://127.0.0.1:5557"
socket.bind(address)
print("Sending to {}...".format(address))
while True:
message = socket.send_string("Got it!")
print("Sent message")
time.sleep(1)
clientd.py:
import zmq
context = zmq.Context()
socket = context.socket(zmq.PULL)
address = "tcp://serverd_dev_1:5557"
socket.connect(address)
print("Listening to {}...".format(address))
while True:
message = socket.recv_string()
print("Client got message! {}".format(message))
我有两个Dockerfile和docker-compose.yml:
服务器端的Dockerfile:
FROM python:3.6
RUN mkdir src
ADD serverd.py /src/
RUN pip install pyzmq
WORKDIR /src/
EXPOSE 5557
clientd.py的Dockerfile:
FROM python:3.6
RUN mkdir src
ADD clientd.py /src/
RUN pip install pyzmq
WORKDIR /src/
EXPOSE 5557
serverd.py 的 docker-compose.yml:
dev:
build: .
command: ["python", "-u", "./serverd.py"]
net: mynet
clientd.py 的 Docker Compose:
dev:
build: .
command: ["python", "-u", "./clientd.py"]
net: mynet
serverd.py
通过docker-compose up
正常启动:
发送到 tcp://127.0.0.1:5557...
clientd.py
无法像此方式启动,因为它找不到主机名tcp://serverd_dev_1:5557
。Attaching to countd_dev_1 dev_1 | Traceback (most recent call last): dev_1 | File "./countd.py", line 6, in <module> dev_1 | socket.connect(address) dev_1 | File "zmq/backend/cython/socket.pyx", line 528, in zmq.backend.cython.socket.Socket.connect (zmq/backend/cython/socket.c:5971) dev_1 | File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:10014) dev_1 | zmq.error.ZMQError: Invalid argument
如果我用
tcp://172.18.0.2:5557
替换URItcp://serverd_dev_1:5557
,程序不再崩溃,但是一直空闲而没有接收到任何来自服务器的消息。显然我做错了什么,但是我不确定具体是什么。我觉得我已经尽可能地按照Docker文档进行操作,非常感谢如果您有任何想法。
.bind()
端以IPv4绝对格式设置目标地址,例如address = "tcp://172.18.0.2:5557"
,以不依赖任何DNS解析,并将其用作客户端端口的.connect()
目标吗?EXPOSE
**似乎只是在主机0/S资源管理和用于隔离的docker抽象之间进行端口管理,因此内部(容器内部)代码应该使用自己的视角中正确设置的<transport-class>:\\address:port#
(从内部人员的角度来看)。 - user3666197