Kubernetes通过一个叫做CNI的接口,维护了一个单独的网桥来代替docker0。这个网桥的
名字就叫作:CNI网桥,它在宿主机上的设备名称默认是:cni0。
容器“跨主通信”的三种主流实现方法:UDP、host-gw、VXLAN。 之前介绍了UDP和
VXLAN,它们都属于隧道模式,需要封装和解封装。接下来介绍一种纯三层网络方案,
host-gw模式和Calico项目
Host-gw模式通过在宿主机上添加一个路由规则:
<目的容器IP地址段> via <网关的IP地址> dev eth0
IP包在封装成帧发出去的时候,会使用路由表里的“下一跳”来设置目的MAC地址。这样,
它就会通过二层网络到达目的宿主机。
这个三层网络方案得以正常工作的核心,是为每个容器的IP地址,找到它所对应的,“下一
跳”的网关。所以说,Flannel host-gw模式必须要求集群宿主机之间是二层连通的,如果宿
主机分布在了不同的VLAN里(三层连通),由于需要经过的中间的路由器不一定有相关的路
由配置(出于安全考虑,公有云环境下,宿主机之间的网关,肯定不会允许用户进行干预和
设置),部分节点就无法找到容器IP的“下一条”网关了,host-gw就无法工作了。
Calico项目提供的网络解决方案,与Flannel的host-gw模式几乎一样,也会在宿主机上添加
一个路由规则:
<目的容器IP地址段> via <网关的IP地址> dev eth0
其中,网关的IP地址,正是目的容器所在宿主机的IP地址,而正如前面所述,这个三层网络方
案得以正常工作的核心,是为每个容器的IP地址,找到它所对应的,“下一跳”的网关。区
别是如何维护路由信息:
Host-gw : Flannel通过Etcd和宿主机上的flanneld来维护路由信息
Calico: 通过BGP(边界网关协议)来实现路由自治,所谓BGP,就是在大规模网络中实现节
点路由信息共享的一种协议。
隧道技术(需要封装包和解包,因为需要伪装成宿主机的IP包,需要三层链通):Flannel
UDP / VXLAN / Calico IPIP
三层网络(不需要封包和解封包,需要二层链通):Flannel host-gw / Calico 普通模式

概念

Veth设备 以两张虚拟网卡形式成对出现,从其中一个“网卡”发出的数据可以直接出现在它对应的另一张“网卡”上,可以跨network namespace
VTEP设备 (虚拟隧道端点) 既有IP又有MAC

Flannel

flannel支持三种后端实现,分别是:

  1. VXLAN (虚拟可扩展局域网)设备 flannel.1(vtep设备,既有IP也有MAC地址) flanneld负责维护VTEP设备信息和FDB信息,FDB记录了发往目标VTEP的数据应该通过宿主机的IP。VXLAN模式组建的覆盖网络,其实就是一个由不同宿主机上的VTEP设备,也就是flannel.1设备组成的虚拟二层网络对于VTEP设备来说,它发出的“内部数据帧”就仿佛是一直在这个虚拟的二层网络上流动。这,也正是覆盖网络的含义。
  2. host-gw: host-gw模式的工作原理,其实就是将每个Flannel子网(Flannel Subnet,比如:10.244.1.0/24)的“下一跳”,设置成了该子网对应的宿主机的IP地址。
  3. UDP 设备flannel0 (TUN设备)最早支持,性能最差, 三层的Overlay网络,需要经过三次用户态与内核态之间的数据拷贝 flanneld负责维护nodeIP

性能:

根据实际的测试,host-gw的性能损失大约在10%左右,而其他所有基于VXLAN“隧道”机制的网络方
案,性能损失都在20%~30%左右 .Flannel host-gw模式必须要求集群宿主机之间是二层连通的。

Calico:

二层连通:node-to-node模式,推荐在少于100个节点的集群里,更大规模用Route -Reflector
三层连通: IPIP模式 tunl0设备(IP隧道设备)性能与Flannel VXLAN大致相当,
除非硬性要求建议将所有宿主机节点放在一个子网里

CNI网络插件

kubernetes-cni包的目的是安装CNI插件所需的基础可执行文件,位于/opt/cni/bin下 可分为三类:

  1. Main插件 (包括bridge、ipvlan、loopback、macvlan、ptp[Veth Pair设备]、vlan) 用来创建具体网络设备的二进制文件 比如Flannel会调用其bridge这个二进制文件
  2. IPAM插件 (包括dhcp local-host[会使用预先配置的IP地址段进行分配])负责分配IP地址的二进制文件
  3. 由CNI社区维护的内置CNI插件 (比如flannel tuning[通过sysctl调整网络设备参数]、protmap[通过iptables配置端口映射]、bandwidth[使用TBF来进行限流])

CRI调用CNI插件通过加载CNI环境变量(CNI_COMMAND、CNI_IFNAME、CNI_NETNS、CNI_CONTAINERID等)和CNI配置文件将容器添加到CNI网络

其他

CNI配置文件是由CRI加载的 比如dockershim
Flannel插件要在CNI配置文件里声明hairpinMode=true。这样,将来这个集群里的Pod才可以通过它自己的Service访问到自己。