原文连接:https://github.com/containernetworking/cni/blob/master/SPEC.md
General consideration
CNI的想法是先让容器runtime为每个容器创建一个新的network namespace,之后再决定容器应该属于哪个network。而对于每个network,需要决定执行哪个插件。
CNI Plugin
Overview
每个CNI插件都是一个可执行文件,能被例如Docker这样的容器管理系统直接调用。通常,CNI插件用于将一个网卡插入容器的network namespace,并且在宿主机中做一些必要的配置。之后,还要给网卡赋上IP,并且通过调用合适的IPAM插件来建立和IP Address Management section一致的路由规则。
Parameters
ContainerID:该项是可选的但是必须的。不一定是实际的ContainerID,也可以是Pod ID,但必须保证全局唯一。
Network configuration:一个用于描述容器所加入的网络的JSON文件。
Extra argument:在每个容器的基础配置上提供了额外的灵活性。
Name of the interface inside the container:该名字需要被赋给容器内的网卡,通常,它需要和标准的Linux网卡命名规则一致。
Result
Interfaces list:对于不同的插件,该项有所不同,可能会包含sandbox的网卡名和宿主机网卡的名字,每个网卡的硬件地址,以及网卡所在的sandbox的一些细节。
IP configuration assigned to each interface:sandbox或者宿主机内的网卡的IPv4以及IPv6地址,网关以及路由。
DNS information:包含nameservers,domain,search domain以及其他DNS信息的字典
The executable command-line API使用网络的类型名作为调用的可执行文件的名字。它会在一系列预先定义的目录里面查找可执行文件。一旦找到,它就会用以下的环境变量作为参数调用该可执行文件:
- CNI_COMMAND:表示指定的操作;ADD,DEL或者VERSION
- CNI_CONTAINERID:容器ID
- CNI_NETNS:network namespace文件的路径
- CNI_IFNAME:创建的网卡的名字;plugin必须服从该命名或者返回一个错误
- CNI_ARGS:用户在调用时额外传入的参数。以包含数字和字母,用分号分开的键值对表示;例如,“FOO=BAR;ABC=123”
- CNI_PATH:用于查询CNI可执行文件的路径集合。在Linux中路径名用':'隔开,Windows用';'隔开
JSON形式的网络配置用stdin的方式流入plugin。这意味着它不依赖于磁盘上任何特定的文件,可以在多次的调用中保留配置信息。
Network Configuration
网络配置以JSON格式描述。有如下字段:
....
- name (sring):网络的名字,必须全局唯一
- type (string):plugin可执行文件的名字
- args (dictionary):由容器运行时提供的可选的参数
- ipMasq (boolean):可选的(如果plugin支持的话)。为该网络在宿主机上创建一个IP masquerade。这对于那些无法路由到容器IP,只能将宿主机作为网关的子网是必要的。
- ipam:由IPAM specific values组成的字典:
- type (string):IPAM plugin可执行文件的文件名
- routes (list):CNI plugin必须保证能路由到的一系列子网(以CIDR形式表示)。每个条目都是一个字典,包含:
- dst (string):用CIDR形式表示的子网
- gw (string):网关的IP地址。如果没有制定,那就假设是子网的默认网关(由IPAM plugin决定)
- dns:与DNS相关的字典:
- nameservers (list of strings):按优先级排列的DNS nameserver的列表。每一个表项都是IPv4或IPv6地址字符串
- domain (string):local domain used for short hostname lookups
- search (list of strings):一系列以优先级排列的search domains for short hostname lookup。相比于domain,大多数resolver更喜欢search
- options (list of strings):一系列传递给resolver的options
Plugin可能会定义一些它们自己需要的额外的字段,如果碰到不能识别的字段也可能报错。例外的是args字段,它可以被用于传递任意的数据,但它们可能会被plugin忽略。
IP Allocation
因为大多数plugin都要编写相同的代码用于支持各种用户想要的IP 管理框架(例如,dhcp,host-local)。因此,可以将这部分的内容抽象出来,形成第二种插件——IP Address Management Plugin(IPAM plugin)。IPAM Plugin主要用于确定网卡的IP/子网,网关以及路由,并将这些信息返回给“main” plugin。
IP Address Management(IPAM)Interface
IPAM plugin也以可执行文件的方式被调用。通常IPAM plugin不知道它的parent plugin配置的网卡的相关信息,像dhcp IPAM plugin这样的特别的IPAM除外。
IPAM有host-local和dhcp两种:
- host-local:在一定区域内选择一个未被使用的IP地址
- dhcp:使用DHCP协议获取IP。因为DHCP请求会通过已创建的容器网卡转发,因此相关的网络必须支持广播