原文链接:https://www.gogo-dev.com/index.php/2022/04/10/cni02/
说明
在上篇“容器网络接口标准v1.0.0”文章中我们提到了CNI标准定义了容器运行时应该如何解析网络配置、如何调用CNI插件,本文就从containerd项目来描述这部分实现。
由于下文会直接从containerd的源码开始分析,分析过程中会涉及到两个比较重要的子项目,为了让大家先对这两个子项目有个简单的印象,这里先列出了这两个子项目,
a. github.com/containerd/go-cni项目
containerd项目在CNI标准实现上又封装的一层抽象,提供了Setup、Remove、Check等接口为容器添加、移除、检查网络等。
b. github.com/containernetworking/cni项目
CNI网络组对于CNI标准的官方实现库,运行时可以直接调用该库从而调用CNI插件,比如下文提到了containerd直接调用的AddNetworkList接口。
代码流程
下文就以containerd拉起容器时需要为容器创建网卡为例开始讲解CNI的工作流程。当kubelet创建pod时会先向containerd发送请求先拉起sandbox容器,这个rpc请求就是RunPodSandbox,也是我们开始的入口:
github.com/containerd/containerd,版本v1.6.2
如果该sandbox不是使用的主机网络,也就是使用cni网络,因此根据cni标准中描述运行时需要先创建网络隔离空间,
创建完隔离空间后,containerd就进入准备容器网络的过程了,
目前containerd/go-cni中似乎只有libcni一种实现,我们之间转到libcni实现的Setup函数,
从上可知,containerd的go-cni项目就只是对containernetworking/cni库做了一层封装。接下来我们就来看看官方的cni库实现。
github.com/containernetworking/cni,版本v1.0.0
CNI接口定义:
首先关注一下入参list *NetworkConfigList,这个即CNI标准里定义的网络配置,
再看一下另一个入参rt *RuntimeConf,这个就对应CNI标准里容器运行时需要传递给插件的参数,
看完传递的参数,我们接着往下看Add操作执行过程,
插件的addNetwork接口,
至此,运行时调用CNI插件的ADD流程就结束了。
总结
containerd在创建sandbox容器的时候,会为容器准备网络,即完成了CNI标准中定义的Runtime容器运行时需要完成的步骤调用了各插件列表的Add接口。