docker-compose创建的网段与内网冲突时的解决方法

docker-compose创建的网段与内网冲突时的解决方法,第1张

Docker启动时会在宿主机上创建一个docker0的虚拟网桥,默认网段为172.17.0.1/16,恰好公司内网VPN使用的是172.18网段,这就导致在使用docker-compose部署的服务时,自动生成的网桥很容易与内网冲突,导致服务枝顷无法访问。

通过修改配猛脊陆置文件,把野蚂 docker0 指定其它网段,同时控制 docker-compose 创建容器时的网段范围。

具体步骤如下:

踩坑:

此时发现容器IP已经在设置的范围内,冲突问题解决。

摘要: Docker , 网桥 , Linux , 路由 , 网关

网上这个问题出现的挺多的,我也总结一下,因为里面涉及到的网络基础知识比较多的,正好我一直不懂这一块,需要大补

问题 :openvpn挂vpn连接远程搏嫌主机,发现无法ping通远程主机IP:172.20.2.52,以前一直可以远程登录

先 route 一波查看一下路由表,看一下主机访问172.20.2.52的路由路径

发现和目标IP 172.20.2.52相似的目标网段为 172.20.0.0 ,看后面的接口为 br-3b2a750ddc03 ,也即是说数据被转发到这个接口下,这貌似是个docker创建的网桥,怀疑是docker网桥占用了172.20网段,查看以下docker网络

看到3b2a750ddc03为命名为milvus的docker网络,原来是milvus的容器创建的网桥,进一步检查网络内部信息

可以看到所属的容器id和容器名

可见这个 网络接口下目标主机只有172.20.0.2,172.20.0.3,172.20.0.4三台主机IP,以及172.20.0.1网关,因此ping 172.20.2.52根本ping不通

milvus的三个容器虚拟IP以及网关服务占用了172.20网段,openvpn创建的网段也是172.20.0.0,因此在路由中产生 网段冲突 ,无法转发到openvpn的对应网络接口,同理从172.17、18、19、20都是docker创建出来的网络接口和网段,如果有其他网络服务处在相同网段可能导致无法路由到

在路由寻址时会根据目标IP在路由表中相同网络ID(网段)的记录,根据该记录将数据转发给下一个路由器,如果路由表中存在多条相同网络ID的记录,根据最长匹配算则最吻合的一个,因此增加一个 172.20.2.0/24 的目标网段即可,使用 route add 进行添加,添加目的地网段为172.20.2.0/24,网络接口为tun0

tun0是openvpn创建的网络接口,使用ifconfig查看

再看一下路由已经成功添加了一条细路由

此时再ping 172.20.2.52已经可以ping通

另一种方法是找到docker网桥对应的容器应用之后直接删除容器,则对应的网络接口和路由都会删除,进入milvus工程目录使用docker-compose停止和删除容器即可

查看route路由表172.20.0.0网段已经消失,ifconfig,docker network ls都已经查不到对应的网络接口,此时再重启openvpn即可

docker-compose默认会给每个应用从172.18.0.0依次往后匹配网段,只要容器没有被删除则一直占用网络,如果删除后重启则依次采用新的网段之前的不再使用,因此很容易造成路由冲突,可以在单个docker-compose.yml文件中增加networks配置,设置网段为10.103.0.0/16

重启docker-compose,此时路由和docker网络都切换为了10.103.0.0/16网段

修改全局docker网络配置,docker自动分配的网段使用12.11.0.0/16,每个子网掩码划分为 255.255.255.0

重启docker

再重新启动docker-compose,项目切换为基漏手指定的网段

不仅是docker-compose,docker run启动的容器的虚拟IP也变更为指定的网段

网关 :网关是一个逻辑概念,网关是一个结点,是一个网络连接到另一个网络的关口, 实质上是一个网络通向其他网络的IP地址 。两个不同网段的网络结点之间通信需要使用网关,如果网络A的主机发现目标主机不在本地网络中就会把数据包发送到A的网关,再转发给网络B的网关,再转发给网络B。

路由器 :路由器是物理设备,路由器可以作为网关使用,通常指的网关就是路由器的IP。主机1.1要发送数据包给主机4.1,因为IP地址不再同一网段,主机会将数据包发送给本网段的网关路由器A。路由器A接收到数据包,查看数据包IP中的目标IP地址,在查找自己的路由表,数据包的目标IP地址是4.1,属于4.0网段,路由器A在路由表中搜芦查到4.0网段转发的接口是SO接口。于是,路由表A将数据包从SO接口转发出去。到达了网关路由器B,用同样的转发方法,从EO口转发出去,4.1主机接收发这个数据包。

docker-compose中可以设置网络,如果不显示设置网络这些容器都会被加入app_default网络,比如工程目录为test,则启动后的网络名为test_default,使用 docker network ls 可以查看网络列表, docker network inspect <network id>可以查看对应网络的配置。如果想要工程有特有的网段以及容器有特有的IP则需要在docker-compose.yml中设置自定义要网络,例子如下

具体的写法是在最下面设置一个工程全局的网络,并且在各个容器服务的最下面引用,在全局下使用subnet设置网段,各容器使用ipv4_address设置IP。重新启动后docker网络已经固定为172.100.0.0/16网段,各容器IP也改为自定义IP

当TCP/IP需要向某个IP地址发起通信时,它会对路由表进行评估,以确定如何发送数据包。评估过程如下:

1 .目的IP地址和路由表中每一个路由项的网络掩码进行相与计算,如果相与后的结果匹配对应路由项的网络地址,则记录下此路由项

2 .当计算完路由表中所有的路由项后,择优选择其中一条路由规则

每一个linux系统中都具有IP路由表,它存储了本地计算机可以到达的网络目的地址范围和如何到达的路由信息,本地计算机上的任何TCP/IP通信都受到路由表的控制,linux通过route 命令查看 Linux 内核的路由表。

使用案例:

(1)查看所有driver=bridge的docker网络

(2)删除已经无效的网络

如果哟啊删除正在使用的网络,需要先断开连接再删除网络

(3)清理无效网络,想通过这种方法清除历史曾经使用过的网段,但是没有达到预期效果,以后再研究

在公司一个环境CentOS7上安装完docker后,发现windows上 xshell的ssh突然断开无法连接,需要经过和服务器同网段的其他机器才能ssh上去。

经排桐租查,原来此环境windows机器余毕的IP 为172.17.79.88,竖轮芹安装docker(1.13.0)后docker创建了一个虚拟网络桥连,恰好也使用了172.17.1.0/16的网段,172.17.79.88直接找到了docker的网段IP(172.17.0.1),而部署目标服务器IP,从而导致无法通过Xshell ssh上目标服务器!

既然找到了原因,我们就让docker避开172.17.18.0/24网段,改成172.20.1.0/16,也避免与一般的家用路由器IP段相撞。

docker0:  mtu 1500 qdisc noqueue state DOWN

link/ether 02:42:6c:a8:3d:34 brd ff:ff:ff:ff:ff:ff

inet 172.17.0.1/16 scope global docker0

valid_lft forever preferred_lft forever

局域网保留地址:

A类:10.0.0.0/8      10.0.0.0~10.255.255.255

B类:172.16.0.0/12  172.16.0.0~172.31.255.255

C类:192.168.0.0/16  192.168.0.0~192.168.255.255

# vim /etc/default/docker

#添加1行:

DOCKER_OPTS="--bip=172.20.1.0/16"

#vim /etc/systemd/system/docker.service

# 如果docker.service文件不存在,则看 /lib/systemd/system/docker.service

[Service] 

EnvironmentFile=-/etc/default/docker

ExecStart=/usr/bin/dockerd  $DOCKER_OPTS

# systemctl restart docker

gw_bridge,然后重建gw_bridge

#  docker swarm leave

# docker swarm leave --force

# docker network rm  gw_bridge

docker swarm无法创建默认的gw_bridge

公司将172相关网段预占用,手动创建,需要指定subnet

# docker network create  --driver=bridge    --subnet 172.21.0.1/24  docker_gwbridge

这样就可用正常使用docker service create创建服务了。

该网段被占用可能导致的另外一个问题就是,docker run一个容器的时候提示:

Error starting daemon: Error initializing network controller: Error creating default "bridge" network: failed to parse pool request for address space "LocalDefault" pool "" subpool "": could not find an available predefined network 

解决办法,通过指定--bip启动docker daemon。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/tougao/12263617.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-22
下一篇2023-05-22

发表评论

登录后才能评论

评论列表(0条)

    保存