K8s 节点 Docker 网段与外部数据库 IP 冲突
问题现象
K8s 部署环境无法连接外部 Oracle 数据库:
数据库:172.17.179.4:1521
现象:应用提示“无法连接数据源”
根本原因
每个 K8s 节点都存在 Docker 默认路由:
172.17.0.0/16 dev docker0
目标数据库 172.17.179.4 属于 172.17.0.0/16。
因此,Linux 根据最长前缀匹配,将数据库流量发给了本机 docker0,而不是通过默认网关 192.168.103.1 发往外部网络:
# 修复前
172.17.179.4 dev docker0 src 172.17.0.1
这属于网络路由冲突,与数据库账号、Oracle JDBC、前端代码和域名无关。即使改用域名,只要域名仍解析到该 IP,问题依然存在。
临时解决方案
在每个可能运行相关服务的 K8s 节点上,为数据库 IP 增加一条 /32 主机路由:
ip route replace 172.17.179.4/32 via 192.168.103.1 dev eth0
验证:
ip route get 172.17.179.4
正确结果类似:
172.17.179.4 via 192.168.103.1 dev eth0 src 192.168.103.101
/32 路由比 Docker 的 /16 路由更精确,因此只有访问 172.17.179.4 的流量改走外部网关,不影响其他 Docker、K8s 和默认路由。
永久生效
先查询 eth0 对应的 NetworkManager 连接名:
nmcli -t -f NAME,DEVICE connection show --active | grep ':eth0$'
不同节点的连接名可能不同,例如:
Wired connection 1:eth0
或者:
eth0:eth0
使用实际查询到的连接名保存路由:
nmcli connection modify "Wired connection 1" +ipv4.routes "172.17.179.4/32 192.168.103.1"
如果连接名是 eth0:
nmcli connection modify "eth0" +ipv4.routes "172.17.179.4/32 192.168.103.1"
验证持久化配置:
nmcli -f ipv4.routes connection show "实际连接名"
预期结果:
{ ip = 172.17.179.4/32, nh = 192.168.103.1 }
连通性验证
nc -vz -w 5 172.17.179.4 1521
如果没有安装 nc:
timeout 5 bash -c '</dev/tcp/172.17.179.4/1521' \
&& echo "1521端口连通" \
|| echo "1521端口不通"
回滚方式
删除当前运行时路由:
ip route del 172.17.179.4/32
删除 NetworkManager 中的持久化配置:
nmcli connection modify "实际连接名" -ipv4.routes "172.17.179.4/32 192.168.103.1"
关键知识点
- Linux 路由遵循“最长前缀优先”,
/32优先于/16。 - K8s Pod 网段和 Docker 默认网桥不是一回事。本环境 Pod 使用
10.244.0.0/16,冲突的是节点上的docker0。 - 不要因为该问题直接修改或重启 Docker 网络,否则可能影响整个 K8s 节点。
- 多节点集群应在所有可能调度相关服务的节点上配置路由,避免 Pod 漂移后问题复发。
/32主机路由适合解决单个目标 IP 的冲突,影响范围小、风险低、容易回滚。- 长期方案是统一规划容器网段、内部网络和云端网络,避免地址段重叠。

浙公网安备 33010602011771号