Docker安装后阿里云Redis内网不通的排查与修复指南
作者:Java小白笔记
TL;DR: Docker 默认网桥 docker0 占用 172.17.0.0/16 网段,与阿里云内网服务 IP 冲突,导致 DNS 解析正确但网络不通。修改 Docker 地址池配置即可解决。
一、问题现象
在阿里云 ECS 上安装 Docker 后,发现应用无法连接阿里云 Redis 实例。ping 测试如下:
[root@iZbp1i6mpczv4wu1v2d2fyZ bin]# ping r-bp1ewz70e1hep9esnv.redis.rds.aliyuncs.com PING r-bp1ewz70e1hep9esnv.redis.rds.aliyuncs.com (172.17.0.116) 56(84) bytes of data. From iZbp1i6mpczv4wu1v2d2fyZ (172.17.0.1) icmp_seq=1 Destination Host Unreachable From iZbp1i6mpczv4wu1v2d2fyZ (172.17.0.1) icmp_seq=2 Destination Host Unreachable From iZbp1i6mpczv4wu1v2d2fyZ (172.17.0.1) icmp_seq=3 Destination Host Unreachable ^C --- r-bp1ewz70e1hep9esnv.redis.rds.aliyuncs.com ping statistics --- 5 packets transmitted, 0 received, +4 errors, 100% packet loss
关键线索:
- DNS 解析正常:域名正确解析到了
172.17.0.116 - 网络不通:100% 丢包,报
Destination Host Unreachable - 错误来源:
From 172.17.0.1——这是docker0网桥的地址,不是真正的出口网卡
[!NOTE]
这类问题的典型特征是:安装 Docker 之前一切正常,安装后内网服务突然不可达。容易误判为防火墙或安全组问题。
二、根因分析
2.1 Docker 默认网桥机制
Docker 安装后会自动创建一个名为 docker0 的虚拟网桥,默认分配 172.17.0.1/16 作为网关地址。所有未指定自定义网络的容器都通过这个网桥与宿主机通信。
通过 ifconfig 可以确认:
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.21.247.213 netmask 255.255.240.0 broadcast 172.21.255.255
2.2 路由冲突原理
问题的核心是 Linux 路由表冲突。以下是数据包的处理流程:

正常情况,访问 172.17.0.116 应该走 eth0 网卡到达阿里云内网。但 docker0 的子网是 172.17.0.0/16,覆盖了 172.17.0.0 ~ 172.17.255.255 的全部 65534 个 IP。Linux 路由表优先匹配了 docker0 的路由条目,导致数据包被错误地发送到虚拟网桥,而不是真正的物理网卡 eth0。
2.3 为什么阿里云 Redis 的 IP 会落在这个范围
阿里云内网 VPC 使用的私网地址范围包括:
| VPC 网段 | 子网范围 |
|---|---|
10.0.0.0/8 | 10.0.0.0 ~ 10.255.255.255 |
172.16.0.0/12 | 172.16.0.0 ~ 172.31.255.255 |
192.168.0.0/16 | 192.168.0.0 ~ 192.168.255.255 |
Docker 默认的 172.17.0.0/16 正好落在阿里云 VPC 的 172.16.0.0/12 范围内。这不是巧合,而是两者的默认配置恰好重叠了。
[!WARNING]
如果你使用的云服务商(AWS、腾讯云、华为云等)的 VPC 网段也是 172.16~31.0.0/12,安装 Docker 后都可能遇到同样的问题。
三、诊断步骤
遇到"安装 Docker 后内网不通"的情况,按以下步骤排查:
步骤 1:确认 DNS 解析结果
nslookup r-bp1ewz70e1hep9esnv.redis.rds.aliyuncs.com # 或 dig r-bp1ewz70e1hep9esnv.redis.rds.aliyuncs.com
记下解析出的 IP 地址。
步骤 2:查看 Docker 网桥地址
ip addr show docker0 # 或 ifconfig docker0
确认 docker0 的 IP 和子网掩码。
步骤 3:检查路由表
ip route # 或 route -n
典型的冲突路由表输出:
default via 172.21.240.1 dev eth0 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 172.21.240.0/20 dev eth0 proto kernel scope link src 172.21.247.213
可以看到:172.17.0.0/16 指向了 docker0,而 Redis 的 IP 172.17.0.116 落在这个范围内。
步骤 4:对比确认
如果步骤 1 解析出的 IP 落在步骤 2 显示的 docker0 子网范围内,就可以确认是网段冲突。
四、修复方案
4.1 修改 Docker 默认地址池(推荐)
编辑 /etc/docker/daemon.json:
{
"default-address-pools": [
{
"base": "172.30.0.0/16",
"size": 24
}
]
}配置项说明:
| 配置项 | 含义 |
|---|---|
default-address-pools | Docker 网络使用的地址池数组,可以定义多个池 |
base | 地址池的总量,172.30.0.0/16 包含 172.30.0.0 ~ 172.30.255.255 共 65534 个 IP |
size | 每个 Docker 网络从池中切出的子网大小,24 表示 /24(256 个 IP) |
[!IMPORTANT]
如果 daemon.json 中已有其他配置(如 registry-mirrors、log-driver 等),请将 default-address-pools 合并到现有 JSON 中,不要覆盖整个文件。
重启 Docker 使配置生效:
systemctl restart docker
验证修复结果:
# 1. 确认 docker0 地址已变更 ip addr show docker0 # 预期输出:inet 172.30.0.1/24 # 2. 验证 Redis 连通性 ping r-bp1ewz70e1hep9esnv.redis.rds.aliyuncs.com # 预期输出:正常收到回复
4.2 选择合适的地址池
172.30.0.0/16 是推荐值,但你也可以根据实际 VPC 网段选择其他地址。核心原则是 避开所有云内网服务可能使用的网段:
| 方案 | 地址池 | 适用场景 |
|---|---|---|
| 推荐 | 172.30.0.0/16 | VPC 使用 172.16~17.0.0/12 时 |
| 保守方案 | 10.200.0.0/16 | VPC 使用 172.x 时,选 10.x 高段避开 |
| 极端保守 | 192.168.100.0/16 | 当 VPC 同时用了 10.x 和 172.x |
[!TIP]
配置前先确认你的 VPC 网段:在阿里云控制台 → VPC → 专有网络详情中查看。确保 Docker 地址池不在 VPC 网段范围内。
4.3 方案对比
| 方案 | 操作复杂度 | 影响范围 | 推荐度 |
|---|---|---|---|
| 修改 Docker 地址池 | 低(改一个配置文件) | 已有容器网络短暂中断 | ★★★★★ |
| 修改 VPC 网段 | 高(需要重建 VPC) | 所有云资源需要迁移 | ★☆☆☆☆ |
| 给 Docker 指定固定 IP | 低 | 仅影响 docker0 | ★★★★☆ |
| 添加静态路由绕过 | 中(手动管理路由) | 维护成本高,容易遗漏 | ★★☆☆☆ |
结论:修改 Docker 地址池是最简单、影响最小的方案。
五、注意事项
5.1 已有容器的影响
重启 Docker 后,docker0 的 IP 地址会变更。已有容器在重启后会获得新地址池中的 IP,但重启期间网络会短暂中断(通常几秒)。
如果生产环境有运行中的容器:
# 建议在业务低峰期操作 # 先查看运行中的容器 docker ps # 修改配置后重启 systemctl restart docker # 容器会自动重连(如果设置了 restart policy) # 如果没有 restart policy,需要手动启动 docker start <container_name>
5.2 多个 Docker 网络的场景
如果项目使用 Docker Compose 创建了多个自定义网络,size: 24 意味着每个网络分配 256 个 IP。172.30.0.0/16 的池子可以切出 256 个这样的子网(172.30.0.0/24、172.30.1.0/24 … 172.30.255.0/24),对于绝大多数场景绑绑有余。
5.3 Docker 版本兼容性
default-address-pools 配置项从 Docker 17.06 版本开始支持。通过以下命令确认版本:
docker --version # 输出示例:Docker version 24.0.7, build afdd53b
如果版本低于 17.06(极少见),需要升级 Docker 而不是改配置。
六、总结
问题本质: Docker 默认网桥 docker0 的 172.17.0.0/16 网段与阿里云 VPC 内网地址冲突,导致路由错误。
修复方法: 在 /etc/docker/daemon.json 中配置 default-address-pools,将 Docker 网段改到不冲突的范围(如 172.30.0.0/16),重启 Docker 即可。
预防措施: 在新机器上安装 Docker 前,先确认 VPC 网段,提前配置好 daemon.json 再启动 Docker 服务,从源头避免冲突。
附录:快速排障清单
遇到"Docker 安装后内网服务不通"时,按顺序检查:
| 序号 | 检查项 | 命令 | 预期 |
|---|---|---|---|
| 1 | DNS 解析 | nslookup <域名> | IP 正常返回 |
| 2 | docker0 地址 | ip addr show docker0 | 与目标 IP 不在同一子网 |
| 3 | 路由表 | ip route | 目标 IP 不走 docker0 |
| 4 | ping 测试 | ping <目标IP> | 正常收到回复 |
| 5 | 应用验证 | redis-cli -h <host> ping | 返回 PONG |
以上就是Docker安装后阿里云Redis内网不通的排查与修复指南的详细内容,更多关于Docker安装Redis内网不通的资料请关注脚本之家其它相关文章!
