Flannel网络
Flannel是CoreOS团队针对kubernetes设计的覆盖网络(Overlay Network)工具,Flannel通过给每台宿主机分配一个子网为容器提供虚拟网络,使用UDP封装IP包来创建overlay网络,并借助etcd维护网络的分配情况。
flannel网络backend解决方案:
- hostgw 直接路由,适合局域网,性能好,仅适合二层可达的局域网
- vxlan 是flannel推荐的方式,需要通信的网络设备支持vxlan,具备很好的跨局域网通信,但使用了隧道封装,性能较差
- udp 改方式于vxlan很类似,对ip层网络进行封装,通常用于调试环境或者不支持vxlan协议的网络环境
Flannel vxlan原理图:
IP package解包:
- 头部TCP头部信息封装源宿主机到目的宿主机IP,MAC地址封装源MAC到下一跳MAC地址的网络信息
- 封装vxlan头部信息,指明改网络包是overlay网络包
- 内部封装容器源mac地址到目的mac地址,源容器IP到目的IP的信息
flannel的的大致工作原理:
- 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,flanneld服务监听在网卡的另外一端。
- flannel通过etcd维护了一张节点间的路由表,该张表保存了各个节点主机的子网网段信息
- 源主机的flanneld服务将原本的数据内容udp封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网络,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样的由docker0路由到达目标容器
flannel网络实验可参考:https://jusene.github.io/2018/04/13/docker-flannel/
Kubernetes中flannel网络
- cni0: 网桥设备,每创建一个pod都会创建一对veth pair,其中一端是pod的eth0,另一端是cni0网桥中的端口,pod中从eth0的流量都会到cni端口
1 | ~]# brctl show |
2 | bridge name bridge id STP enabled interfaces |
3 | cni0 8000.a2ed1ec1f6fa no veth382beee9 |
4 | vethf1a85950 |
5 | docker0 8000.0242b9ef22c0 no |
1 | ~]# ifconfig cni0 |
2 | cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 |
3 | inet 10.20.2.1 netmask 255.255.255.0 broadcast 10.20.2.255 |
4 | ether a2:ed:1e:c1:f6:fa txqueuelen 1000 (Ethernet) |
5 | RX packets 44921 bytes 3152070 (3.0 MiB) |
6 | RX errors 0 dropped 0 overruns 0 frame 0 |
7 | TX packets 47841 bytes 17248924 (16.4 MiB) |
8 | TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 |
cni0设备获取到的地址是分配到本机网络的第一个ip
- flannel.1 overlay网络设备,用来进行vxlan的报文处理(封包和解包);不同node之间的Pod数据流量都从overlay设备以隧道的形式发送到对端
1 | ~]# ifconfig flannel.1 |
2 | flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 |
3 | inet 10.20.2.0 netmask 255.255.255.255 broadcast 0.0.0.0 |
4 | ether 32:5b:33:4e:42:50 txqueuelen 0 (Ethernet) |
5 | RX packets 5 bytes 420 (420.0 B) |
6 | RX errors 0 dropped 0 overruns 0 frame 0 |
7 | TX packets 5 bytes 420 (420.0 B) |
8 | TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 |
- flanneld: flannel会在每个主机运营flanneld作为agent,它会会主机在集群网络地址空间中获取一个小网段,本机内所有容器的IP地址都从中分配;同时flanneld会监听etcd,为flannel.1设备提供封装时必要的mac、ip等网络数据信息
解析
1 | ~]# kubectl get pod --all-namespaces -o wide |
2 | NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES |
3 | default test-skaffold-6d8ff678d-ldhqm 1/1 Running 0 3m24s 10.20.1.5 k8s-node1 <none> <none> |
4 | kube-system coredns-85b4878f78-gtknx 1/1 Running 0 45s 10.20.2.4 k8s-node2 <none> <none> |
从10.20.1.5访问10.20.2.4
- 进入容器查看路由
1 | / # route -n |
2 | Kernel IP routing table |
3 | Destination Gateway Genmask Flags Metric Ref Use Iface |
4 | 0.0.0.0 10.20.1.1 0.0.0.0 UG 0 0 0 eth0 |
5 | 10.20.0.0 10.20.1.1 255.255.0.0 UG 0 0 0 eth0 |
6 | 10.20.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 |
网关指向cni0的ip
- 在宿主机上查看路由表
1 | ~]# route -n |
2 | Kernel IP routing table |
3 | Destination Gateway Genmask Flags Metric Ref Use Iface |
4 | 0.0.0.0 10.211.55.1 0.0.0.0 UG 100 0 0 eth0 |
5 | 10.20.0.0 10.20.0.0 255.255.255.0 UG 0 0 0 flannel.1 |
6 | 10.20.1.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0 |
7 | 10.20.2.0 10.20.2.0 255.255.255.0 UG 0 0 0 flannel.1 |
8 | 10.211.55.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0 |
9 | 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 |
路由指向flannel.1
- flannel.1
flannel.1为vxlan设备,当数据包来到flannel.1时,需要将数据包封装起来,vxlan需要封装mac地址信息,flannel.1通过flanneld程序从etcd中获取mac地址,并用此信息封装vxlan数据包。
简单流程:
- 数据包到达flannel.1通过查找路由表,知道数据包要通过flannel.1发往10.20.2.0
- 通过arp cache表,知道目的的ip 10.20.2.4的mac地址(对端flannel.1的mac地址)
- 对端flannel.1
对端eth0接受vxlan数据包,拆开数据包,转给flannel.1设备
1 | ~]# route -n |
2 | Kernel IP routing table |
3 | Destination Gateway Genmask Flags Metric Ref Use Iface |
4 | 0.0.0.0 10.211.55.1 0.0.0.0 UG 100 0 0 eth0 |
5 | 10.20.0.0 10.20.0.0 255.255.255.0 UG 0 0 0 flannel.1 |
6 | 10.20.1.0 10.20.1.0 255.255.255.0 UG 0 0 0 flannel.1 |
7 | 10.20.2.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0 |
8 | 10.211.55.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0 |
9 | 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 |
通过路由表 10.20.2.0 的数据包发往cni0
- cni0发送到pod
cni0是一个网桥设备,通过peer veth将数据包发给pod
查看arp cache
1 | ip n | grep 10.20.2.4 |
2 | 10.20.2.4 dev cni0 lladdr ea:ca:7c:a8:5b:60 REACHABLE |