Kubernetes网络之CNI规范解读

May 11, 2022

image

CNI 简介

容器网络接口(Container Network Interface),简称 CNI,是 CNCF 旗下的一个项目,由一组用于配置 Linux 容器的网络接口的规范和库组成,同时还包含了一些插件。CNI 仅关心容器创建时的网络分配,和当容器被删除时释放网络资源。

使用CNI的容器运行时有:

  • Kubernetes
  • ContainerD
  • Mesos
  • Cloud Foundry
  • OpenShift

实现了CNI规范的网络插件有:

  • Flannel
  • Calico
  • Weave
  • Cilium
  • 等等

CNI插件

CNI 插件必须实现一个可执行文件,这个文件可以被容器管理系统(例如 rkt 或 Kubernetes)调用。

CNI 插件负责将网络接口插入容器网络命名空间(例如,veth 对的一端),并在主机上进行任何必要的改变(例如将 veth 的另一端连接到网桥)。然后将 IP 分配给接口,并通过调用适当的 IPAM 插件来设置与 “IP 地址管理” 部分一致的路由。

CNI规范

1. CNI定义规范版本,用来控制版本兼容性问题,但是版本不是一尘不变的。

2. 概念:

  • 容器是一个网络隔离域。
  • 网络是指一组可以唯一寻址的端点,它们可以相互通信。
  • Container Runtime是负责执行CNI插件的地方。
  • Plugin是指网络配置的程序。

3. 规范

CNI规范定义了5点:

    1. 系统管理员去定义网络配置的格式。
    1. Container Runtime向网络插件发起请求的协议。
    1. 基于系统管理员提供的配置执行插件,由第2步发起调用。
    1. CNI插件会将功能委托给其他插件。
    1. 插件返回result到container runtime的数据类型。

CNI Arch

3.1 网络配置

网络配置是具有如下字段的json格式:

  • cniVersion: 指定CNI规范的版本。
  • Name: 网络名字,这在主机的网络配置中应该唯一。
  • disableCheck: 是否禁用检查网络,如果为true,则 container runtime 不会调用 Check 方法进行网络检查。
  • plugin: cni插件及其配置列表,可以配置多个插件。
3.2 执行协议

CNI协议基于容器运行时调用插件二进制程序。CNI程序逻辑本身被封装在了libcni中,会被其他容器运行时调用。在libcni中总共暴露了 4 个核心方法:

type CNI interface {
    // 添加网络
    AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
    // 检查网络
	CheckNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
    // 删除网络
	DelNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) error
    // 获取网络缓存结果
	GetNetworkCachedResult(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
    // 获取网络缓存配置
	GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) ([]byte, *RuntimeConf, error)
    // 校验网络
	ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
}

CNI插件负责以某种方式配置容器的网络接口,通过标准输入提供配置,标准输出上返回结果,标准错误上返回error。

3.3 CNI操作

CNI插件定义了4个操作:ADD、DEL、CHECK、Version。

  1. ADD:添加容器到网络中,插件收到ADD命令执行如下步骤;不支持多次调用。
  • 在CNI_NETNS的容器中创建CNI_IFNAME的接口。
  • 调整CNI_NETNS容器内CNI_IFNAME的配置。
  1. DEL:从容器中删除网络,插件收到DEL命令执行如下步骤;支持多次调用。
  • 删除CNI_NETNS容器内的CNI_IFNAME定义的接口。
  • 撤销插件ADD功能中应用的修改。
  1. Check:检查容器的网络是否符合预期。

  2. Version:探测CNI插件版本是否支持。

CNI Plugin 项目

Plugin中提供了3个维度的插件,一个是main,用户创建网络接口的插件,一个ipam,用于管理ip地址的插件,可以被main插件调用,一个meta插件,就是其它插件。


LRF 记录学习、生活的点滴