上回我们说到,bridge插件在kubernetes的node之间,为pod的互联互通架起了简单直接的一座大桥,像南京长江大桥一样实现了天堑变通途。
随着历史的车轮转动,当一位老人在祖国的南海边画下那个圈的时候,一座神奇的桥,在北京拔地而起,这就是——西直门立交桥。
上错图了,应该放这个:
还是不对,应该是这个:
为什么要修建如此复杂的立交桥呢?
当然,是因为简单的桥梁无法满足复杂交通的需求。
类似市政交通的世界里那样,在容器的世界里,使用bridge插件,作为kubernetes的网络实现,虽然简单而直接,但有两个问题:
一、bridge这种互通方式,本质上是将所有pod放在一个二层域内,没有任何子网之间的隔离,任何BUM数据包都会被复制到所有pod。当pod数超过500,BUM泛洪数量是不可接受的。
二、bridge这种互通方式,缺少“网关”(gateway),这会让各个子网之间无法通信,也就是说,nginx的pod无法访问tomcat的pod!
这两个问题实际上是有解的。
对于第一个问题,bridge是支持VLAN的。在配置文件中,有一个VLAN选项,通过这个选项,可以让bridge配置VLAN access和VLAN trunk:
如图所示,我们可以为nginx, tomcat和mysql分配三个VLAN,对应它们各自的CIDR。这样,通过VLAN将广播域划分开,第一个问题就得以解决了。
第二个问题也是可以解决的。
bridge除了二层工作方式,还有三层工作方式。
它的三层工作方式配置文件如下:
{
"cniVersion": "0.3.1",
"name": "mynet",
"type": "bridge",
"bridge": "mynet0",
"isDefaultGateway": true,
"forceAddress": false,
"ipMasq": true,
"hairpinMode": false,
"ipam": {
"type": "host-local",
"subnet": "172.17.11.0/24"
}
}
和前面的配置文件相比,多了一些配置,但最核心的是这个地方:
isDefaultGateway:设置为true以后,bridge就可以工作在三层模式,具有三层转发的能力;
ipam字段配置了子网172.17.11.0/24,这样能够为VLAN内的pod分配地址。
需要注意一个细节:hairpinmode,如果打开这个开关,会导致bridge本身不做任何数据包交换转发,而是将数据包全部送到TOR交换机处理。这个问题将来再阐述。
通过这种方式,可以实现如下的组网——
如图,左边的node上运行了3个pod,每个pod均运行nginx,而右边的node上运行了3个pod,每个pod均运行tomcat。
但是,我们知道,实际上,为了让每个宿主机上的资源得以充分利用,容器编排平台会倾向于将不同的应用放在同一个node,让同一个node上运行着内存密集型、CPU密集型和磁盘I/O密集型的Pod,将宿主机上的资源压榨到极限。这时候,无论是使用bridge的二层模式,还是三层模式,都有无法满足pod之间互通需求的地方。
因此,人们开发了一个新的CNI插件——flannel。
请看下回分解。