docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Docker安装Redis内网不通

Docker安装后阿里云Redis内网不通的排查与修复指南

作者:Java小白笔记

Docker安装后访问阿里云内网服务如Redis出现丢包,很可能是docker0默认172.17网段与VPC网段冲突导致路由错误,本文教你如何修改Docker地址池快速解决内网不通问题,并提供详细排查步骤,需要的朋友可以参考下

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

关键线索:

[!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/810.0.0.0 ~ 10.255.255.255
172.16.0.0/12172.16.0.0 ~ 172.31.255.255
192.168.0.0/16192.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-poolsDocker 网络使用的地址池数组,可以定义多个池
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-mirrorslog-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/16VPC 使用 172.16~17.0.0/12
保守方案10.200.0.0/16VPC 使用 172.x 时,选 10.x 高段避开
极端保守192.168.100.0/16当 VPC 同时用了 10.x172.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/24172.30.1.0/24172.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 默认网桥 docker0172.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 安装后内网服务不通"时,按顺序检查:

序号检查项命令预期
1DNS 解析nslookup <域名>IP 正常返回
2docker0 地址ip addr show docker0与目标 IP 不在同一子网
3路由表ip route目标 IP 不走 docker0
4ping 测试ping <目标IP>正常收到回复
5应用验证redis-cli -h <host> ping返回 PONG

以上就是Docker安装后阿里云Redis内网不通的排查与修复指南的详细内容,更多关于Docker安装Redis内网不通的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文