一、Linux网桥和veth pair
1、Linux网桥,虚拟的交换机,工作在数据链路层,通过学习到MAC地址,将数据包转发到网桥的不同端口上。
2、Veth pair,可以理解为一根虚拟的网线,创建veth pair后,会以两张虚拟网卡的形式成对出现,在其中一个网卡发出的数据包,会直接出现在与它对应的另一张网卡上。
二、三种docker网络驱动
Docker默认会创建三种网络,分别为:none、host和bridge,可以通过命令docker network ls查看
# docker network ls NETWORK ID NAME DRIVER SCOPE 948cb107a456 bridge bridge local 59932afae000 host host local d16315c941e2 none null local
1、none网络驱动
none,就是什么都没有,在创建容器时,指定参数—network=none,使用ifconfig命令查看,可以看到只有lo的回环网卡。
# docker run -it --network=none busybox / # ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
2、host网络驱动
共享宿主机的网络栈,性能最佳,但是由于共享宿主机的网络栈,也共享了宿主机的网络端口资源。
在笔者的线上环境,为了网络性能,我们使用的就是host模式来部署zabbix server监控。
# docker run -it --network=host busybox / # ifconfig docker0 Link encap:Ethernet HWaddr 02:42:44:C8:BF:47 inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:100 errors:0 dropped:0 overruns:0 frame:0 TX packets:100 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:7702 (7.5 KiB) TX bytes:11897 (11.6 KiB) eth0 Link encap:Ethernet HWaddr FA:16:3E:38:3C:A1 inet addr:10.30.20.87 Bcast:10.30.20.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1016565 errors:0 dropped:0 overruns:0 frame:0 TX packets:169554 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:289066541 (275.6 MiB) TX bytes:35157980 (33.5 MiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:4 errors:0 dropped:0 overruns:0 frame:0 TX packets:4 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:200 (200.0 B) TX bytes:200 (200.0 B)
3、bridge网络驱动
Docker服务启动后,默认有一个名为docker0的网卡,在宿主机上可以用ifconfig查看到,分配的IP地址是172.17.0.1
# ifconfig docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:44:c8:bf:47 txqueuelen 0 (Ethernet) RX packets 100 bytes 7702 (7.5 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 100 bytes 11897 (11.6 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
使用bridge创建容器,可以看到容器的eth0网卡分配的IP地址是172.17.0.2,网关是172.17.0.1
# docker run -it --network=bridge busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) …… / # route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
在宿主机上使用brctl show查看,网桥docker0上“插入”了网卡vethc79f4a4,这个就是我们上面提到的veth pair,一端是vethc79f4a4接入网桥docker0,另一端就是容器里的eth0网卡
# brctl show bridge name bridge id STP enabled interfaces docker0 8000.024244c8bf47 no vethc79f4a4 # ifconfig vethc79f4a4 vethc79f4a4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 3e:d7:34:58:8b:ea txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
为什么docker0分配的IP地址是172.17.0.1?
# docker network inspect bridge …… "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ……
我们可以查看docker0分配的网段是172.17.0.0/16
最终使用网桥创建的容器的网络架构图如下