Kubernetes CNI 学习笔记
文章目录
1. Overview
Kuberentes 对任何网络实现提出了以下要求:
- Pod 可以不借助 NAT 访问同一集群中任意 Node 上所有 Pod(包括自己)
- Node 上的服务可以不借助 NAT 访问同一集群中任意 Node 上所有 Pod
Kubernetes 采用了 CNI 规范,第三方厂商只要遵循该规范就可为 Kubernetes 实现 L3 层的网络自定义。
绝大部分 Kubernetes 网络插件包括两个部分:
- 二进制 CNI 文件:分配 Pod IP,创建虚拟网络设备,Pod插上网线。
- 网络模型:通过在 Kubernetese 运行 controller/agent 服务私有 overlay/underlay 网络,保证Pod联通性
CNI 规范主要对二进制 CNI 文件进行限制,而如何实现网络模型 Kubernetes 并没有要求。
2. CNI Spec
当前CNI 1.0.0依然处于开发状态,最新的稳定为 v0.4.0,不同版本之间CNI约束条件不一样,参数也不一样。
1. 限制
CNI和CRI交互时有以下几个约定:
- CRI实现调用CNI接口前,必须创建好相应的网络命名空间。
- CRI必须指定容器归属的网络,并且对于每个网络,CRI需要判断需要运行那些插件
- CNI的配置文件必须是JSON格式
- 单个容器加入/退出网络时,CRI串行运行插件
- 容器生命周期完成后,运行时必须以相反的顺序(相对于添加容器执行的顺序)执行插件,以使容器与网络断开连接
- 同一容器不能并行操作,但可以为不同容器调用并行操作
- ADD和DEL是顺序的,不能重复ADD,但是可以重复DEL(要求DEL应该是幂等的)
- CNI存储网络状态为:(network name, CNI_CONTAINERID, CNI_IFNAME)
2. 调用方式约定
- CNI插件必须实现成可执行文件给Kubernetes调用
- CRI会使用配置文件中的Type值调用二进制文件,Kubernetes原生集成了一些CNI插件,被放置在/opt/cni/bin目录下
以下是配置文件 calico-vxlan 的 cni 配置文件( /etc/cni/net.d/10-calico.conflist ):
|
|
上述配置文件中,串行定义了以下三个不同类型 CNI 插件,这些插件通过二进制的方式保存在 /opt/cni/bin/ 目录下,当 Kubelet 创建容器时依次调用这些二进制文件。
- calico
- portmap
- bandwidth
3. 调用接口约定
- 插件支持的Operations
- ADD:添加容器到网络,操作的输入如上面两点所描述,返回值如下
- Interfaces list:接口列表,根据CNI的实现有所不同
- IP configuration assigned to each interface:分配到容器的IP地址,路由、网关等信息
- DNS:容器内的DNS信息
- DEL:删除容器网络
- 所有参数和ADD一样,但是JSON参数中可能会多一个prevResult字段,该字段是ADD操作的返回值。如何不带这个字段表示删除容器中的所有网络资源,否则只删除prevResult字段描述的资源
- DEL操作要在不返回ERROR的情况下,尽可能回收分配的资源
- CHECK:检查容器的网络是否符合预期
- 输入参数和ADD完全一样,但是JSON参数中必须多一个prevResult字段
- 返回none或者抛出一个异常
- VERSION:返回CNI spec的版本信息
- ADD:添加容器到网络,操作的输入如上面两点所描述,返回值如下
4. 调用参数约定
- CRI通过环境变量的方式向这些二进制文件传递参数:
- CNI_COMMAND:操作类型,包括ADD、DEL、CHECK、VERSION
- CNI_CONTAINERID:容器ID
- CNI_NETNS:容器命名空间地址
- CNI_IFNAME:容器内网络设备名称
- CNI_ARGS:用户额外传递的参数,例如,“ FOO = BAR; ABC = 123”
- CNI_PATH:CNI插件执行文件的搜索路径,用":“分隔
- CNI插件的JSON配置信息,通过stdin流式传输到插件
- CNI插件的配置文件被保存在磁盘上(通常是/etc/cni/net.d/10-xxxx.conflist),或者由CRI实时生成
- JSON中通常会有一个插件列表,列表中的插件会串行运行
5. 返回值约定
插件通过标准输出流返回JSON格式的信息,主要包括:cniVersion、interfaces、ips、routes、dns 等信息
3.CNI 自带的插件
为了避免CNI插件开发者反复实现一些相同的功能,CNI项目维护了一些基础插件。这些插件的源码在:containernetworking/plugins,CNI官网有比较详细的说明文档。
-
IPAM类插件:
- dhcp plugin:基于DHCP的IP地址分配
- /opt/cni/bin/dhcp需要在宿主机上启动一个进程,这个进程是容器网络命名空间发送DHCP的代理,并不是DHCP服务器
- 服务端启动后会生成**
/run/cni/dhcp.sock**,CRI操作网络时通过这个通道将请求发送到宿主机的DHCP进程上
- host-local IP
- 可以指定IP
- 可以指定DNS配置
/var/lib/cni/networks/$NETWORK_NAME
- 静态IP
- dhcp plugin:基于DHCP的IP地址分配
-
Main插件:这类插件可以在容器内创建网络设备,或者关联网络设备到指定命名空间
- bridge
- ipvlan
- macvlan
- ptp:只创建一个veth对,相比bridge不会将veth的一端挂载到网桥上
- host-device:将请求的设备从主机的网络名称空间移动到容器的网络名称空间。
-
Meta类型的插件:辅助功能类的插件
文章作者 yoaz
上次更新 2022-03-15
许可协议 MIT