Docker:多个 Client/Server 个没有硬编码 IP 地址的容器
Docker: Multiple Client/Server Containers without Hardcoding IP Addresses
下午好。我是 Docker 的新手,我正在努力想出一个可扩展的解决方案来生成网络流量。我想让许多客户端和服务器容器通过 docker 桥接网络相互通信。现在我有一个客户端和一个服务器容器,它们相互通信,但速度非常慢。此外,我必须对他们的 IP 地址进行硬编码,以便他们能够找到彼此。必须有更好的方法来扩大规模,但我很挣扎,因为我的 client.py 代码需要服务器的 IP 地址和端口号才能找到服务器。
Client.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)
客户端Docker文件
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"]
Server.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, [int(uniform(0,100))])
# Tank 3
DataBank.set_words(2, [int(uniform(0,100))])
# Tank 4
DataBank.set_words(3, [int(uniform(0,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)
服务器Docker文件
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-编写文件
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
这 运行s,但我的客户需要很长时间才能将寄存器值打印到命令行。除了速度慢之外,我当前的方法不可扩展。我必须使用 MODBUS TCP 协议进行通信,这就是 python 代码使用 pyModbusTCP 的原因。但是必须有一种方法可以让 10 个客户端和服务器容器相互通信,而不必为每个容器指定 IP 地址吗?
我研究了 docker swarm,但我看不出它对解决为每个容器分配静态 IP 地址的问题有何帮助。我还尝试添加一个环境变量,其中 docker 获取服务器的 IP 地址并将其传递给 client.py 代码,但我无法使其正常工作。我很困,任何帮助将不胜感激。非常感谢您的宝贵时间。
编辑:它非常慢意味着当我 运行“docker-撰写”时,我收到通知“附加到 server1_con,client1_con”,但随后我的命令行开始显示打印输出大约需要 10 分钟。
这里有很多问题;首先是关于“我的命令行开始显示打印输出大约需要 10 分钟”; 运行 python 在非缓冲模式下,例如:
CMD ["python","-u", "client.py"]
第二个问题与您启动服务器的方式有关 ModbusServer('localhost',502, no_block=True)
- 这将绑定到本地主机并且无法在主机(或本例中的容器)外部访问。使用 ModbusServer('0.0.0.0',502, 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")
。通过这些更改,当我 运行 在我的机器上应用程序时,您的应用程序可以满足您的期望。
下午好。我是 Docker 的新手,我正在努力想出一个可扩展的解决方案来生成网络流量。我想让许多客户端和服务器容器通过 docker 桥接网络相互通信。现在我有一个客户端和一个服务器容器,它们相互通信,但速度非常慢。此外,我必须对他们的 IP 地址进行硬编码,以便他们能够找到彼此。必须有更好的方法来扩大规模,但我很挣扎,因为我的 client.py 代码需要服务器的 IP 地址和端口号才能找到服务器。
Client.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)
客户端Docker文件
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"]
Server.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, [int(uniform(0,100))])
# Tank 3
DataBank.set_words(2, [int(uniform(0,100))])
# Tank 4
DataBank.set_words(3, [int(uniform(0,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)
服务器Docker文件
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-编写文件
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
这 运行s,但我的客户需要很长时间才能将寄存器值打印到命令行。除了速度慢之外,我当前的方法不可扩展。我必须使用 MODBUS TCP 协议进行通信,这就是 python 代码使用 pyModbusTCP 的原因。但是必须有一种方法可以让 10 个客户端和服务器容器相互通信,而不必为每个容器指定 IP 地址吗?
我研究了 docker swarm,但我看不出它对解决为每个容器分配静态 IP 地址的问题有何帮助。我还尝试添加一个环境变量,其中 docker 获取服务器的 IP 地址并将其传递给 client.py 代码,但我无法使其正常工作。我很困,任何帮助将不胜感激。非常感谢您的宝贵时间。
编辑:它非常慢意味着当我 运行“docker-撰写”时,我收到通知“附加到 server1_con,client1_con”,但随后我的命令行开始显示打印输出大约需要 10 分钟。
这里有很多问题;首先是关于“我的命令行开始显示打印输出大约需要 10 分钟”; 运行 python 在非缓冲模式下,例如:
CMD ["python","-u", "client.py"]
第二个问题与您启动服务器的方式有关 ModbusServer('localhost',502, no_block=True)
- 这将绑定到本地主机并且无法在主机(或本例中的容器)外部访问。使用 ModbusServer('0.0.0.0',502, 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")
。通过这些更改,当我 运行 在我的机器上应用程序时,您的应用程序可以满足您的期望。