赞
踩
flannel是CoreOS提供用于解决Dokcer集群跨主机通讯的覆盖网络工具。它的主要思路是:预先留出一个网段,每个主机使用其中一部分,然后每个容器被分配不同的ip;让所有的容器认为大家在同一个直连的网络,底层通过UDP/VxLAN等进行报文的封装和转发。
Flannel 是一种“覆盖网络(overlay network)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持udp、vxlan、host-gw、aws-vpc、gce和alloc路由等数据转发方式,默认的节点间数据通信方式是UDP转发。
$ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
$ vi kube-flannel.yml
"Network": "10.244.0.0/16",
$ kubectl apply -f kube-flannel.yml
$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
kube-flannel-ds-8qnnx 1/1 Running 0 10s
kube-flannel-ds-979lc 1/1 Running 0 16m
kube-flannel-ds-kgmgg 1/1 Running 0 16m
不同node上的pod通信流程:
集群节点上网络分配:
$ ip addr 6: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default link/ether b6:95:2a:cd:01:c3 brd ff:ff:ff:ff:ff:ff inet 10.244.0.0/32 brd 10.244.0.0 scope global flannel.1 valid_lft forever preferred_lft forever inet6 fe80::b495:2aff:fecd:1c3/64 scope link valid_lft forever preferred_lft forever 7: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default qlen 1000 link/ether 16:ac:e9:68:a4:c0 brd ff:ff:ff:ff:ff:ff inet 10.244.0.1/24 brd 10.244.0.255 scope global cni0 valid_lft forever preferred_lft forever inet6 fe80::14ac:e9ff:fe68:a4c0/64 scope link valid_lft forever preferred_lft forever $ ethtool -i cni0 driver: bridge $ ethtoo -i flannel.1 driver: vxlan $ ps -ef | grep flanneld root 15300 15275 0 10:21 ? 00:00:19 /opt/bin/flanneld --ip-masq --kube-subnet-mgr $ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.80.2 0.0.0.0 UG 0 0 0 ens33 10.244.0.0 10.244.0.0 255.255.255.0 UG 0 0 0 flannel.1 10.244.1.0 10.244.1.0 255.255.255.0 UG 0 0 0 flannel.1 10.244.2.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0 192.168.80.0 0.0.0.0 255.255.255.0 U 0 0 0 ens33 $ brctl show bridge name bridge id STP enabled interfaces cni0 8000.e2ee89678398 no veth28b04daf vethe6d4a6b8
cni0: 网桥设备,每创建一个pod都会创建一对 veth pair。其中一段是pod中的eth0,另一端是cni0网桥中的端口。
flannel.1: vxlan网关设备,用户 vxlan 报文的解包和封包。不同的 pod 数据流量都从overlay设备以隧道的形式发送到对端。flannel.1不会发送arp请求去获取目标IP的mac地址,而是由Linux kernel将一个"L3 Miss"事件请求发送到用户空间的flanneld程序,flanneld程序收到内核的请求事件后,从etcd中查找能够匹配该地址的子网flannel.1设备的mac地址,即目标pod所在host中flannel.1设备的mac地址。
flanneld: 在每个主机中运行flanneld作为agent,它会为所在主机从集群的网络地址空间中,获取一个小的网段subnet,本主机内所有容器的IP地址都将从中分配。同时Flanneld监听K8s集群数据库,为flannel.1设备提供封装数据时必要的mac,ip等网络数据信息。
VXLAN(Virtual eXtensible Local Area Network,虚拟扩展局域网),采用L2 over L4(MAC-in-UDP)的报文封装模式,将二层报文用三层协议进行封装,可实现二层网络在三层范围内进行扩展,同时满足数据中心大二层虚拟迁移和多租户的需求。
flannel只使用了vxlan的部分功能,VNI被固定为1。容器跨网络通信解决方案:如果集群的主机在同一个子网内,则通过路由转发过去;若不在一个子网内,就通过隧道转发过去。
$ cat /etc/cni/net.d/10-flannel.conflist { "name": "cbr0", "cniVersion": "0.3.1", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } $ cat /run/flannel/subnet.env FLANNEL_NETWORK=10.244.0.0/16 FLANNEL_SUBNET=10.244.0.1/24 FLANNEL_MTU=1450 FLANNEL_IPMASQ=true # Bridge CNI 插件 $ cat /var/lib/cni/flannel/462cf658ef71d558b36884dfb6d068e100a3209d36ba2602ad04dd9445e63684 | python3 -m json.tool { "cniVersion": "0.3.1", "hairpinMode": true, "ipMasq": false, "ipam": { "routes": [ { "dst": "10.244.0.0/16" } ], "subnet": "10.244.2.0/24", "type": "host-local" }, "isDefaultGateway": true, "isGateway": true, "mtu": 1450, "name": "cbr0", "type": "bridge" }
kubectl delete -f kube-flannel.yml
ip link set cni0 down
ip link set flannel.1 down
ip link delete cni0
ip link delete flannel.1
rm -rf /var/lib/cni/
rm -f /etc/cni/net.d/*
$ vi kube-flannel.yml
"Backend": {
"Type": "host-gw"
}
$ kubectl apply -f kube-flannel.yml
$ kubectl get pod -n kube-system
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system kube-flannel-ds-l2dg7 1/1 Running 0 7s
kube-system kube-flannel-ds-tj2vg 1/1 Running 0 7s
kube-system kube-flannel-ds-xxhfm 1/1 Running 0 7s
host-gw采用纯静态路由的方式,要求所有宿主机都在一个局域网内,跨局域网无法进行路由。如果需要进行跨局域网路由,需要在其他设备上添加路由,但已超出flannel的能力范围。可选择calico等使用动态路由技术,通过广播路由的方式将本机路由公告出去,从而实现跨局域网路由学习。
所有的子网和主机的信息,都保存在Etcd中,flanneld只需要watch这些数据的变化 ,实时更新路由表。
核心是IP包在封装成桢的时候,使用路由表的“下一跳”设置上的MAC地址,这样可以经过二层网络到达目的宿主机。
集群节点上网络分配:
$ ip addr 7: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 2a:00:05:23:3f:5e brd ff:ff:ff:ff:ff:ff inet 10.244.2.1/24 brd 10.244.2.255 scope global cni0 valid_lft forever preferred_lft forever inet6 fe80::2800:5ff:fe23:3f5e/64 scope link valid_lft forever preferred_lft forever $ kubectl logs kube-flannel-ds-l2dg7 -n kube-system I1227 12:09:56.991787 1 route_network.go:86] Subnet added: 10.244.2.0/24 via 192.168.80.240 I1227 12:09:56.992305 1 route_network.go:86] Subnet added: 10.244.0.0/24 via 192.168.80.241 $ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.80.2 0.0.0.0 UG 0 0 0 ens33 10.244.0.0 192.168.80.241 255.255.255.0 UG 0 0 0 ens33 10.244.1.0 192.168.80.242 255.255.255.0 UG 0 0 0 ens33 10.244.2.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0 192.168.80.0 0.0.0.0 255.255.255.0 U 0 0 0 ens33
与 VxLan 一致
Flanneld 收到 EventAdded 事件后,从 etcd 将其他主机上报的各种信息,在本机上进行配置,主要分下列三种信息:
补充:
Kubelet、Container Runtime 和 CNI 插件交互:
Containerd CRI 插件和 CNI 插件之间的交互:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。