Docker网络IP地址冲突的解决方法

 更新时间:2023年06月30日 15:04:58   作者:laisky  
本文主要介绍了Docker网络IP地址冲突的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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

一、前置知识

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

就算能,主机间的 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="<nil>" 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

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

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

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

  • 删除 ingress
  • 删除 my-ingress(不一定存在,不存在就忽略)
  • 新建 my-ingress
yes 'y' | docker network rm ingress
yes 'y' | docker network rm my-ingress 2>&1 | true
docker network create \
  --driver overlay \
  --ingress \
  --subnet=10.252.3.0/24 \  # 指定 ingress 的网段,不要和上面 daemon.json 的网段冲突
  --gateway=10.252.3.2 \
  --opt com.docker.network.driver.mtu=1200 \
  my-ingress

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

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

ip link del dev docker0
ip link del dev docker_gwbridge
rm -rf /var/lib/docker/network

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

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

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

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

ip link add name docker0 type bridge
ip addr add dev docker0 10.252.0.1/24

 到此这篇关于Docker网络IP地址冲突的解决方法的文章就介绍到这了,更多相关Docker网络IP地址冲突内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Docker在Windows环境的搭建和使用详解

    Docker在Windows环境的搭建和使用详解

    这篇文章主要介绍了Docker在Windows环境的搭建和使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 手动构建自己的docker容器镜像实战

    手动构建自己的docker容器镜像实战

    这篇文章主要介绍了如何手动构建自己的镜像并上传到镜像仓库中,文中有详细的代码实例,需要的朋友可以参考阅读
    2023-04-04
  • docker容器存放目录磁盘空间满了的解决

    docker容器存放目录磁盘空间满了的解决

    这篇文章主要介绍了docker容器存放目录磁盘空间满了的解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • 解决Docker删除镜像报错:Error response from daemon:conflict:unable to delete xxx (cannot be forced)

    解决Docker删除镜像报错:Error response from daemon:con

    删除Docker镜像时遇到冲突,因为镜像正在被一个运行中的容器使用,解决方法是先停止并删除该容器,然后再尝试删除镜像,此外,还可以选择强制删除镜像,但这可能会导致数据丢失
    2024-11-11
  • 详解使用Docker容器来源码编译etcd

    详解使用Docker容器来源码编译etcd

    这篇文章主要介绍了详解使用Docker容器来源码编译etcd,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • IDEA使用Docker插件远程部署项目到云服务器的方法步骤

    IDEA使用Docker插件远程部署项目到云服务器的方法步骤

    这篇文章主要介绍了IDEA使用Docker插件远程部署项目到云服务器的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Docker容器搭建并运行实现过程详解

    Docker容器搭建并运行实现过程详解

    这篇文章主要介绍了Docker容器搭建并运行实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • 如何调整Docker中nginx的日志级别详解

    如何调整Docker中nginx的日志级别详解

    这篇文章主要给大家介绍了关于如何调整Docker中nginx的日志级别的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-09-09
  • docker-compose编排语法及使用说明

    docker-compose编排语法及使用说明

    Compose是用于定义和运行多容器Docker的工具,支持多配置文件、环境变量、网络和端口映射等功能,简化多容器应用部署,通过Dockerfile和docker-compose.yml配置,Compose实现多容器间的依赖、资源限制和日志管理,提高开发效率
    2026-06-06
  • docker下载运行java项目的实现步骤

    docker下载运行java项目的实现步骤

    本文主要介绍了docker下载运行java项目的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-12-12

最新评论