目录
一:什么是Flannel
Flannel 由coreOS开发,用于解决docker集群跨主机通讯的覆盖网络(overlay network),它的主要思路是:预先留出一个网段,每个主机使用其中一部分,然后每个容器被分配不同的ip;让所有的容器认为大家在同一个直连的网络,底层通过UDP/VxLAN/Host-GW等进行报文的封装和转发。
- Flannel实质上是一种“覆盖网络(overlaynetwork)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持udp、vxlan、host-gw、aws-vpc、gce和alloc路由等数据转发方式,默认的节点间数据通信方式是UDP转发。
- 它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。
- Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得同属一个内网且不重复的IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。
1.1 Flannel实现原理
- 集群中的不同节点上,创建的Pod具有全集群唯一的虚拟IP地址。
- 建立一个覆盖网络(overlay network),通过这个覆盖网络,将数据包原封不动的传递到目标容器。覆盖网络通过将一个分组封装在另一个分组内来将网络服务与底层基础设施分离。在将封装的数据包转发到端点后,将其解封装。
- 创建一个新的虚拟网卡flannel0接收docker网桥的数据,通过维护路由表,对接收到的数据进行封包和转发(vxlan)。
- etcd保证了所有node上flanned所看到的配置是一致的。同时每个node上的flanned监听etcd上的数据变化,实时感知集群中node的变化。
1.2 数据转发流程
- 容器直接使用目标容器的ip访问,默认通过容器内部的eth0发送出去。
- 报文通过veth pair被发送到vethXXX。
- vethXXX是直接连接到虚拟交换机docker0的,报文通过虚拟bridge docker0发送出去。
- 查找路由表,外部容器ip的报文都会转发到flannel0虚拟网卡,这是一个P2P的虚拟网卡,然后报文就被转发到监听在另一端的flanneld。
- flanneld通过etcd维护了各个节点之间的路由表,把原来的报文UDP封装一层,通过配置的iface发送出去。
- 报文通过主机之间的网络找到目标主机。
- 报文继续往上,到传输层,交给监听在8285端口的flanneld程序处理。
- 数据被解包,然后发送给flannel0虚拟网卡。
- 查找路由表,发现对应容器的报文要交给docker0。
- docker0找到连到自己的容器,把报文发送过去。
简单理解:
容器10.1.15.2/24访问10.0.20.3/24,经过所在主机的docker0,也就相当于这个容器的网关,转发到flannel0虚拟网卡,经过flanneld进行处理,将源容器的ip和目的容器的ip封装成内部ip,将源物理网卡的网关和目的物理网卡的网关封装成外部ip,并同时封装其MAC地址,源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后进入目的节点flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,传递到对应ip的容器
二: Flannel网络概述
Overlay Network:
覆盖网络,在基础网络上叠加的一种虚拟网络技术模式,该网络中的主机通过虚拟链路连接起来
类似VPN隧道,原理为在物理网络上实现的逻辑网络
VXLAN:
将源数据包封装到UDP中,并使用基础网络的IP/MAC作为外层包头进行封装,然后在以太网上传输,到达目的地后由隧道断电解封并将数据发给目标地址
Flannel:
是Overlay网络的一种,也是将源数据包封装在另一种网络包中进行路由转发和通信,目前已支持UDP、VXLAN、AWS VPN和GCE路由等数据转发方式
特点 | |
hostgw | 这种方式就是直接路由 |
vxlan | 是flannel推荐的方式。需要通信的网络设备能够支持vxlan协议 |
udp | 该方式与vxlan很类似,它对ip层网络进行包装。通常用于调试环境或者不支持vxlan协议网络环境中 |
2.1 Vxlan 模式
2.1.1 通信流程
不同node上的pod通信流程:
- pod中的数据,根据pod的路由信息,发送到网桥 cni0
- cni0 根据节点路由表,将数据发送到隧道设备flannel.1
- flannel.1 查看数据包的目的ip,从flanneld获取对端隧道设备的必要信息,封装数据包
- flannel.1 将数据包发送到对端设备。对端节点的网卡接收到数据包,发现数据包为overlay数据包,解开外层封装,并发送内层封装到flannel.1 设备
- Flannel.1 设备查看数据包,根据路由表匹配,将数据发送给cni0设备
- cni0匹配路由表,发送数据到网桥
2.1.2 部署
$ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 配置 Pod CIDR
$ vi kube-flannel.yml
"Network": "10.244.0.0/16",
# 多网卡时,可指定网卡
vi kube-flannel.yml
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
- --iface=ens38 # 指定网卡
$ 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
集群节点上网络分配:
$ 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.