代码之家  ›  专栏  ›  技术社区  ›  Joe N

您可以使用python套接字进行docker容器通信吗?

  •  5
  • Joe N  · 技术社区  · 6 年前

    在docker网络中,我试图使用python套接字在两个容器之间进行通信(发送数据包)。Ping可以工作,但python套接字库不能工作。

    错误:

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

    第一个python3接收。py在container1中运行。然后python3发送。py在容器2中运行。容器1打印“已接受”,然后不打印其他内容。如上所述的容器2错误。

    此网络是一个用户定义的网络,具有自己的子网和默认网关。当我使用它连接到我的raspberry pi时,这个错误不会发生在相同的代码中,但它会在容器通信中出错。

    所有代码:

    容器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),请帮助!谢谢

    2 回复  |  直到 6 年前
        1
  •  4
  •   0xcaff    6 年前

    你有几个问题。

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

      TypeError: 'NoneType' object is not iterable
      
    2. 插座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
  •  2
  •   James Knott    6 年前

    您可能想试试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()