【问题标题】:Can you use python sockets for docker container communication?你可以使用 python 套接字进行 docker 容器通信吗?
【发布时间】:2018-10-25 21:44:36
【问题描述】:

在 docker 网络中,我尝试使用 python 套接字在两个容器之间进行通信(发送数据包)。 Pinging 有效,但 python 套接字库不起作用。

错误:

line 6: conn, addr = sock.connect(('172.168.1.2', 4000)) TypeError: 'NoneType' object is not iterable

第一个 python3 receive.py 在 container1 中运行。然后 python3 send.py 在容器 2 中运行。容器 1 打印“已接受”,然后没有其他内容。如上所述的容器 2 错误。

此网络是用户定义的网络,具有自己的子网和默认网关。当我使用相同的代码连接到我的树莓派时,不会发生此错误,但容器通信会出错。

全部代码:

容器1:

import socket

def receive():
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(("", 4000))
        s.listen(2)
        conn, addr = s.accept()
        print("accepted")
        print(bytes.decode(conn.recv(1024)))

容器 2:

import socket

def send():
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        command = "bridge test!"
        conn, addr = sock.connect(('172.168.1.2', 4000))
        conn.sendall(command)

设置网络:

docker network create --subnet 172.168.1.0/24 testNetwork
docker network connect testNetwork container1
docker network connect testNetwork container2

我从 docker inspect 获得了容器的 IP 地址(加上对它们的 ping 工作)请帮忙!谢谢!

【问题讨论】:

  • “加上 ping 他们工作” ping 什么从什么?
  • 我可以从主机和彼此内部 ping 容器

标签: python python-3.x sockets docker networking


【解决方案1】:

你有几个问题。

  1. socket.connect 不返回任何内容。它返回None。你认为它返回一个 conn, addr 的元组。 Python 尝试通过迭代来解构返回到元组中的任何内容,但您会收到错误:

    TypeError: 'NoneType' object is not iterable
    
  2. socket.sendall 接受不是str 的字节。转换方式

    sock.sendall(command.encode())
    

这是固定的send.py

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
command = "bridge test!"
x, y = sock.connect(('172.168.1.2', 4000))
sock.sendall(command.encode())

【讨论】:

    【解决方案2】:

    您可能想尝试 python 的 docker api。 https://github.com/docker/docker-py.git

    这是一个例子。

    #!/usr/bin/python3
    
    import docker
    import requests
    
    def main():
    
      # Connect to the default unix socket (/var/run/docker.sock)
      client = docker.from_env()
    
      #Pull the nginx:alpine image
      client.images.pull('nginx:alpine')
    
      #Define some test parameters, our first HTTP port and the number of containers
      portstart = 10000
      count = 1000
    
      #Create and start 'count' number of containers. Map container port 80 to an external port.
      for a in range(1,count+1):
        container = client.containers.create('nginx:alpine',ports={'80/tcp':portstart+a})
        container.start()
        print('Created container number {} name: {}'.format(a,container.name))
    
      #Get a list of all the running containers (best you don't run this script on a system which has existing containers running)
      #Iterate through the list, pick out the remote port, and perform a GET request to it to check nginx is online. If the status code is 200, we must be successful!
      container_list = client.containers.list()
      count = 0
      for container in container_list:
        port = container.attrs['HostConfig']['PortBindings']['80/tcp'][0]['HostPort']
        r = requests.get('http://127.0.0.1:{}'.format(port))
        if(r.status_code == 200):
          print('Container {} is alive and working on port {}!'.format(container.name,port))
          count += 1
        else:
          print('Container {} is dead :( Code: {}'.format(container.name,r.status_code))
    
      print('Summary: Online Containers: {} Offline Containers: {}'.format(count,len(container_list)-count))
      print('Removing containers...')
    
      #Let's clean up and put our toys back in the toybox.
      for container in container_list:
        container.stop()
        container.remove()
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

    • 有趣,我会去看看。谢谢
    • 这用于通过套接字与 docker 守护进程交互。我相信 OP 正在尝试在容器之间发送数据包。
    • 是的,这实际上对我正在做的其他事情很有帮助,但它不能回答我在这里发布的问题
    猜你喜欢
    • 2016-10-10
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 2020-06-16
    相关资源
    最近更新 更多