docker网段占用内网 IP 问题

作者:matrix 发布时间:2026-06-30 分类:零零星星

docker会通过网桥(Bridge)给容器分配内网 IP,实现容器之间的通信。分配的内网IP地址遵守了 RFC 1918 国际标准(私有 IP 地址范围)

默认情况下,docker 需要新建网络时,它会依次从以下范围中切出子网(通常是 /16/24):

- `172.17.0.0/16` 到 `172.31.0.0/16`(B类私有地址)

- `192.168.0.0/16`(C类私有地址)

- `10.0.0.0/8`(A类私有地址)

问题

服务器对部分内网来源 IP 的服务访问异常,表现为:部分内网 IP 请求服务器服务失败,但不是所有内网 IP 都失败。

ping服务端表现都是Request timeout for icmp_seq 0,curl请求服务全部超时

排查

查看 IP 是否命中路由表

$ ip route get 172.19.11.22
172.19.11.22 via 10.100.10.1 dev xgbe0  src 10.100.10.36 
    cache 

监听的en0网卡指定 IP 的数据包

$ tcpdump -ni eno host 172.19.11.22

原因

今天内网 172.19开头的 客户端IP 请求服务都失败了,正好是落在这个Docker 网络 IP 段

$ ip route show
...
172.19.0.0/16 dev br-f8d5609d3bbf  proto kernel  scope link  src 172.19.0.1 
192.168.5.0/24 dev docker0  proto kernel  scope link  src 
...

当服务器准备把响应发回给 172.19.xx.xx客户端IP的时候,服务器操作系统查看自己的路由表发现两条路:

  • 默认路由:去往任何地方(0.0.0.0/0),走 via 10.104.62.1 dev xgbe0

  • Docker 路由:去往 172.19.0.0/16,走 dev br-f8d5609d3bbf

  • 悲剧链路:根据操作系统的最长前缀匹配原则(Longest Prefix Match)/16 的精确度远高于 /0(默认路由),服务器把本该发往外部流量直接丢进了 Docker 的虚拟网桥 br-f8d5609d3bbf 里,由于网桥里根本没有 172.19.xx.xx客户端IP这个容器,流量直接“死”在里面,导致外部客户端超时报错。

解决

全局修改 Docker 的地址池

/etc/docker/daemon.json文件添加bip,fixed-cidr,default-address-pools 字段配置,强制以后任何 Docker Compose 自动创建的新网络,都会被强制限制在 192.168.0.0/16 范围内划分。

{
...
  "bip": "192.168.1.1/24",
  "fixed-cidr": "192.168.1.0/25",
  "default-address-pools": [
    {
      "base": "192.168.0.0/16",
      "size": 24
    }
  ]
  ...
}

修改后记得重启docker