在上期的专题《五湖四海的友谊》中我们提到,Kubernetes为第三方开发者提供了CNI(Container Network Interface)接口,通过安装CNI插件,在创建pod的时候,调用CNI插件的API,实现pod自动化入网。同样地,在pod销毁的时候,释放相应的网络资源。
“无规矩,不成方圆”。我们如果想理解Kubernetes容器云平台的网络究竟是什么样,首先要理解它的规矩——CNI接口。
高能预警:以下可能涉及到一些程序代码,不过不要担心,也不要跳过去不看,因为,程序代码对没有编程基础的同学而言,并没有那么可怕……
让我们打开CNI接口的规约(Specifaction):
https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration
在这个链接里面,约定了CNI插件应当遵守什么样的规范:
当我们阅读完CNI的Spec后,不禁赞叹:
大道至简!
CNI实际上是一个可执行文件。
它只需要实现4种操作:
增,删,查,自述。
顾名思义,“增”是指将容器连接到网络。
“增”对应CNI的命令:ADD。ADD命令需要的输入包括以下内容:
容器ID——可以理解为容器的身份证号;
容器Namespace路径——可以理解为容器的户口所在地;
网络配置——以JSON格式描述的网络配置,包含网络IP、子网掩码、DNS等信息,一个例子:
{
"cniVersion": "0.4.0",
"name": "dbnet",
"type": "bridge",
// type (plugin) specific
"bridge": "cni0",
"ipam": {
"type": "host-local",
// ipam specific
"subnet": "10.1.0.0/16",
"gateway": "10.1.0.1"
},
"dns": {
"nameservers": [ "10.1.0.1" ]
}
}
从各个字段的描述,很容易看出,上面的JSON描述的是一个容器入网的需求。
它的网络类型为bridge,我们在后面会以此为例子,分析bridge这个CNI插件的实现。
另一个例子:
{
"cniVersion": "0.4.0",
"name": "pci",
"type": "ovs",
// type (plugin) specific
"bridge": "ovs0",
"vxlanID": 42,
"ipam": {
"type": "dhcp",
"routes": [ { "dst": "10.3.0.0/16" }, { "dst": "10.4.0.0/16" } ]
},
// args may be ignored by plugins
"args": {
"labels" : {
"appVersion" : "1.0"
}
}
}
这个JSON描述的是使用了OVS作为网桥的容器入网,后面也会讲到它的实现方式。
“删”指的是命令DEL,它的作用是将一个容器从网络中删除,一般用于容器销毁时。它的输入与“增”类似。
“查”指的是命令CHECK,可以确认容器的网络配置是否和JSON中的描述一致。
“自述”指的是命令VERSION,可以用于确认CNI版本信息。
了解了这些关于CNI的输入输出规范,我们可以看出,kubelet和CNI的关系实际上如下图:
这构成了一个完美简洁的闭环,果然是大道至简!
在后面的专题中,我们将分析一些CNI的实现,敬请期待——