Docker网络IP地址冲突的解决方法
目录
- 一、前置知识
- 二、问题表现
- 三、排查
- 四、解决
- 1、找到占用的网段
- 案例
- 2、修改 docker 占用的网段
- 3、另一种粗糙简单的解决办法
这个问题其实稍微有一点点麻烦,网上也没有看到有比较全面正确的文章, 值得单独写一篇记录一下。
一、前置知识
因为交换机的能力有限制,以及网线的连接不可能无限长, 所以我们不可能把所有的主机都连到同一个交换机上,然后处于同一个二层网络中。
就算能,主机间的 ARP 广播也会让这个网络瞬间瘫痪。
所以我们得把主机拆分到一个个的小的子网里,然后通过路由器再并成三层网络。
我们俗称的 IP 地址其实由两个部分组成,网络地址和主机地址。 比如 10.0.0.1/8 中,第一个 10 是网络地址,后面的 0.0.1 是主机地址。 那我怎么知道怎么去拆分这两段呢?靠的就是子网掩码,也就是那个 /8。
IP 其实是由 32 位的二进制组成的,x.x.x.x 只是为了方便人类阅读将其转成了十进制。 有个简单粗暴的办法就是可以认为每一段都是 8 位,所以 /8 就代表第一段是网络地址。
同理,/16 就代表前两段都是网络地址,10.0.0.0/16 中, 网络地址是 10.0,后两位 0.0 代表每个子网中的主机地址。
比如 10.0.0.1/16 和 10.0.0.2/16 是同一个子网的两个主机。 10.0.0.1/16 和 10.1.0.1/16 是不同的子网的两个主机。
这里只是简单粗暴的介绍下,更多的信息还是自己去查资料了解学习。
二、问题表现
- docker 进程无法启动
- 容器端口无法访问,抓包显示为有入站但是没有出站
三、排查
此处针对的是 dockerd 无法启动的情况,如果 dockerd 能启动,可以直接跳到“解决”一节
首先是看下日志
systemctl status docker journalctl -u docker dmesg | grep docker
一般能看到如下日志:
docker0: link is not ready docker_gwbridge: link is not ready
或者更简单的排查方法,直接手动启动 dockerd 看看。 启动方法可以通过 grep ExecStart /usr/lib/systemd/system/docker.service 查看,
一般来说按如下执行就行:
/usr/bin/dockerd --debug
然后能看到最后输出:
INFO[2021-07-29T02:25:55.811673622Z] stopping event stream following graceful shutdown error="
" module=libcontainerd namespace=moby
failed to start daemon: Error initializing network controller: list bridge addresses failed: PredefinedLocalScopeDefaultNetworks List: [10.252.0.0/24 10.252.1.0/24 10.252.2.0/24]: no available network
这时候可以看下 ip addr,是否有 docker0 和 docker_gwbridge,
如果发现没有 docker0,那基本可以肯定是 docker0 无法创建导致 dockerd 启动失败了。
四、解决
1、找到占用的网段
默认的 docker0 网段是 172.17.0.0/16,docker_gwbridge 网段是 172.18.0.0/24,你需要确认下这两个网段是否被占用了。
最简单的方法就是 ping 一下,如果无响应的话,那么就说明没有被占用。
其次就是看一下本机的路由表 route -n,确认一下有没有冲突的段。 一般来说,你会发现相关网段要么已经被占用,要么是路由表里存在冲突。
案例
比如在我的环境里,我给 docker0 配置为 10.252.0/24,然后 dockerd 起不来。
排查后发现 route -n 里有这么一条:
10.0.0.0 172.21.0.1 255.0.0.0 UG 0 0 0 eth0
也就是说 10/8 被占用了,导致和我的 10.252.0/24 冲突。 后来联系网管删除了这条 10/8 的路由后解决。
2、修改 docker 占用的网段
以下操作需要先停止 docker 进程
systemctl stop docker
如果你用 docker service,那么 docker 会占用四个网段:
- docker0
- docker_gwbridge
- ucp(docker engine 占用,不常见)
- ingress
其中前三个的网段可以通过配置文件配置,第四个只能手动创建。
前三个网段会读取 /etc/docker/daemon.json 这个配置文件, 这个文件默认是没有的,需要手动创建。
{
"bip": "",
"default-address-pools": [
{"base": "10.252.0.0/24", "size": 24},
{"base": "10.252.1.0/24", "size": 24},
{"base": "10.252.2.0/24", "size": 24}
]
}
注意这个 default-address-pools 至少要有两项,按顺序依次为:
- docker0
- docker_gwbridge
- ucp
以防万一的话,配置三个是最好的
您可能感兴趣的文章
- 12-20Kubernetes中使用临时容器进行故障排查的方法
- 12-20Nginx设置HTTPS的方法步骤
- 12-20二进制方式安装 Kubernetes1.18.3版本实现脚本
- 12-20Nginx工作模式及代理配置的使用细节
- 12-20ZooKeeper分布式协调服务设计核心概念及安装配置
- 12-20Kubernetes部署可视化地图的十个步骤
- 12-20关于docker清理Overlay2占用磁盘空间的问题(亲测有效)
- 12-20Docker compose配置文件写法及命令使用示例
- 12-20openwrt安装docker并启动的操作方法
- 12-20云原生Kubernetes初始化容器Init使用教程


阅读排行
推荐教程
- 12-07一文教你怎么选择Tomcat对应的JDK版本
- 12-07新版Eclipse集成Tomcat时找不到server选项的解决方法
- 12-06IIS7 应用程序池自动回收关闭的解决方案
- 12-05Windows Server 2019安装VMware
- 12-05Windows服务器默认IE浏览器无法下载文件的解决方法
- 12-05Docker安装Jenkins全过程
- 12-19Zabbix SAML SSO 登录绕过漏洞的操作流程
- 12-15Docker-Compose搭建Spark集群的实现方法
- 12-14Docker Desktop无法正常启动解决(failed to start...)
- 12-14k8s 与docker空间使用分析与清理方法





