docker-compose 连接来自 LAN 上不同设备的服务器/客户端容器
Posted
技术标签:
【中文标题】docker-compose 连接来自 LAN 上不同设备的服务器/客户端容器【英文标题】:docker-compose connect server/client containers from different devices on LAN 【发布时间】:2019-03-03 12:51:27 【问题描述】:我正在使用 docker-compose 在本地网络的不同设备上部署服务器/客户端应用程序。我的设置如下:
在我的 docker-compose.yml 文件中,我有一个名为“server”的服务,它依赖于两个附加服务(“database”和“web”)。这三个服务在同一台设备上运行,并且能够相互成功连接。 “服务器”服务部署了基于 Flask 的 API,理想情况下,该 API 应该等待来自同一 LAN 中其他设备的请求。
在同一个 docker-compose.yml 文件中,我有一个名为“客户端”的服务,它运行一个应用程序,该应用程序应该部署在同一 LAN 中的多个设备上。独立于运行它的设备的“客户端”服务应该能够向位于同一 LAN 中的不同设备上的“服务器”服务发送请求。
这是我的 docker-compose.yml 文件:
version: '3.5'
networks:
outside:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.220.0/24
services:
client:
build: ./client
environment:
TZ: "Europe/Madrid"
command: >
sh -c "ln -snf /usr/share/zoneinfo/$TZ /etc/localtime &&
echo $TZ > /etc/timezone &&
nmap -p 8080 192.168.220.220 &&
python -u client/main_controller.py"
restart: always
volumes:
- .:/code
networks:
outside:
server:
build: ./server
environment:
TZ: "Europe/Madrid"
command: >
sh -c "ln -snf /usr/share/zoneinfo/$TZ /etc/localtime &&
echo $TZ > /etc/timezone &&
python -u server/main_server.py"
volumes:
- .:/code
ports:
- "8080:8080" # host:container
restart: always
depends_on:
- database
- web
networks:
default:
outside:
ipv4_address: 192.168.220.220
database:
image: mysql:latest
#command: ./database/run_db.sh #mysqld --user=root --verbose
restart: always
volumes:
- ./database:/docker-entrypoint-initdb.d/:ro
ports:
- "3306:3306" # host:container
environment:
MYSQL_ROOT_PASSWORD: root
networks:
default:
web:
image: nginx:latest
restart: always
ports:
- "8081:80"
volumes:
- ./interface:/www
- ./interface/nginx.conf:/etc/nginx/conf.d/default.conf
networks:
default:
我正在使用 python 请求库使用以下 url 将请求从“客户端”发送到“服务器”:
http://192.168.220.220:8080
我的问题是,当我在同一设备 [deviceA] 上运行两个容器“客户端”和“服务”时,它们能够成功通信。
但是当我在不同的设备上运行容器时(使用 Mac OS X [deviceA] 的计算机上的“服务”和 Raspberry Pi [deviceB] 上的“客户端”,两者都使用 wi-fi 连接到同一个 LAN) ,“客户端”无法访问指定的 IP 和端口。
为了测试设备是否能够访问 IP:port 组合,我在运行“客户端”服务后立即使用以下命令:
nmap -p 8080 192.168.220.220
在 [deviceA] 上给出以下输出:
client_1 | Starting Nmap 7.01 ( https://nmap.org ) at 2019-03-03 12:22 Europe
client_1 | Nmap scan report for raspberry_escape_controller_server_1.raspberry_escape_controller_outside (192.168.220.220)
client_1 | Host is up (0.00012s latency).
client_1 | PORT STATE SERVICE
client_1 | 8080/tcp open http-proxy
client_1 | MAC Address: <mac_address> (Unknown)
client_1 |
client_1 | Nmap done: 1 IP address (1 host up) scanned in 0.71 seconds
以及 [deviceB] 上的以下一个:
client_1 | Starting Nmap 7.40 ( https://nmap.org ) at 2019-03-03 13:24 CET
client_1 | Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
client_1 | Nmap done: 1 IP address (0 hosts up) scanned in 0.78 seconds
----------- [编辑 1] -----------
正如 DTG 所建议的,这里是 [deviceB] 上 netstat 命令的输出:
root@a9923f852423:/code# netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.220.1 0.0.0.0 UG 0 0 0 eth0
192.168.220.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
好像看不到[deviceA],应该是192.168.220.220
【问题讨论】:
检查 docs.docker.com/network/iptables/… 是否在 /etc/docker/daemon.json 中将iptables
设置为 false
可能会产生类似的结果
我在两台机器上都把参数改成了false,但似乎没有做任何改变。
除非您想自己处理路由,否则不应将其设置为false
。
【参考方案1】:
在我看来,即使该服务已在您的 [deviceA] 中启动并运行,但有某种防火墙不允许从外部连接到它。
也许您需要检查 [deviceA] 上的防火墙配置。
路由问题
如果是路由问题,您应该在 hostB 中看到路由表
netstat -nr
并查看到 hostA 的有效路由存在
如果不存在有效的路线,您应该添加一条
sudo route add -net hostA_IP/MASK gw HOSTB_DEFAULT_GATEWAY
码头工人间通讯
创建网络后,您可以使用 docker run --network= 选项在其上启动容器。您在此网络中启动的容器必须驻留在同一 Docker 主机上。网络中的每个容器都可以立即与网络中的其他容器通信。
阅读有关了解 docker 通信的更多信息: See docker documentation here
【讨论】:
感谢您的评论。我检查了它的防火墙,但它看起来像是被禁用了。可以看截图here。 您可以从其他主机或网络中的某个点连接到您的 macbook 吗? 按照您的建议使用 telnet:从 [deviceA] 的“客户端”容器内部运行它能够到达主机:root@ccaba82bb26e:/code# telnet 192.168.220.220 8080 Trying 192.168.220.220 ... 连接到 192.168.220.220。尽管从 [deviceB] 上的“客户端”容器内部运行时,它无法建立连接:root@a9923f852423:/code# telnet 192.168.220.220 8080 Trying 192.168.220.220... telnet: Unable to connect to remote主机:没有路由到主机 啊,是问题(NO ROUTE TO HOST),表示deviceB不知道如何到达deviceA,是路由问题 您应该查看 hostB 中的路由表、IP 以及应该允许从 hostB 内部发起的传出连接的防火墙。您可以在 hostB 中使用:code
netstat -nr ifconfig code
来检查您的网络状态以上是关于docker-compose 连接来自 LAN 上不同设备的服务器/客户端容器的主要内容,如果未能解决你的问题,请参考以下文章