使docker容器通过端口通信

Ayo*_*yan 3 python docker dockerfile

我试图创建2个docker容器并以它们可以通过localhost中的端口相互通信的方式运行它们。我已经创建了2个python文件作为发送方和接收方。当我在没有docker的情况下运行它们时,它们可以很好地通信。但是使用docker它们无法正常运行。

发件人

Python脚本

#!/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()
Run Code Online (Sandbox Code Playgroud)

Docker文件

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
Run Code Online (Sandbox Code Playgroud)

接收者

Python脚本

#!/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)
Run Code Online (Sandbox Code Playgroud)

Docker文件

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
Run Code Online (Sandbox Code Playgroud)

为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
Run Code Online (Sandbox Code Playgroud)

发送方运行命令

docker run --name="testTalk" --env SEND_HOST="localhost" --env SEND_PORT="5555" docker.io/ayonnayihan/sample-sendr-rcv-test:sender0.1
Run Code Online (Sandbox Code Playgroud)

在运行容器之前,我确保两个映像均已构建。谁能说出它为什么不能正常运行?

这是简单的python运行命令,在没有docker的情况下也可以正常工作:

在接收器上 python script.py localhost 5555

发件人 python script.py localhost 5555

joe*_*lnb 6

我认为您可以通过以下三种方法来使此工作正常进行:

  1. 创建一个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
    
    Run Code Online (Sandbox Code Playgroud)
  2. docker-composedocker-compose.ymllike 一起使用:

    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
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用主机网络:

    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
    
    Run Code Online (Sandbox Code Playgroud)

第三个选项与您当前正在执行的操作最相似,但出于以下原因,我不建议您这样做。其他任何一个选项都可以使用,但是如果您只是从Docker开始,那么可能不值得学习docker-compose。

您遇到问题的原因是,每个容器都有自己的“本地主机”概念,因为它们位于不同的网络名称空间中。这意味着“ testTalk”容器上的“ localhost”不会解析为运行侦听器的主机。使用--net=host(上面的选项3)时,您将删除容器的单独名称空间,从而删除了使用docker的一些安全优势。