我试图创建2个docker容器并以他们可以通过localhost中的端口相互通信的方式运行它们。我创建了2个python文件作为发送者和接收者。当我在没有码头的情况下运行它们时,它们很好地沟通但是对于docker他们运行不正常。
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import socket
import time
import sys
print sys.argv[1]
print sys.argv[2]
for i in range(1,10):
time.sleep(2)
data = "My parameters that I want to share with the server on ith iteration %d" % (i)
print "sedning data: %d" % (i)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((sys.argv[1], int(sys.argv[2])))
sock.sendall(data)
sock.close()
FROM ubuntu
RUN \
apt-get update && \
apt-get install -y python python-dev python-pip python-virtualenv && \
rm -rf /var/lib/apt/lists/*
ADD script.py /root/script.py
CMD python -u /root/script.py $SEND_HOST $SEND_PORT
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import socket
import sys
print sys.argv[1]
print sys.argv[2]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((sys.argv[1], int(sys.argv[2])))
s.listen(3)
while True:
conn, addr = s.accept()
data = conn.recv(1024)
conn.close()
print "received data from sender: %s" % (data)
FROM ubuntu
RUN \
apt-get update && \
apt-get install -y python python-dev python-pip python-virtualenv && \
rm -rf /var/lib/apt/lists/*
ADD script.py /root/script.py
CMD python -u /root/script.py $LISTEN_HOST $LISTEN_PORT
为Receiver运行命令
docker run --name="testListen" -p 5555:5555 --env LISTEN_HOST="localhost" --env LISTEN_PORT="5555" docker.io/ayonnayihan/sample-sendr-rcv-test:receiver0.1
为发件人运行命令
docker run --name="testTalk" --env SEND_HOST="localhost" --env SEND_PORT="5555" docker.io/ayonnayihan/sample-sendr-rcv-test:sender0.1
在运行容器之前,我确保构建了两个图像。有人能说出为什么它运行不正常吗?
这是一个简单的python运行命令,在没有docker的情况下工作正常:
接收者python script.py localhost 5555
上的
发件人python script.py localhost 5555
答案 0 :(得分:5)
我认为你有三个选择来实现这个目的:
创建一个docker网络来连接主机:
docker network create --driver bridge sample-sendr-rcv-test
docker run --name="testListen" --env LISTEN_HOST="0.0.0.0" --env LISTEN_PORT="5555" --network=sample-sendr-rcv-test -d docker.io/ayonnayihan/sample-sendr-rcv-test:receiver0.1
docker run --name="testTalk" --env SEND_HOST="testListen" --env SEND_PORT="5555" --network=sample-sendr-rcv-test -d docker.io/ayonnayihan/sample-sendr-rcv-test:sender0.1
将docker-compose与docker-compose.yml
类似使用:
version: '2'
services:
sender:
image: docker.io/ayonnayihan/sample-sendr-rcv-test:sender0.1
# build: sender
environment:
SEND_HOST: receiver
SEND_PORT: 5555
receiver:
image: docker.io/ayonnayihan/sample-sendr-rcv-test:receiver0.1
# build: receiver
environment:
LISTEN_HOST: '0.0.0.0'
LISTEN_PORT: 5555
使用主机网络:
docker run --name="testListen" --env LISTEN_HOST="127.0.0.1" --env LISTEN_PORT="5555" --net=host -d docker.io/ayonnayihan/sample-sendr-rcv-test:receiver0.1
docker run --name="testTalk" --env SEND_HOST="localhost" --env SEND_PORT="5555" --net=host -d docker.io/ayonnayihan/sample-sendr-rcv-test:sender0.1
第三个选项与您目前正在进行的操作最相似,但我不推荐它,原因如下所述。如果您刚刚开始使用docker,那么其他任何一个选项都可以使用,但可能不值得学习docker-compose。
您遇到问题的原因是每个容器都有自己的想法' localhost'因为他们在不同的网络namespace。这意味着' localhost'在你的' testTalk'容器无法解析为运行侦听器的主机。当您使用--net=host
(上面的选项3)时,您将删除容器的单独命名空间,从而消除使用docker的一些安全优势。