在上期,我们介绍了CNI所需要实现的命令字和接口。常见的开源CNI实现有flannel和calico。
flannel是CoreOS推出的容器网络插件。flannel实质上是在kubernetes的每个node上部署一个flanneld作为routing table的外挂,并且操纵routing table进行数据包的处理。
flannel有三种工作模式:udp, vxlan和host-gw,最常见的是VXLAN模式。
如图,flanneld在node上会创建两个设备:
flannel.0端口就通往vtep,在vtep中进行VXLAN的封装和解封装。这样,数据包在发送流程和接收流程中都只进出一次内核,避免了过多的性能影响。
这种基于VXLAN Overlay的容器网络的好处在于,它不挑node之间的网络实现。node之间只要网络三层可达,就可以基于VXLAN实现容器之间的互联互通。
但是,VXLAN本身还是会有一定的开销的,会增加50Byte的包头,而封装和解封装也会增加少量的网络时延。因此,flannel还有另一种工作模式:Host-GW。
Host-GW模式的工作原理如下图:
如果node 172.16.112.10和node 172.16.112.20可以在同一个二层子网内,flanneld能够让pod A 到其他Pod的默认网关为route,通过cni0让route转发到下一跳。
route实际上为Linux内部协议栈,走默认路由即可将数据包转发到其他node(如果在同一个二层子网内)。但是,如果其他node不在同一个二层子网,flannel无法操纵node的下一跳 (如物理交换机) 学习通往其他node的路由,网络是无法打通的。
能够解决这一问题的网络插件叫calico。
calico的工作原理如上图。实际上,它在每个node上利用linux内核转发机制,实现了一个vrouter。vrouter的路由来自bird。此外,calico的控制平面还有felix模块修改iptables规则,来实现kubernetes的network policy。
calico有两种工作模式:ipip和bgp。前者的数据平面与VXLAN类似,是calico调用Linux的ipip封装功能实现的。calico的felix修改内核的fib表,让数据包的出接口指向tunl0,在tunl0上进行ipip封装。另一种方式叫做bgp方式,在无需进行封装的同时,还可以实现数据包的三层转发,如图:
图中,两个Pod可以通过L3 IP网络进行通信。
要满足L3 IP网络可以通信,需要具备什么条件呢?
让我们换一个视角来看问题:
在IP网络看来,Router X收到了一个数据包,其目的地址是172.17.10.162,应当匹配路由的下一跳。Router X根据相关转发表将其发送到了Router Y,而Router Y将这个数据包发到了172.16.210.10的Node上,最后送达Pod。
问题来了,怎么样让router X和router Y知道,172.17.10.162这个数据包应当送去哪里呢?
答案是,使用BGP传递路由。
BGP (Border Gateway Protocol)是一种互联网上最常见的传播路由的方式,BGP支持所谓的“路由反射器”(RR, Route Reflector),路由反射器可以将路由信息传递给每一个RR Client。在部署Calico的时候,需要一个路由反射器,如部署了bird的虚拟机,或Cisco ASR9900这样的路由器,同时,要让IP网络中的网络设备也从RR学习路由。
在RR及转发路径中所有交换机的配合下,Calico就可以让容器在不进行隧道封装的情况下,跨越现有网络进行通信了。
然而,无论是Calico还是flannel,在大型的公有云中部署都遇到了难以避免的问题。
在大型公有云中,往往使用虚拟机作为容器的工作节点,虚拟机之间通过隧道实现overlay,也就是所谓的VPC。如果再增加嵌套隧道会对性能造成显著的影响,而如果通过calico的路由方式转发,又难以让大型公有云宿主机上的vswitch去配合Bird RR实现BGP的学习。
工程师们为了解决这一问题,再次以史为鉴。
上期说到,苏共总书记勃列日涅夫的野心破灭后,从1976年起,身体健康情况每况愈下,最终在1982年去找列宁作检讨了。继任者安德罗波夫是克格勃资深情报员,期望通过克格勃与秘密警察来监督整个国家进步,复兴伟大的苏联,甚至命令警察把上班摸鱼跑出来玩的工人抓回去工作。显然,这种方式无法解决问题,而安德罗波夫在1984年也因肾衰竭等原因,去向列宁复盘自己执政得失了。
安德罗波夫的继任者是病入膏肓的契尔年科。13个月后,列宁又将契尔年科召唤走了。最终,庞大的红色帝国在戈尔巴乔夫手中终结,1991年12月25日,克里姆林宫顶的镰刀锤子旗缓慢降下。
数十年来,为理想而战斗的人们对苏联的历史进行了全面复盘,认为其中一大原因是,社会资源层(人民)与应用调度层(干部)发生了严重的脱节,而这一教训也一直在警醒着后来者。
因此,如果期望在大型云计算平台中做好容器网络的实现,就需要让应用调度层(容器)与资源层(虚拟机)紧密结合。
那么,世界上最先进的云计算平台是怎么做的呢?
请看下期。