在上期,我们复习了《钢铁是怎样炼成的》中,保尔,冬妮娅和达雅之间的故事,也理解了公有云的容器网络实现方式之一——TKE Global Router。
TKE Global Router的实现方式简单直接:为每个Kubernetes工作节点(worker node)分配一个C类网段,在该node上的所有Pod均赋予属于该网段的IP,并将node作为路由节点。
该方案有一个问题:由于网段和Pod是对应的,如果一个pod被驱逐并调度到其他node上,这个pod的网段会发生改变,也就是ip地址一定会改变。虽然Kubernetes提供了service等机制来实现屏蔽ip地址,但极少数应用由于历史原因,不得不要求IP地址恒定不变,而Global Router无法满足该需求。
另一个问题是Global Router方案中,来自Pod的数据包要经过Node上的Router模块转发,增加了时延。对于一些时延敏感业务的关键路径,工程师们期望避免这种额外转发带来的时延增加。那么,是否有更合适的方案呢?
在TKE中,提供了另一种插件,叫做VPC-CNI。从字面意义上理解,就是通过CNI插件,将Kubernetes的Pod直接接入VPC。这是如何实现的呢?
我们回顾一下虚拟机CVM接入VPC的方式:
如图,虚拟机CVM操作系统GuestOS看到的网卡实际上是Virtio-net提供的虚拟网卡,GuestOS协议栈调用virtio-net网卡驱动发送的数据包在内核态,被宿主机内核的vHost模块处理,并且送到vswitch进行VPC隧道封装后从物理网络发出。在虚拟机建立后,也可以为虚拟机添加更多的virtio-net设备接入到同一VPC,分配同一子网网段或不同子网网段的IP地址,这叫做弹性网卡 (elastic NIC)。其实现如下图所示:
如图,虚拟机CVM上有3个弹性网卡ENIC,均可通过vSwitch接入到VPC。(为什么不是接入到不同VPC请自行思考)
我们将CVM上的多个弹性网卡分配到不同的pod,就可以实现pod经过NIC直接通到VPC了!
如图,如果一个CVM上有多个弹性网卡,只需要自身保留1个用于连接VPC,其他的都可以给Kubernetes的Pod使用。这样一来,pod就可以和cvm共处于同一个网段,还可以保持固定IP。
如图,CVM X和CVM Y上各有两个Pod,其中Pod C的IP地址和Pod A的IP地址在同一网段。所有的Pod和CVM都加入了同一个VPC,共用172.18.0.0/16的网段,而Pod C和Pod A可以加入同一个子网。
进一步地,我们还可以把pod和cvm放在同一个负载均衡下:
这样可以实现应用的微服务灰度迭代改造。
我们在前一期讲到,保尔和冬妮娅的爱情以分手的悲剧而告终,其表面原因是保尔的思想在革命的战斗中逐渐进步,而冬妮娅并没有跟随保尔,两个人的差距越来越大。实际上,这是因为冬妮娅的思想深处没有实现对灰度迭代的支持,无法跟随保尔成长为无产阶级战士。
所谓灰度迭代,就是将旧的体系各个组件逐渐替换为新的体系。在应用微服务改造中,部分较为关键的应用组件容器化改造存在风险,可以先将其一部分实例进行容器化,并且和原先运行在虚拟机中的实例并行挂载在负载均衡下,待运行稳定后再逐渐全量替换成容器化实例。而TKE的VPC-CNI功能,为应用开发者提供了支持这一灰度迭代方法的工具。
今天我们有两个收获:
1. 理解了VPC-CNI的工作原理;
2. 理解了人的进步需要灰度迭代,跟不支持灰度迭代的人谈恋爱很难有结果;
下期我们会一起看更精彩的内容——如何改造思想内核。
敬请期待。