《桥》是人们熟悉的南斯拉夫影片,讲述的是二战时期,英勇的南斯拉夫人民为了歼灭侵略军,炸毁了敌军逃亡路线上的桥梁的故事。
二战胜利后,以中国人民为代表,世界上被帝国主义压迫的国家纷纷举起了独立自由的旗帜,并展开了壮丽的工业化建设画卷。
南京长江大桥就是我国劳动人民敢于否定专家脱离实际的方案,利用简单直接的方案,实现了跨长江的互联互通。
在K8S网络中,也有这么一种简单直接的方案——网络桥接。 这种方案叫做bridge。
在bridge方案中,每个宿主机上的pod都通过veth pair连接到网桥。(什么是veth pair? 请戳这里)
如图,每个node上的组网如下图:
这个图太经典了,以后我们会经常回顾。
将它放大,钻到每个pod内部和Node内部,看到的是这样的——
如图,我们看到,bridge的veth11,veth12和veth13,跟3个pod的veth101, veth102, veth103互通。而veth0连接到物理网卡eth0上。
(实际上,在node的Linux操作系统看来,这些veth接口是属于自己控制下,分属于不同namespace而已)
在有多个node的时候,bridge可以将各个node上的不同pod连接起来,实现最简单直接的互联互通。
一个配置文件的样例如下:
{
"cniVersion": "0.3.1",
"name": "mynet",
"type": "bridge",
"bridge": "mynet0",
"ipam": {}
}
其中,cniVersion字段标识的是CNI插件版本,name字段表示的是网络名称。type强制要求为“bridge”。
bridge需要一个名称,我们给它起名为“mynet0”。
由于bridge处于纯二层模式,不感知IP地址,因此ipam(IP Address Management)字段不需要填写。
这样,bridge就虚拟出了一个纯二层交换机(俗称傻交换)。
如图所示,这样配置bridge以后,172.17.10.0/24这个网段(英文缩写:CIDR,Classless Inter-Domain Route,无类域间路由)的6个pod,在两个不同的node上运行。有了bridge以后,就可以利用这个插件让它们互联互通了。
但是,让我们思考一个问题:
如果有两个应用,分属不同的CIDR,而这两个应用又在不同的node上运行,能不能利用bridge让它们互联互通呢?
如图,假设有三组pod,分别运行nginx, tomcat和mysql,
它们分别使用CIDR:172.17.11.0/24,172.17.12.0/24和172.17.13.0/24。
实际上,这三组pod每组内部也是可以互通的。
但是,这样一来,会造成两个问题:
一、bridge这种互通方式,本质上是将所有pod放在一个二层域内,没有任何子网之间的隔离,任何BUM数据包都会被复制到所有pod。当pod数超过500,BUM泛洪数量是不可接受的。
二、bridge这种互通方式,缺少“网关”(gateway),这会让各个子网之间无法通信,也就是说,nginx的pod无法访问tomcat的pod!
怎么样才能解决这两个问题呢?
请看下回分解。