微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Docker:无需硬编码 IP 地址的多个客户端/服务器容器

如何解决Docker:无需硬编码 IP 地址的多个客户端/服务器容器

下午好。我是 Docker 的新手,我正在努力想出一个可扩展的解决方案来生成网络流量。我想让许多客户端和服务器容器通过 docker 网桥网络相互通信。现在我有一个客户端和一个服务器容器,它们相互通信,但速度非常慢。此外,我必须对他们的 IP 地址进行硬编码,以便他们能够找到彼此。必须有更好的方法来扩大规模,但我很挣扎,因为我的 client.py 代码需要服务器的 IP 地址和端口号才能找到服务器。

客户端.py

from pyModbusTCP.client import ModbusClient
import time    

c = ModbusClient()
c.host("172.20.0.2")
c.port(502)
    
while True:
    if not c.is_open():
        if not c.open():
            print("Unable to connect to Server at 172.20.0.2:502")
        
    if c.is_open():
        regs = c.read_holding_registers(0,4)
        if regs:
            print("Register #0: " + str(regs[0]))
            print("Register #1: " + str(regs[1]))
            print("Register #2: " + str(regs[2]))
            print("Register #3: " + str(regs[3]))
    time.sleep(5)

客户端 DockerFile

FROM python:3
    
workdir ~/client-server-docker-test/client
    
copY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
    
copY . .
    
CMD ["python","./client.py"]

服务器.py

from pyModbusTCP.server import ModbusServer,DataBank
from time import sleep
from random import uniform
    
# set up server
server = ModbusServer('localhost',502,no_block=True)
# initialize register 0 with value of 80
DataBank.set_words(0,[80])
    
try:
    print("Start server...")
        server.start()
        print("Server is online...")
        # change register value every 5 seconds. 
        while True:
            # Set Register @ Address 0 to random int. value
            DataBank.set_words(0,[int(uniform(0,100))])
            # Tank 2
            DataBank.set_words(1,100))])
            # Tank 3
            DataBank.set_words(2,100))])
            # Tank 4
            DataBank.set_words(3,100))])
            sleep(5)
# when hit ctrl+C in CMD line,shut down server
except:
    print("Shutdown server....")
    server.stop()
    print("Server is offline...")
    sleep(0.5)

服务器 DockerFile

FROM python:3
    
workdir ~/client-server-docker-test/server
    
copY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
    
copY . .
    
CMD ["python","./server.py"]

Docker-Compose 文件

version: '2.1'
services:
  server:
    image: server1
    container_name: server1_con
    ports:
      - 502:502
    networks:
      test_net:
        ipv4_address: 172.20.0.2
    
  client:
    image: client1
    container_name: client1_con
    depends_on:
      - server
    networks:
      test_net:
        ipv4_address: 172.20.0.3
    
networks:
  test_net:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/16

这会运行,但我的客户需要很长时间才能将寄存器值打印到命令行。除了速度慢之外,我目前的方法不可扩展。我必须使用MODBUS TCP协议进行通信,这就是python代码使用pyModbusTCP的原因。但是必须有一种方法可以让 10 个客户端和服务器容器相互通信,而不必为每个容器指定 IP 地址?

我已经研究了 docker swarm,但我看不出它如何帮助我为每个容器分配静态 IP 地址的问题。我还尝试添加一个环境变量,其中 docker 获取服务器的 IP 地址并将其传递到 client.py 代码中,但我无法使其正常工作。我很困,任何帮助将不胜感激。非常感谢您抽出宝贵时间。

编辑:它令人难以置信的慢意味着当我运行“docker-compose up”时,我收到一条通知“附加到 server1_con,client1_con”,但随后我的命令行开始显示打印输出大约需要 10 分钟。

解决方法

这里有很多问题;首先是关于“我的命令行开始显示打印输出大约 10 分钟”;在无缓冲模式下运行 python,例如:

CMD ["python","-u","client.py"]

第二个问题与您启动服务器 ModbusServer('localhost',502,no_block=True) 的方式有关 - 这将绑定到 localhost 并且无法在主机(或在这种情况下为容器)之外访问。使用 ModbusServer('0.0.0.0',no_block=True) 绑定到主机上的所有地址。

第三是不再需要硬编码 IP 地址;将您的 docker-compose.yml 更新为(注意:我已添加 build 路径):

version: '2.1'
services:
  server:
    build: ./server
    networks:
      - test_net

  client:
    build: ./client
    depends_on:
      - server
    networks:
      - test_net

networks:
  test_net:
    driver: bridge
    ipam:
      driver: default

并将 client.py 更改为使用服务名称 c.host("server")。通过这些更改,当我在我的机器上运行您的应用程序时,您的应用程序可以满足您的期望。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?