J'essaye de mettre en place un exemple de réseau Docker avec ZeroMQ dans macOS, où le serverd.py
envoie un message au clientd.py
et le client l'affiche simplement en utilisant PUSH/PULL. Si je les lance à l'extérieur du conteneur, ils fonctionnent bien, mais j'ai du mal à les faire communiquer lorsqu'ils sont dans des conteneurs séparés. Il semble que mon clientd.py
ne puisse pas se connecter au nom du conteneur, bien qu'il se trouve dans le même réseau de pont. J'ai essayé de remplacer le nom d'hôte avec l'adresse IP affectée pour serverd_dev_1
, mais cela ne fonctionne pas non plus.ZeroMQ ne parvient pas à communiquer entre deux conteneurs Docker
Voici ma configuration:
J'ai créé un nouveau réseau avec
docker network create -d bridge mynet
. Voici la sortie dedocker network inpsect 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": {} }
J'ai créé
serverd.py
etclientd.py
comme celui-ci et les mettre dans des dossiers séparés avec leurs Dockerfiles et 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))
I ont deux Dockerfiles et docker-compose.yml:
Dockerfile pour serverd.py:
FROM python:3.6
RUN mkdir src
ADD serverd.py /src/
RUN pip install pyzmq
WORKDIR /src/
EXPOSE 5557
Dockerfile pour clientd.py:
FROM python:3.6
RUN mkdir src
ADD clientd.py /src/
RUN pip install pyzmq
WORKDIR /src/
EXPOSE 5557
docker-Compose. yml pour serverd.py:
dev:
build: .
command: ["python", "-u", "./serverd.py"]
net: mynet
docker-Compose pour clientd.py:
dev:
build: .
command: ["python", "-u", "./clientd.py"]
net: mynet
serverd.py
démarre comme prévu avecdocker-compose up
:
Sending to tcp://127.0.0.1:5557...
clientd.py
ne démarrera pas comme ceci parce qu'il ne trouve pas le nom d'hôtetcp://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
Si je remplace l'URI
tcp://serverd_dev_1:5557
avectcp://172.18.0.2:5557
il ne plante plus, mais il est tout simplement marche au ralenti, sans recevoir des messages du serveur. Évidemment, je fais quelque chose de mal, mais je ne suis pas tout à fait sûr de quoi exactement. J'ai l'impression d'avoir suivi la documentation de Docker le plus fidèlement possible, et je serais très reconnaissant si vous aviez des idées.
Mon suspect est un docker-isolation des périphériques. Pourriez-vous définir les adresses cibles dans un format IPv4-absolute du côté ** '.bind()' ** -, comme 'address =" tcp: //172.18.0.2: 5557 "' ne pas compter sur n'importe quelle résolution de DNS et l'employant aussi comme le '.connect()' -target respectif sur le client? ** 'EXPOSE' ** semble juste pour arbitrer la gestion des ports entre la gestion des ressources 0/S de l'hôte et l'abstraction docker utilisée pour l'isolation, de sorte que le code interne (container-docker-container) doit utiliser la classe: \\ adresse: port # 'sur leur propre vision du monde (d'un point de vue interne). –
user3666197