CNI系列之规范学习
CNI是什么吗?
- 全称是
Container Network Interface
; - 也是CNCF管理的一个项目;
- 该项目包含规范和实现库(golang版本);
- CNI只关注于容器启动时网络的联接以及容器退出时网络资源的释放;
本文主要是学习CNI规范(其实就是翻译😀),golang版本的实现库,后续文章继续学习。
版本
当前CNI版本号为0.4.0
,已发布的版本如下:
版本 | 主要变更 |
---|---|
spec v0.4.0 | 引入CHECK命令;DEL命令需要传递prevResult |
spec v0.3.1 | 无 |
spec v0.3.0 | 丰富result类型,支持链式插件 |
spec v0.2.0 | 支持VERSION命令 |
spec v0.1.0 | 初始版本 |
概述
本文旨在说明为Linux上的应用容器提供一种通用的基于插件的网络解决方案,即容器网络接口(Container network interface),简称CNI。源自rkt网络解决方案,rkt旨在适应多种网络设计思路。
为了更好的描述该规范,约定下面两个术语,本文后续使用network
和container
描述:
容器(container)
:可以认为等同于Linux网络命名空间。具体的承载单元,取决于特定的容器runtime实现。例如,rkt中每一个pod都是运行在一个独一无二的网络命名空间中;而docker中,每一个独立的Docker容器都存在一个独立的网络命名空间;网络(network)
:指一组实体,这些实体都是独一无二可寻址的而且可以相互通信的。单个实体可以是一个独立的容器container
,一台机器或者其他网络设备(例如一个路由器)。逻辑上containers
可以添加到一个或者多个网络network
,也可以从中退出。
本文旨在规范runtimes
和plugins
之间的接口。尽管有一些众所周知的字段,runtimes
可能希望增加一些额外的信息给plugins
。这些拓展不是规范的一部分,而是归属于约定。
关键字”must”, “must not”, “required”, “shall”, “shall not”, “should”, “should not”, “recommended”, “may”和”optional”都是遵循规范RFC 2119。注意:本文对应于必须,必须不等等。
基本准则
- 为容器执行任何插件之前,容器
runtime
必须创建一个新的网络命名空间; runtime
必须决定这个容器应该属于那些networks
,而且对于每个network
那些插件必须执行;network
配置是JSON格式,而且容易存储到文件。network
配置包含强制性字段,如”name”和”type”;”type”对应于插件名。network
配置允许字段在调用过程中变更值。为此,可选配置”args”,必须包含可变信息;- 容器
runtime
必须依次把容器添加到network
中,通过执行相应的插件实现; - 容器生命周期结束之后,
runtime
必须以逆序(相对于加入network
的操作顺序)执行插件,把容器从这些networks
中退出; - 容器
runtime
必须不能对同一个容器并发执行network
操作,但是允许对不同容器并发执行network
操作; - 容器
runtime
必须保证对容器的ADD
和DEL
操作是对应的,ADD
之后总是对应一个DEL
操作。DEL
之后可能有其他的DELS
,但是插件应该允许处理多个DEL
操作,即插件的DEL
应该是幂等的; - 容器必须通过独一无二的容器ID来标识。插件存储状态信息,应该使用
(network name, CNI_CONTAINERID, CNI_IFNAME)
作为主键; - 容器
runtime
必须不能对同一个(network name, container id, name of the interface inside the container)
执行两次ADD
操作(没有执行相应的DEL
操作)。这意味着对同一个容器ID添加到特定的网络多次,只能是每次添加操作针对不同的接口名; - CNI结构(Network Configuration 和CNI Plugin Result)中的字段,除非标记为可选的,否则是必须的;
CNI插件
CNI插件必须以可执行文件的方式存在,由容器管理系统(rkt或者K8S)调用。
CNI插件负责把网络接口(例如veth对的一端)插入到容器网络命名空间,并且在host上面做必要的修改(例如把veth对的另外一端链接到bridge上面)。然后CNI插件需要给网络接口分配一个IP,并且通过调用适当的IPAM插件设置与IP地址管理部分一致的路由配置。
ADD操作参数
作用:把容器加入到network
中。
支持的参数如下:
参数 | 作用 |
---|---|
Container ID | 由runtime 分配的独一无二的明文标识符,必须以字母数字开头,后面可以跟一个或者多个字母数字、下划线_ 、点. 或者中划线- 字符的任意组合。 |
Network namespace path | 表示加入的网络命名空间的路径,例如/proc/[pid]/ns/net 或者bind-mount/link 的路径。 |
Network configuration | 描述容器将加入的network 的JSON文档,下面会有章节详细描述。 |
Extra arguments | 提供了一个替代的机制,允许对每个基础容器上的插件进行简单的配置。 |
Name of the interface inside the container | 指定容器(网络命名空间)内创建的接口名称;该名称必须遵守Linux对接口名称的标准规范,必须不为空,必须不为”.”或者”..”,必须小于16个字符,而且不能包含”/“、”:”或者其他任何空白字符。 |
返回结果结构如下:
字段 | 描述 |
---|---|
Interfaces list | 取决于插件实现,可以包含sandbox(如容器或者hypervisor )中的接口名(如网卡名)或者主机上的接口名,每个接口的物理地址,以及这些接口所在的sandbox的详细信息。 |
IP configuration assigned to each interface | 分配给sandbox或/和主机的接口的IPV4/IPV6的地址,网关和路由信息。 |
DNS information | 包含DNS信息(nameservers,domain,search domains,options)的字典 |
DEL操作参数
作用:把容器从network
中退出。
支持参数如下:
参数 | 作用 |
---|---|
Container ID | 同ADD |
Network namespace path | 同ADD |
Network configuration | 同ADD |
Extra arguments | 同ADD |
Name of the interface inside the container | 同ADD |
功能规范要求:
- 传递给
DEL
的参数,必须和对应的ADD
的一样; DEL
操作应该释放container
对已配置network
持有的所有资源;- 如果已知对
container
的前一个ADD
操作,那么runtime
必须把前一个ADD
返回的Result
传递给当前JSON配置的插件(或者插件链的所有插件)的prevResult
字段。runtime
可能希望使用libcni
提供的Result cache
。 - 如果没有提供
CNI_NETNS
和/或prevResult
,插件应该尽可能的释放资源(如释放IPAM分配的IP),并返回成功响应; - 如果
runtime cache
中缓存了给定容器的上一个ADD
操作的Result
,那么必须在DEL
操作成功之后,删除该缓存的Result
。
即使某些资源丢失,插件一般也应该无错误的完成DEL
操作。例如,即使容器网络命名空间不存在,IPAM
插件也应该释放分配的IP,并且返回成功;除非这个网络命名空间对于IPAM
管理器至关重要。虽然DHCP通常会给容器网络接口发送一个”释放”消息,但是由于DHCP租约存在一个生命周期,所以这个释放操作不会被认为是关键的,也不应该返回任何错误。
再例如,即使容器网络命名空间和/或容器的接口不存在了,bridge
插件也应该把DEL
操作委托给IPAM
插件去清理自己的资源(如果有)。
CHECK操作参数
作用:检测容器的网络是否符合预期。
支持参数如下:
参数 | 作用 |
---|---|
Container ID | 同ADD |
Network namespace path | 同ADD |
Network configuration | 同ADD,必须包含prevResult 字段,值为该容器的上一个ADD 操作返回的Result |
Extra arguments | 同ADD |
Name of the interface inside the container | 同ADD |
返回结果:
- 无任何返回或者返回错误
功能规范要求:
插件必须通过
pervResult
确定期望的网络接口和地址;插件必须允许插件链后续的插件修改网络资源,例如路由;
如果CNI结果类型中包含的资源(网络接口、地址或者路由)是由插件创建的,并且在
prevResult
中列出,但丢失或者处于非法状态,那么插件应该返回错误;如果非CNI结果类型中的资源,丢失或者处于非法状态,如下面的资源,插件也应该返回错误:
- 防火墙规则;
- 流量控制;
- IP预订;
- 外部依赖,如链接需要的守护进程;
- 其他。。。
如果插件感知到容器处于一般无法到达的状态,应该返回错误;
插件必须处理
ADD
之后立刻执行CHECK
的调用,因此应该允许任何异步资源有合理的收敛延迟;插件应该在委托的所有插件(如IPAM)上面调用
CHECK
,而且返回错误给调用者;runtime
必须不能对未执行ADD
或者执行过最后ADD之后的DEL
的容器执行CHECK
;如果网络配置的
disableCheck
设置为true
,那么runtime
必须不能执行CHECK
;runtime
必须把前一个ADD
返回的Result
传递给当前JSON配置的插件(或者插件链的所有插件)的prevResult
字段。runtime
可能希望使用libcni
提供的Result cache
;当一个插件返回错误,
runtime
可能选择停止对插件链后续插件执行CHECK
;runtime
可以在ADD
之后立即执行CHECK
,直到容器从network
中删除;runtime
可能认为CHECK
失败的容器,将永久处于错误状态;
VERSION操作参数
作用:报告版本信息;
参数:无;
结果:插件支持的CNI规范版本信息,详细结构如下
1 | { |
插件执行说明
runtime
必须根据network
的type
字段指定的名字作为可执行文件的名字调用。runtime
应该从一组预定义的目录(该规范没有指定目录列表,但库实现有:/opt/cni/bin)中搜索该可执行文件。一旦找到,runtime
必须使用以下的环境变量传递参数:
CNI_COMMAND
:表示期望执行的操作;ADD
、DEL
、CHECK
或者VERSION
;CNI_CONTAINERID
:容器ID;CNI_NETNS
:网络命名空间文件路径;CNI_IFNAME
:构建的接口名,如果插件无法使用该接口名,必须返回一个错误;CNI_ARGS
:调用时用户传入的额外参数,以’;’分割的字母数字键值对,例如:”FOO=BAR;ABC=123”CNI_PATH
:列出搜索CNI插件可执行文件的路径列表,路径由特定于OS的列表分割符分割,例如,Linux的’:’,Windows的’;’
JSON格式的网络配置信息,必须通过stdin流的方式传递给插件。这意味着它不需要绑定到磁盘的特定文件,而且可能包含调用过程中变化的信息。
CNI插件总结
runtime
可以通过两种方式传递参数或者信息给插件:
- 网络配置信息,通过stdin流传递给插件;
- 环境变量;
Result
注意IPAM插件应该返回一个简洁的Result
结构体,如[IP Allocation](#IP Allocation)章节所描述。
执行ADD
操作,插件必须返回0表示成功,而且把下面的JSON结构输出到stdout
。
1 | { |
ips
和dns
字段应该和IPAM创建返回的结果一样,除此之外插件应该合理的填充interface
字段;由于IPAM插件对interfaces
无感知,因此IPAM返回的输出中无interface
字段。
cniVersion
描述当前插件使用的CNI规范版本。插件可能支持多个CNI规范版本(通过VERSION
操作获取),插件返回的cniVersion
必须和网络配置中设置的cniVersion
一致。如果插件不支持网络配置指定的cniVersion
,插件应该返回一个错误码”1”(详情见[Error Code](#Error Codes))。
interfaces
描述插件创建的网络接口。如果CNI_IFNAME
环境变量存在,插件必须使用它指定的名字创建sandbox/hypervisor
接口,如果不能创建则返回错误。
mac
:字符串类型,值为接口的物理地址。如果L2地址对插件无意义,那么该字段是可选的;sandbox
:字符串类型,容器(基于命名空间的)环境应该返回该sandbox
的网络命名空间的完整文件系统路径。hypervisor
(基于虚拟机的)插件应该返回创建接口的虚拟sandbox
的唯一ID。对于创建或者移动到sandbox
(网络命名空间)或者hypervisor
(VM)的接口,必须指定此项。
ips
字段表示一组IP配置信息。详情见well-know ips。
routes
字段表示一组路由的配置信息。详情见well-know routes。
dns
字段表示常见DNS信息组成的字典。详情见well-know DNS。本规范未声明CNI消费者必须如何处理这些信息。常用的例子,生成一个/etc/resolv.conf
文件并且注入容器的文件系统,或者在主机上运行一个DNS转发器。
错误
错误通过非0的返回值和如下的stdout的输出描述:
1 | { |
cniVersion
表示插件使用的CNI规范版本,错误码”0-99”为保留的常用的错误。”100+”的错误码插件可以自由使用。
此外,stderr可以用于输出未格式化的信息,例如日志。
Network Configuration
网络配置以JSON格式呈现。该配置可能存储在磁盘,也可能由容器runtime
的其他组件生成。网络配置包含下面的通用字段:
cniVersion
:字符串类型,当前配置符合的CNI规范版本;name
:字符串类型,网络名称。在主机(或者其他管理域)上的所有容器中应该是唯一的。必须以数字字符开头,后面可以跟一个或者多个字母数字、下划线_
、点.
或者中划线-
字符的任意组合;type
:字符串类型,表示CNI插件可执行文件名;args
:字典类型(可选),容器runtime
提供的额外参数。例如,可以通过设置args
的一项,可以把一个标签字典传递给CNI插件;ipMasq
:布尔类型(可选),如果插件支持,会在主机上为该网络设置IP伪装。如果主机作为子网的网关,而子网无法路由到分配给容器的IP,那么配置ipMasq
是必须的;ipam
:字典类型(可选),IPAM特定值的字典:type
:字符串类型,表示IPAM插件可执行文件名;
dns
:字典类型(可选),DNS特定值的字典:nameservers
:字符串数组(可选),该网络能够识别的DNS域名服务器的优先顺序列表。数组每项包含一个IPV4或者IPV6的地址;domain
:字符串类型,用于短主机名查找的本地域;search
:字符串数组类型,为短主机名查找的优先顺序搜索域的列表。大部分解析都优先于domain
执行。options
:字符串数组类型,传递给解析器的一组选项。查看CNI插件Result获取更多信息。
插件可以定义他们能接受的附加字段,但是如果传递未知的字段可能会报错。而args
字段可以传递任意的数据,如果未知插件会忽略该字段。
示例
bridge
的网络配置示例
1 | { |
ovs
网络配置示例
1 | { |
macvlan
网络配置示例
1 | { |
Network Configuration Lists
网络配置列表提供了对单容器按特定顺序执行多个插件的机制,并且把每个插件的执行结果传递给它的下一个插件。结果和网络配置一样,以JSON为格式,包含一些通用的配置项和一组[网络配置](#Network Configuration)的列表。该配置可能存储在磁盘,也可能由容器runtime
的其他组件生成。下面是通用配置的描述:
cniVersion
:字符串类型,当前配置符合的CNI规范版本;name
:字符串类型,网络名称。在主机(或者其他管理域)上的所有容器中应该是唯一的。必须以数字字符开头,后面可以跟一个或者多个字母数字、下划线_
、点.
或者中划线-
字符的任意组合;disableCheck
:字符串类型,值为true
或者false
。如果disableCheck
为true
,runtime
必须不对该网络配置列表进行CHECK
操作。这可以允许管理员阻止CHECK
组合插件已知的假错误。plugins
:网络配置列表类型,一组CNI网络配置字典(详细信息见上节);
执行插件链时,runtime
必须替换plugins
中的每个网络配置的name
和cniVersion
为网络配置列表本身的name
和cniVersion
。这样可以保证执行所有插件时CNI版本一致,防止由于版本不一致导致的错误。
如果插件的网络配置文件的capabilities
字段声明支持某种能力,那么runtime
可能把基于该能力的配置通过插件的配置JSON的runtimeConfig
字段传递过去。
对于ADD
操作,runtime
必须在执行第一个插件之后,把上一次插件执行结果(Result),添加到JSON配置的prevResult
字段。而且插件应该把它收到的prevResult
的内容输出到stdout,从而允许后续的插件(和runtime)接收到这些内容,除非是当前插件需要修改或者屏蔽到之前的结果。插件允许修改或者屏蔽prevResult
的全部或者部分内容。然而,插件支持的CNI规范版本包好了prevResult
字段,那么插件必须处理prevResult
字段,可以是修改、透传或者屏蔽。对prevResult
字段一无所知是不符合规范的。
对于CHECK
和DEL
操作,runtime
必须(除非不可用,DEL
可以忽略)为每一个插件的JSON配置添加prevResult
字段,其值必须是前一个ADD
操作的JSON格式的结果。
runtime
必须以相同的环境执行列表中的每一个插件。
DEL
操作的顺序必须是和列表顺序相反。
网络配置列表错误处理
当插件列表执行操作(ADD
或者DEL
)出现错误时,runtime
必须停止该列表的执行。
如果ADD
执行失败,当runtime
决定处理该错误时,它应该对列表中的所有插件执行DEL
操作(相对于ADD
的逆序),即使执行ADD
操作时某些插件没有被调用。
网络配置列表示例
1 | { |
网络配置列表运行示例
ADD操作
以上节的网络配置列表的JSON为例,runtime
运行ADD
操作,会执行如下步骤。注意:runtime
给plugins
的所有网络配置添加cniVersion
和name
字段,以保证所有插件运行时版本和名字一致。
首先,使用如下JSON配置,调用bridge插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20{
"cniVersion": "0.4.0",
"name": "dbnet",
"type": "bridge",
"bridge": "cni0",
"args": {
"labels" : {
"appVersion" : "1.0"
}
},
"ipam": {
"type": "host-local",
// ipam specific
"subnet": "10.1.0.0/16",
"gateway": "10.1.0.1"
},
"dns": {
"nameservers": [ "10.1.0.1" ]
}
}然后,以下面的JSON配置,调用
tuning
插件,prevResult
字段包含了bridge
插件的返回JSON1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35{
"cniVersion": "0.4.0",
"name": "dbnet",
"type": "tuning",
"sysctl": {
"net.core.somaxconn": "500"
},
"prevResult": {
"ips": [
{
"version": "4",
"address": "10.0.0.5/32",
"interface": 2
}
],
"interfaces": [
{
"name": "cni0",
"mac": "00:11:22:33:44:55"
},
{
"name": "veth3243",
"mac": "55:44:33:22:11:11"
},
{
"name": "eth0",
"mac": "99:88:77:66:55:44",
"sandbox": "/var/run/netns/blue"
}
],
"dns": {
"nameservers": [ "10.1.0.1" ]
}
}
}
CHECK操作
以相同的网络配置列表的JSON为例,runtime
运行CHECK
操作,会执行如下步骤。
首先,以如下JSON,调用
bridge
插件,prevResult
字段包含了ADD
插件的返回JSON1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47{
"cniVersion": "0.4.0",
"name": "dbnet",
"type": "bridge",
"bridge": "cni0",
"args": {
"labels" : {
"appVersion" : "1.0"
}
},
"ipam": {
"type": "host-local",
// ipam specific
"subnet": "10.1.0.0/16",
"gateway": "10.1.0.1"
},
"dns": {
"nameservers": [ "10.1.0.1" ]
},
"prevResult": {
"ips": [
{
"version": "4",
"address": "10.0.0.5/32",
"interface": 2
}
],
"interfaces": [
{
"name": "cni0",
"mac": "00:11:22:33:44:55"
},
{
"name": "veth3243",
"mac": "55:44:33:22:11:11"
},
{
"name": "eth0",
"mac": "99:88:77:66:55:44",
"sandbox": "/var/run/netns/blue"
}
],
"dns": {
"nameservers": [ "10.1.0.1" ]
}
}
}然后,以如下JSON,调用
tuning
插件,prevResult
字段包含了ADD
插件的返回JSON1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35{
"cniVersion": "0.4.0",
"name": "dbnet",
"type": "tuning",
"sysctl": {
"net.core.somaxconn": "500"
},
"prevResult": {
"ips": [
{
"version": "4",
"address": "10.0.0.5/32",
"interface": 2
}
],
"interfaces": [
{
"name": "cni0",
"mac": "00:11:22:33:44:55"
},
{
"name": "veth3243",
"mac": "55:44:33:22:11:11"
},
{
"name": "eth0",
"mac": "99:88:77:66:55:44",
"sandbox": "/var/run/netns/blue"
}
],
"dns": {
"nameservers": [ "10.1.0.1" ]
}
}
}
DEL操作
以相同的网络配置列表的JSON为例,runtime
运行DEL
操作,会执行如下步骤。注意:插件执行的顺序与ADD
和CHECK
是相反的。
首先,以如下JSON配置,执行
tuning
插件,prevResult
字段包含了ADD
插件的返回JSON1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35{
"cniVersion": "0.4.0",
"name": "dbnet",
"type": "tuning",
"sysctl": {
"net.core.somaxconn": "500"
},
"prevResult": {
"ips": [
{
"version": "4",
"address": "10.0.0.5/32",
"interface": 2
}
],
"interfaces": [
{
"name": "cni0",
"mac": "00:11:22:33:44:55"
},
{
"name": "veth3243",
"mac": "55:44:33:22:11:11"
},
{
"name": "eth0",
"mac": "99:88:77:66:55:44",
"sandbox": "/var/run/netns/blue"
}
],
"dns": {
"nameservers": [ "10.1.0.1" ]
}
}
}然后,以如下JSON配置,执行
bridge
插件,prevResult
字段包含了ADD
插件的返回JSON1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47{
"cniVersion": "0.4.0",
"name": "dbnet",
"type": "bridge",
"bridge": "cni0",
"args": {
"labels" : {
"appVersion" : "1.0"
}
},
"ipam": {
"type": "host-local",
// ipam specific
"subnet": "10.1.0.0/16",
"gateway": "10.1.0.1"
},
"dns": {
"nameservers": [ "10.1.0.1" ]
},
"prevResult": {
"ips": [
{
"version": "4",
"address": "10.0.0.5/32",
"interface": 2
}
],
"interfaces": [
{
"name": "cni0",
"mac": "00:11:22:33:44:55"
},
{
"name": "veth3243",
"mac": "55:44:33:22:11:11"
},
{
"name": "eth0",
"mac": "99:88:77:66:55:44",
"sandbox": "/var/run/netns/blue"
}
],
"dns": {
"nameservers": [ "10.1.0.1" ]
}
}
}
IP Allocation
CNI插件被期望去分配IP地址,并且安装接口相关的任何必要的路由配置。这个CNI插件带来巨大的灵活性,同时也带来巨大的负担。有些CNI插件可能需要通过相同的代码支持多种用户期望的IP管理策略(例如,dhcp或host-local)。
为了减少这种负担,并且使得IP管理策略和CNI插件类型正交,本规范定了第二种插件类型(IP Address Management Plugin = IPAM插件)。而CNI插件需要在执行过程中,选择合适的时间调用IPAM插件。IPAM插件必须决定接口的IP/子网、网关和路由并且把这些信息返回给调用它的”主“插件。
IPAM插件可以通过协议(如dhcp)、本地文件系统存储,网络配置文件的ipam
字段甚至以上方式的集合获取信息。
IPAM Interface
和CNI插件类似,IPAM插件作为可执行文件被运行。可执行文件通过搜索预定义的一批路径搜索获得,通过CNI_PATH
传递给CNI插件。IPAM插件必须接受CNI插件完全一样的环境变量。IPAM插件也是通过stdin接受网络配置的。
执行成功,则返回0并且输出如下JSON信息到stdout(以ADD
操作为例):
1 | { |
注意:不像常规的CNI插件,IPAM插件应该返回一个简洁的Result
结构,不包含interfaces
字段,由于IPAM插件应该对interfaces
无感知,而是由父插件配置,除非IPAM由特殊依赖(例如,dhcp IPAM插件)。
cniVersion
描述当前插件使用的CNI规范版本。插件可能支持多个CNI规范版本(通过VERSION
操作获取),插件返回的cniVersion
必须和网络配置中设置的cniVersion
一致。如果插件不支持网络配置指定的cniVersion
,插件应该返回一个错误码”1”(详情见[Error Code](#Error Codes))。
ips
字段表示一组IP配置信息。详情见well-know ips。
routes
字段表示一组路由的配置信息。详情见well-know routes。
dns
字段表示常见DNS信息组成的字典。详情见well-know DNS。
错误和日志和CNI插件使用相同的方式。详情见Result错误。
IPAM插件的例子:
host-local
:选择指定区间内一个未使用的IP(相同主机上其他容器);dhcp
:使用DHCP协议区获取和维护租约。DHCP请求将通过创建的容器接口发送,因此,相关的网络必须支持广播。
注意:
- 默认路由可能设置为”0.0.0.0/0”。由于其他网络可能已经设置默认路由,因此CNI插件应该准备跳过默认路由设置。
- 期望以0为指标添加路由
Well-know Structures
本章主要是说明众所周知的结构体,例如,IP、路由以及DNS,还有错误码。
ips
1 | "ips": [ |
ips字段的值是由插件决定的一组IP配置信息列表。每一项表示一个网络接口的IP配置信息字典。多个网络接口或者一个接口的多个网络配置,可能通过独立ips
的项表示。应该提供插件所知道的所有属性,即使不是严格要求的。
version
:string类型,值范围为”4”或者”6”,对应当前项的IP地址的版本。所有的IP地址和网关对于给定版本必须是合法的。address
:string类型,CIDR格式的IP地址,例如”192.168.1.3/24”。gateway
:string类型,为子网设置默认的网关,如果该网关存在。CNI插件不会为该网关设置任何路由配置,路由配置是通过routes
项单独设置。使用该配置的一个例子,CNI插件bridge
为Linux桥配置一个IP,使得该桥成为网关。interface
:uint类型,CNI插件Result中interface
链表的下标,指明该IP配置将应用到那个接口上。IPAM插件不应该返回该字段,因为它们没有关于网络接口的信息。
routes
1 | "routes": [ |
每个条目包含如下字段。条目中,所有的IP地址必须是相同的IP版本,4或者6。
dst
:string类型,CIDR格式的目的地址子网;gw
:string类型,网关的IP,如果省略,则假定为默认网关(由CNI插件决定);
每个条目必须和CNI_IFNAME
指定的 sandbox
的接口关联。
DNS
1 | "dns": { |
dns
字段包含了常用DNS信息的字典。
nameservers
:字符串数组类型,该网络能够识别的DNS域名服务器的优先顺序列表。数组每项包含一个IPV4或者IPV6的地址;domain
:字符串类型,用于短主机名查找的本地域;search
:字符串数组类型,为短主机名查找的优先顺序搜索域的列表。大部分解析都优先于domain
执行。options
:字符串数组类型,传递给解析器的一组选项。查看CNI插件Result获取更多信息。
Error Codes
1-99为规范保留的通用错误码,必须不能被其他地方使用。
Error Code | Error Description |
---|---|
-1 |
Incompatible CNI version |
-2 |
Unsupported field in network configuration. The error message must contain the key and value of the unsupported field. |
-3 |
Container unknown or does not exist. This error implies the runtime does not need to perform any container network cleanup (for example, calling the DEL action on the container). |
-4 |
Invalid necessary environment variables, like CNI_COMMAND, CNI_CONTAINERID, etc. The error message must contain the names of invalid variables. |
-5 |
I/O failure. For example, failed to read network config bytes from stdin. |
-6 |
Failed to decode content. For example, failed to unmarshal network config from bytes or failed to decode version info from string. |
-7 |
Invalid network config. If some validations on network configs do not pass, this error will be raised. |
-11 |
Try again later. If the plugin detects some transient condition that should clear up, it can use this code to notify the runtime it should re-try the operation later. |