Docker 网络 IP 地址冲突,就该这么处理!

简介: Docker 网络 IP 地址冲突,就该这么处理!


Docker 网络 IP 地址冲突这个问题其实稍微有一点点麻烦,网上也没有看到有比较全面正确的文章, 值得单独写一篇记录一下。

1前置知识

因为交换机的能力有限制,以及网线的连接不可能无限长, 所以我们不可能把所有的主机都连到同一个交换机上,然后处于同一个二层网络中。

就算能,主机间的 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/1610.0.0.2/16是同一个子网的两个主机。10.0.0.1/1610.1.0.1/16是不同的子网的两个主机。

这里只是简单粗暴的介绍下,更多的信息还是自己去查资料了解学习。

2问题表现

  • docker 进程无法启动
  • 容器端口无法访问,抓包显示为有入站但是没有出站

3排查

此处针对的是 dockerd 无法启动的情况,如果 dockerd 能启动,可以直接跳到解决一节

首先是看下日志

$systemctlstatusdocker $journalctl-udocker $dmesg|grepdocker

一般能看到如下日志:

docker0:linkisnotready docker_gwbridge:linkisnotready

或者更简单的排查方法,直接手动启动 dockerd 看看。启动方法可以通过grep ExecStart /usr/lib/systemd/system/docker.service查看。


一般来说按如下执行就行:

$/usr/bin/dockerd--debug

然后能看到最后输出:

INFO[2021-07-29T02:25:55.811673622Z]stoppingeventstreamfollowinggracefulshutdownerror="<nil>"module=libcontainerdnamespace=moby failedtostartdaemon:Errorinitializingnetworkcontroller:listbridgeaddressesfailed:PredefinedLocalScopeDefaultNetworksList:[10.252.0.0/2410.252.1.0/2410.252.2.0/24]:noavailablenetwork

这时候可以看下ip addr,是否有docker0docker_gwbridge

如果发现没有docker0,那基本可以肯定是 docker0 无法创建导致 dockerd 启动失败了。

4解决

找到占用的网段

默认的 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.0172.21.0.1255.0.0.0UG000eth0

也就是说10/8被占用了,导致和我的10.252.0/24冲突。后来联系网管删除了这条10/8的路由后解决。

修改 docker 占用的网段

以下操作需要先停止 docker 进程

$systemctlstopdocker

如果你用 docker service,那么 docker 会占用四个网段:

  1. docker0
  2. docker_gwbridge
  3. ucp(docker engine 占用,不常见)
  4. 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至少要有两项,按顺序依次为:

  1. docker0
  2. docker_gwbridge
  3. ucp

以防万一的话,配置三个是最好的 。

接下来是修改 ingress,这个比较麻烦,需要手动创建。

我的办法是在初始化 docker swarm 以后,启动 docker stack/service 以前,执行以下脚本:

  1. 删除 ingress
  2. 删除 my-ingress(不一定存在,不存在就忽略)
  3. 新建 my-ingress
$yes'y'|dockernetworkrmingress $yes'y'|dockernetworkrmmy-ingress2>&1|true $dockernetworkcreate\ --driveroverlay\ --ingress\ --subnet=10.252.3.0/24\#指定ingress的网段,不要和上面daemon.json的网段冲突 --gateway=10.252.3.2\ --optcom.docker.network.driver.mtu=1200\ my-ingress

ingress 是默认名,之所以新建一个名字不一样的,是因为删除 ingress 是异步的。如果你删除 ingress 后立刻新建一个也叫 ingress 的网络,很可能会报一个重名的错误。

重启 docker 前,最好先清理一下 docker 的缓存:

$iplinkdeldevdocker0 $iplinkdeldevdocker_gwbridge $rm-rf/var/lib/docker/network

另一种粗糙简单的解决办法

另一种粗糙简单的解决办法就是干脆直接手动创建一个 docker0。

这种解决方法最简单,但是机器 reboot 后 docker0 会自动被删掉, 所以这方法并不持久。

而且,实际上也不一定能解决网段冲突的问题,只是说 docker 能启动了而已。

iplinkaddnamedocker0typebridge ipaddradddevdocker010.252.0.1/24
相关文章
|
6天前
|
NoSQL 关系型数据库 MySQL
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
91 56
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
|
18天前
|
安全 Docker 容器
docker的默认网络模式有哪些
Docker 默认网络模式包括:1) bridge:默认模式,各容器分配独立IP,可通过名称或IP通信;2) host:容器与宿主机共享网络命名空间,性能最优但有安全风险;3) none:容器隔离无网络配置,适用于仅需本地通信的场景。
32 6
|
21天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
54 7
|
22天前
|
网络安全 Python
Python网络编程小示例:生成CIDR表示的IP地址范围
本文介绍了如何使用Python生成CIDR表示的IP地址范围,通过解析CIDR字符串,将其转换为二进制形式,应用子网掩码,最终生成该CIDR块内所有可用的IP地址列表。示例代码利用了Python的`ipaddress`模块,展示了从指定CIDR表达式中提取所有IP地址的过程。
36 6
|
27天前
|
网络协议 安全 文件存储
动态DNS(DDNS)技术在当前网络环境中日益重要,它允许使用动态IP地址的设备通过固定域名访问
动态DNS(DDNS)技术在当前网络环境中日益重要,它允许使用动态IP地址的设备通过固定域名访问,即使IP地址变化,也能通过DDNS服务保持连接。适用于家庭网络远程访问设备及企业临时或移动设备管理,提供便捷性和灵活性。示例代码展示了如何使用Python实现基本的DDNS更新。尽管存在服务可靠性和安全性挑战,DDNS仍极大提升了网络资源的利用效率。
48 6
|
28天前
|
安全 网络安全 数据安全/隐私保护
利用Docker的网络安全功能来保护容器化应用
通过综合运用这些 Docker 网络安全功能和策略,可以有效地保护容器化应用,降低安全风险,确保应用在安全的环境中运行。同时,随着安全威胁的不断变化,还需要持续关注和研究新的网络安全技术和方法,不断完善和强化网络安全保护措施,以适应日益复杂的安全挑战。
42 5
|
1月前
|
网络协议 网络安全 网络虚拟化
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算。通过这些术语的详细解释,帮助读者更好地理解和应用网络技术,应对数字化时代的挑战和机遇。
88 3
|
1月前
|
存储 网络协议 安全
30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场
本文精选了 30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场。
83 2
|
1月前
|
网络协议 Linux
使用nmcli命令设置IP地址并排查网络故障
nmcli 是一个功能强大的网络管理工具,通过它可以轻松配置IP地址、网关和DNS,同时也能快速排查网络故障。通过正确使用nmcli命令,可以确保网络配置的准确性和稳定性,提高系统管理的效率。希望本文提供的详细步骤和示例能够帮助您更好地掌握nmcli的使用方法,并有效解决实际工作中的网络问题。
61 2
|
2月前
|
Docker 容器
docker swarm启动服务并连接到网络
【10月更文挑战第16天】
45 5