一.docker网络类型

bridge

默认类型,docer启动后宿主机默认创建docker0,默认创建的容器的IP与docker0在一个网段

host

容器与宿主机共享网络,与宿主机一模一样,无独立的network namespace

none

容器没有可用IP,只有一个环回口网卡lo,无法与外界通信,network namespace是独立的

container

与指定的容器使用一模一样的network namespace,网卡配置相同

自定义

自定义network名字,实际是bridge类型,如--net lnmp,同一个lnmp同一个网段,从docker0里面重新划分一个子网

二.修改默认分配的容器IP网段与宿主机路由查看

docker启动默认有两个IP网段,可为容器分配IP,分配的IP默认是与docker0一个网段

172.17.0.0/16 dev docker0

172.18.0.0/16 dev br-6d7ae1d4f0cb

可以自定义容器的默认IP网段,/etc/docker/daemon.json,如定义容器的ip网段为10.10.0.0/16,注意daemon.json的每一类参数最后是逗号,分割的,上一类参数后面添加逗号后再添加内容

#/etc/docker/daemon.json增加以下的内容
 "default-address-pools": [
    {"base": "10.10.0.0/16", "size": 24}
 ]
  • 1.
  • 2.
  • 3.
  • 4.

修改后重启docker,systemctl restart docker,重启后172.17.0.0/16 dev docker0变为10.10.0.0/24 dev docker0

#docker启动后未创建容器的宿主机上路由
[root@doker ~]# ip route  
default via 192.168.77.2 dev ens33 proto static metric 100  
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1  
172.18.0.0/16 dev br-6d7ae1d4f0cb proto kernel scope link src 172.18.0.1  
192.168.77.0/24 dev ens33 proto kernel scope link src 192.168.77.130 metric 100  
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
#docker启动后未创建容器的宿主机上路由,修改后
[root@doker ~]# ip route
default via 192.168.77.2 dev ens33 proto static metric 100 
10.10.0.0/24 dev docker0 proto kernel scope link src 10.10.0.1 
172.18.0.0/16 dev br-6d7ae1d4f0cb proto kernel scope link src 172.18.0.1 
192.168.77.0/24 dev ens33 proto kernel scope link src 192.168.77.130 metric 100 
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

三.验证

bridge:默认类型,docer启动后宿主机默认创建docker0,默认创建的容器的IP与docker0在一个网段

docker网络类型与IP路由冲突排错_IP

#创建容器,默认网络类型bridge
docker run -itd --name bs1 busybox
#进入容器后查看IP
docker exec -it bs1 sh
#容器eth0的IP与docker0一个网段,还有一个环回口lo
ifconfig
#路由追踪,容器eth0的IP---docker0网关---宿主机eth0网关
traceroute 223.5.5.5
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

host:容器与宿主机共享网络,与宿主机一模一样,无独立的network namespace

docker网络类型与IP路由冲突排错_IP_02

#创建容器,指定网络类型host --net host
docker run -itd --name bs2 --net host busybox
#进入容器后查看IP
docker exec -it bs2 sh
#容器网卡与宿主机网卡一模一样
ifconfig
#路由追踪,直接到宿主机eth0网关
traceroute 223.5.5.5
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

none:容器没有可用IP,只有一个环回口网卡lo,无法与外界通信,network namespace是独立的

docker网络类型与IP路由冲突排错_网络类型_03

#创建容器,指定网络类型none --net none
docker run -itd --name bs3 --net none busybox
#进入容器后查看IP
docker exec -it bs3 sh
#只有一个环回口lo 127.0.0.1
ifconfig
#路由追踪,无法与外界通信
traceroute 223.5.5.5
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

container:与指定的容器使用一模一样的network namespace,网卡配置相同

docker网络类型与IP路由冲突排错_IP_04

#创建容器,指定容器名字 --net container:被指定的容器name
docker run -itd --name bs4 --net container:bs1 busybox
docker run -itd --name bs5 --net container:bs2 busybox
docker run -itd --name bs6 --net container:bs3 busybox
#进入容器后查看IP
docker exec -it bs4 sh
docker exec -it bs5 sh
docker exec -it bs6 sh
#与被指定的容器一模一样的网卡
ifconfig
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

自定义:自定义network名字,实际是bridge类型,如--net lnmp,同一个lnmp同一个网段,从docker0里面重新划分一个子网

docker网络类型与IP路由冲突排错_IP_05

路由查看

#查看路由,多出一个子网10.10.1.0/24 dev br-1d9e08dac25e,lnmp网络类型容器的IP都从这个子网分配
[root@doker ~]# ip route
default via 192.168.77.2 dev ens33 proto static metric 100  
10.10.0.0/24 dev docker0 proto kernel scope link src 10.10.0.1  
10.10.1.0/24 dev br-1d9e08dac25e proto kernel scope link src 10.10.1.1  
172.18.0.0/16 dev br-6d7ae1d4f0cb proto kernel scope link src 172.18.0.1  
192.168.77.0/24 dev ens33 proto kernel scope link src 192.168.77.130 metric 100  
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
#创建自定义网络类型
docker network create lnmp
#查看没看到lnmp类型其实是bridge
docker network ls
#创建容器,指定自定义网络类型lnmp --net lnmp
docker run -itd --name bs7 --net lnmp busybox
docker run -itd --name bs8 --net lnmp busybox
docker run -itd --name bs9 --net lnmp busybox
#进入容器后查看IP
docker exec -it bs7 sh
docker exec -it bs8 sh
docker exec -it bs9 sh
#容器IP从10.10.1.0/24子网分配的
ifconfig
#路由追踪,traceroute:容器eth0的IP---新网桥br-xxx网关---宿主机eth0网关
traceroute 223.5.5.5
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

四.故障排查

问题现象:本地办公室电脑的客户端访问云上容器的web服务访问不到,容器web服务正常,云上安全组和本地防火墙都放行web服务的端口,排查宿主机的路由,发现了问题,云上容器返回本地电脑的路由匹配到了172.17.0.0/16走docker0了,没有走宿主机的eth0,出不去了。

这是为什么呢?因为默认路由查找的方式要遵循最长掩码匹配原则,试着分析一下

返回172.17.16.229/24的路由,在宿主机路由表中匹配,没匹配到172.17.16.229/32主机路由......没匹配到172.17.16.0/24路由......匹配到了172.17.0.0/16,匹配到后,路由出口是docker0,不是eth0。

docker网络类型与IP路由冲突排错_网络类型_06

解决方式一:宿主机添加路由

#临时添加
route add -net 172.17.16.0 netmask 255.255.255.0 dev eth0
#永久添加
echo "route add -net 172.17.16.0 netmask 255.255.255.0 dev eth0" >>/etc/rc.local
  • 1.
  • 2.
  • 3.
  • 4.

docker网络类型与IP路由冲突排错_IP_07

解决方式二:更改容器IP,需要重启docker

/etc/docker/daemon.json增加分配给容器IP的网段,默认是172.17.0.0/16 如改为172.19.0.0/16,更改后,原来使用172.17.0.0/16网段的容器,IP也会也会随着更改,因为容器的服务端口是端口映射的,所以的服务没影响。

#/etc/docker/daemon.json增加以下的内容
 "default-address-pools": [
    {"base": "172.19.0.0/16", "size": 24}
 ]
 #重启docerk
 systemctl restart docker
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.