UFW 导致 Docker 容器无法使用 IP 访问宿主机

问题描述

  • Debian 服务器的内网 IP(宿主机 IP) 是 192.16.1.5,启用了 UFW 防火墙,并且服务器上运行着两个 Docker 容器。
  • 假设用 -p 8080:80 参数启动了容器 A 内的服务,在容器 B 内的服务通过宿主机 IP(192.16.1.5:8080)访问容器 A 的服务,发现无法正常访问。

问题分析

Debian 启用 UFW 防火墙后,Docker 容器可能无法使用宿主机的 IP 地址相互通信。这是因为 Docker 默认会直接修改 iptables 规则,而这些规则可能与 UFW 的配置产生冲突,导致通信受阻。

问题解决

解决方案一

关闭 UFW 防火墙,这是最简单的方案,但也是最危险的方案。因为服务器将失去 UFW 防火墙的保护,容易受到恶意攻击。

解决方法二

自定义 Docker 桥接网络,并添加 UFW 防火墙规则允许 Docker 桥接网络与宿主机互相通信。

  • 定义 Docker 桥接网络,同时指定自定义网络的子网范围
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
services:

user-biz:
image: clay/user-biz:latest
container_name: user-biz
restart: always
ports:
- 8080:80
networks:
cloud_default:
ipv4_address: 173.18.0.05

order-biz:
image: clay/order-biz:latest
container_name: order-biz
restart: always
ports:
- 9090:80
networks:
cloud_default:
ipv4_address: 173.18.0.06

networks:
cloud_default:
name: cloud_default
driver: bridge
ipam:
config:
- subnet: 173.18.0.0/16
  • 或者手动创建 Docker 桥接网络,同时指定自定义网络的子网范围,并在容器启动时指定桥接网络
1
sudo docker network create --driver bridge --subnet 173.18.0.0/16 cloud_default
1
2
sudo docker run -d --name user-biz -p 8080:80 --network cloud_default --ip 173.18.0.05 clay/user-biz:latest
sudo docker run -d --name order-biz -p 9090:80 --network cloud_default --ip 173.18.0.06 clay/order-biz:latest
  • 查看 Docker 桥接网络的 IP 分配情况
1
sudo docker inspect network cloud_default
1
2
3
4
5
6
7
8
9
10
11
12
13
14
"d268549f1335d1078c3692e1208a0376eb403a920a176642983f2eb0f64f4b61": {
"Name": "user-biz",
"EndpointID": "8d5cba4fe76a69b4169e6266ca2d3a5cbd9be84fdcf0e7f4f3ab6a05c2825a1f",
"MacAddress": "8e:40:19:99:af:49",
"IPv4Address": "173.18.0.05/16",
"IPv6Address": ""
},
"f83453e8d515e58a1c5a68c7957835ed82cece7104129dba1fcb604bb1215d8a": {
"Name": "order-biz",
"EndpointID": "8899737f0c54cfb3f4fac0f9effaeaf318eb12e8d0d4988fff399a2d94e9be0b",
"MacAddress": "72:6e:1b:a8:15:26",
"IPv4Address": "173.18.0.06/16",
"IPv6Address": ""
}
  • 添加 UFW 防火墙规则(使用 CIDR 表示法),允许 Docker 桥接网络与宿主机互相通信。
1
2
sudo ufw allow from 173.18.0.0/16
sudo ufw allow out to 173.18.0.0/16

参考资料