容器网络接口规范
翻阅历史记录,发现此篇未发布翻译稿,截止目前
CNI SPEC
版本已经至0.4.0.
了。
版本
这是CNI 规范版本0.4.0-dev。此规范包含未发布的更改。
请注意,这与此存储库中的CNI库和插件的版本无关(例如,版本的发布版本)。
发布版本
已发布的规范版本可作为Git标签使用。
标签 | 规范永久链接 | 主要变化 |
---|---|---|
spec-v0.3.1 |
规范v0.3.1 | 无(仅限拼写错误) |
spec-v0.3.0 |
规格v0.3.0 | 丰富的结果类型,插件链接 |
spec-v0.2.0 |
规范v0.2.0 | VERSION命令 |
spec-v0.1.0 |
规格v0.1.0 | 初始版本 |
不要依赖这些标签稳定。在将来,我们可能会改变我们的想法,即哪个特定提交是给定历史规范版本的正确标记。
概观
本文档提出了一种基于插件的通用网络解决方案,适用于Linux,容器网络接口或CNI上的应用程序容器。它是从衍生RKT网络的议案,旨在满足众多的设计考虑在网络RKT。
出于本提案的目的,我们非常具体地定义了两个术语:
- 容器可以被认为是Linux 网络命名空间的同义词。这对应于哪个单元取决于特定的容器运行时实现:例如,在诸如rkt 之类的App Container Spec的实现中,每个pod在唯一的网络命名空间中运行。另一方面,在Docker中,每个单独的Docker容器通常都存在网络命名空间。
- 网络是指可以在彼此之间进行通信的唯一可寻址的一组实体。这可以是单个容器(如上所述),机器或某些其他网络设备(例如路由器)。可以在概念上将容器添加到一个或多个网络中或从中移除容器。
本文档旨在指定“运行时”和“插件”之间的接口。虽然存在某些众所周知的字段,但运行时可能希望将附加信息传递给插件。这些扩展不是本规范的一部分,但记录为约定。关键词“必须”,“不得”,“必须”,“应”,“不得”,“应该”,“不应该”,“推荐”,“可以”和“可选”的使用如RFC 2119。
一般考虑
- 容器运行时必须在调用任何插件之前为容器创建新的网络命名空间。
- 然后,运行时必须确定此容器应属于哪些网络,并且对于每个网络,必须确定必须执行哪些插件。
- 网络配置采用JSON格式,可以轻松存储在文件中。网络配置包括必需字段,例如“名称”和“类型”以及插件(类型)特定字段。网络配置允许字段在调用之间更改值。为此目的,存在可选字段“args”,其必须包含变化的信息。
- 容器运行时必须通过按顺序执行每个网络的相应插件来将容器添加到每个网络。
- 在完成容器生命周期后,运行时必须以相反的顺序执行插件(相对于执行它们以添加容器的顺序)以断开容器与网络的连接。
- 容器运行时不能为同一容器调用并行操作,但允许为不同容器调用并行操作。
- 容器运行时必须为容器命令ADD和DEL操作,这样ADD总是最后跟随相应的DEL。DEL可以跟随其他DEL,但插件应该允许多个DEL(即插件DEL应该是幂等的)。
- 容器必须由ContainerID唯一标识。存储状态的插件应该使用主键
(network name, CNI_CONTAINERID, CNI_IFNAME)
。 - 运行时不能为ADD调用两次(没有相应的DEL)
(network name, container id, name of the interface inside the container)
。这意味着只有在使用不同的接口名称进行每次添加时,才能将给定的容器ID多次添加到特定网络。 - 除非特别标记为可选,否则CNI结构中的字段(如网络配置和CNI插件结果)是必需的。
CNI插件
概观
每个CNI插件必须实现为容器管理系统调用的可执行文件(例如rkt或Kubernetes)。
CNI插件负责将网络接口插入容器网络命名空间(例如,veth对的一端)并在主机上进行任何必要的更改(例如,将veth的另一端连接到桥中)。然后,它应该通过调用适当的IPAM插件将IP分配给接口并设置与IP地址管理部分一致的路由。
参数
CNI插件必须支持的操作是:
-
ADD
:将容器添加到网络- 参数:
- 容器ID。由运行时分配的容器的唯一明文标识符。一定不能为空。
- 网络命名空间的路径。这表示要添加的网络命名空间的路径,即/ proc / [pid] / ns / net或其绑定装载/链接。
- 网络配置。这是一个JSON文档,描述了容器可以加入的网络。该模式如下所述。
- 额外的论点。这提供了一种替代机制,允许基于每个容器简单地配置CNI插件。
- 容器内接口的名称。这是应该分配给在容器内创建的接口的名称(网络命名空间); 因此,它必须符合Linux对接口名称的标准限制。
- 结果:
- 接口列表。根据插件,这可以包括沙箱(例如,容器或管理程序)接口名称和/或主机接口名称,每个接口的硬件地址以及接口所在的沙箱(如果有)的详细信息。
- 分配给每个接口的IP配置。分配给沙箱和/或主机接口的IPv4和/或IPv6地址,网关和路由。
- DNS信息。包含域名服务器,域,搜索域和选项的DNS信息的字典。
- 参数:
-
DEL
:从网络中删除容器- 参数:
- 容器ID,如上所定义。
- 网络命名空间路径,如上所述。
- 网络配置,如上所述。
- 额外的参数,如上所定义。
- 容器内接口的名称,如上所述。
- 所有参数应与传递给相应添加操作的参数相同。
- 删除操作应释放所配置网络中提供的containerid所拥有的所有资源。
- 如果
ADD
容器有一个已知的先前操作,运行时必须prevResult
在插件的配置JSON(或链中的所有插件)中添加一个字段,该字段必须是JSON格式的Result
前一个ADD
操作(见下文)。运行时可能希望使用libcni对缓存的支持Result
。 - 当
CNI_NETNS
和/或未prevResult
提供时,插件应尽可能多地清理资源(例如,释放IPAM分配)并返回成功的响应。 - 如果运行时缓存了给定容器
Result
的先前ADD
响应,则必须在DEL
该容器成功时删除该缓存响应。
- 参数:
-
CHECK
:检查容器的网络是否符合预期- 参数:
-
容器ID,定义为
ADD
。 -
网络命名空间路径,定义为
ADD
。 - 定义的网络配置
ADD
,必须包含一个prevResult
包含容器Result
紧前面的字段ADD
。 -
额外的参数,定义为
ADD
。 -
容器内接口的名称,定义为
ADD
。
-
容器ID,定义为
- 结果:
- 该插件必须返回任何内容或错误。
- 插件必须查阅
prevResult
以确定预期的接口和地址。 - 该插件必须允许稍后链接的插件具有修改的网络资源,例如路由。
- 如果CNI结果类型(接口,地址或路由)中包含资源,插件应返回错误:
- 是由插件创建的,和
- 列在
prevResult
,和 - 不存在,或处于无效状态。
- 如果结果类型中未跟踪的其他资源(如以下内容)丢失或处于无效状态,则插件应返回错误:
- 防火墙规则
- 流量整形控制
- IP预订
- 外部依赖项,例如连接所需的守护程序
- 等等
- 如果插件知道容器通常无法访问的情况,则应该返回错误。
- 插件必须处理
CHECK
后立即调用ADD
,因此应该允许任何异步资源的合理收敛延迟。 - 该插件应调用
CHECK
任何委托(例如IPAM)插件并将任何错误传递给其调用者。 - 运行时必须不调用
CHECK
对于尚未容器ADD
编,或者已经DEL
经过了最后etedADD
。 -
CHECK
如果在配置列表中disableCheck
设置为运行时,则不能调用运行时。true
- 运行时必须
prevResult
在网络配置中包含一个字段,该字段包含容器Result
的紧前面ADD
。运行时可能希望使用libcni对缓存的支持Result
。 -
CHECK
当插件返回错误时,运行时可以选择停止为链执行。 - 运行时可以
CHECK
在成功之后立即执行ADD
,直到容器DEL
从网络中移出。 - 运行时可以假定失败
CHECK
意味着容器永久处于错误配置状态。
- 参数:
-
VERSION
:报告版本-
参数:无。
-
结果:有关插件支持的CNI规范版本的信息
{ "cniVersion": "0.4.0", // the version of the CNI spec in use for this output "supportedVersions": [ "0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0" ] // the list of CNI spec versions that this plugin supports }
-
运行时必须使用网络类型(请参阅下面的网络配置)作为要调用的可执行文件的名称。然后,运行时应在预定义目录列表中查找此可执行文件(此规范未规定目录列表)。一旦找到,它必须使用以下环境变量调用可执行文件以进行参数传递:
-
CNI_COMMAND
:表示所需的操作;ADD
,DEL
,CHECK
,或VERSION
。 -
CNI_CONTAINERID
:容器ID -
CNI_NETNS
:网络命名空间文件的路径 -
CNI_IFNAME
:要设置的接口名称; 如果插件无法使用此接口名称,则必须返回错误 -
CNI_ARGS
:用户在调用时传入的额外参数。由分号分隔的字母数字键值对; 例如,“FOO = BAR; ABC = 123” -
CNI_PATH
:搜索CNI插件可执行文件的路径列表。路径由特定于操作系统的列表分隔符分隔; 例如Linux上的':'和';' 在Windows上
必须通过stdin将JSON格式的网络配置流式传输到插件。这意味着它不依赖于磁盘上的特定文件,并且可能包含在调用之间更改的信息。
结果
请注意,IPAM插件应返回IP分配中Result
所述的缩写结构。
插件必须指示成功,返回代码为零,并且在ADD命令的情况下,将以下JSON打印到stdout。在ips
和dns
项目应该是相同的输出由IPAM插件(见返回IP分配的详细信息)除了插件应该在填写interface
适当的指标,这是从IPAM插件输出丢失,因为IPAM插件应该是不知道的接口。
{
"cniVersion": "0.4.0",
"interfaces": [ (this key omitted by IPAM plugins)
{
"name": "<name>",
"mac": "<MAC address>", (required if L2 addresses are meaningful)
"sandbox": "<netns path or hypervisor identifier>" (required for container/hypervisor interfaces, empty/omitted for host interfaces)
}
],
"ips": [
{
"version": "<4-or-6>",
"address": "<ip-and-prefix-in-CIDR>",
"gateway": "<ip-address-of-the-gateway>", (optional)
"interface": <numeric index into 'interfaces' list>
},
...
],
"routes": [ (optional)
{
"dst": "<ip-and-prefix-in-cidr>",
"gw": "<ip-of-next-hop>" (optional)
},
...
]
"dns": { (optional)
"nameservers": <list-of-nameservers> (optional)
"domain": <name-of-local-domain> (optional)
"search": <list-of-additional-search-domains> (optional)
"options": <list-of-options> (optional)
}
}
cniVersion
指定插件使用的CNI规范的语义版本2.0。插件可能支持多个CNI规范版本(因为它通过VERSION
命令报告),此处cniVersion
插件返回的结果必须与网络配置中cniVersion
指定的一致。如果插件不支持网络配置,则插件应返回错误代码1(有关详细信息,请参阅众所周知的错误代码)。cniVersion
interfaces
描述了插件创建的特定网络接口。如果CNI_IFNAME
变量存在,则插件必须使用该名称作为沙箱/管理程序接口,否则返回错误。
-
mac
(字符串):接口的硬件地址。如果L2地址对插件没有意义,则此字段是可选的。 -
sandbox
(字符串):基于容器/命名空间的环境应该返回该沙箱的网络命名空间的完整文件系统路径。基于Hypervisor / VM的插件应返回创建接口的虚拟沙箱的唯一ID。必须为创建或移动到沙箱(如网络命名空间或虚拟机管理程序/ VM)中的接口提供此项。
该ips
字段是IP配置信息的列表。有关更多信息,请参阅IP知名结构部分。
该dns
字段包含由常见DNS信息组成的字典。有关更多信息,请参阅DNS知名结构部分。
该规范未声明CNI消费者必须如何处理此信息。示例包括生成/etc/resolv.conf
要注入容器文件系统的文件或在主机上运行DNS转发器。
错误必须由非零返回码表示,并且以下JSON将打印到stdout:
{
"cniVersion": "0.4.0",
"code": <numeric-error-code>,
"msg": <short-error-message>,
"details": <long-error-message> (optional)
}
cniVersion
指定插件使用的CNI规范的语义版本2.0。错误代码0-99保留用于众所周知的错误(参见“已知错误代码”部分)。100+的值可以自由地用于插件特定错误。
此外,stderr可用于非结构化输出,例如日志。
网络配置
网络配置以JSON格式描述。配置可以存储在磁盘上,也可以由容器运行时从其他源生成。以下字段是众所周知的,具有以下含义:
-
cniVersion
(字符串):此配置符合的CNI规范的语义版本2.0。 -
name
(字符串):网络名称。这在主机(或其他管理域)上的所有容器中应该是唯一的。 -
type
(字符串):指CNI插件可执行文件的文件名。 -
args
(dictionary,optional):容器运行时提供的附加参数。例如,可以通过将标签字典添加到标签字段下来将标签字典传递给CNI插件args
。 -
ipMasq
(布尔值,可选):如果插件支持,则在主机上为此网络设置IP伪装。如果主机将充当到无法路由到分配给容器的IP的子网的网关,则必须执行此操作。 -
ipam
(字典,可选):具有IPAM特定值的字典:-
type
(字符串):指IPAM插件可执行文件的文件名。
-
-
dns
(字典,可选):具有DNS特定值的字典:-
nameservers
(字符串列表,可选):此网络知道的DNS名称服务器的优先级排序列表。列表中的每个条目都是包含IPv4或IPv6地址的字符串。 -
domain
(字符串,可选):用于短主机名查找的本地域。 -
search
(字符串列表,可选):用于短主机名查找的优先级排序搜索域列表。domain
大多数解析器都会优先考虑。 -
options
(字符串列表,可选):可以传递给解析程序的选项列表
-
插件可以定义它们接受的其他字段,如果使用未知字段调用,则可能会生成错误。例外情况是该args
字段可用于传递任意数据,如果不理解,应该被插件忽略。
示例配置
{
"cniVersion": "0.4.0",
"name": "dbnet",
"type": "bridge",
// type (plugin) specific
"bridge": "cni0",
"ipam": {
"type": "host-local",
// ipam specific
"subnet": "10.1.0.0/16",
"gateway": "10.1.0.1"
},
"dns": {
"nameservers": [ "10.1.0.1" ]
}
}
{
"cniVersion": "0.4.0",
"name": "pci",
"type": "ovs",
// type (plugin) specific
"bridge": "ovs0",
"vxlanID": 42,
"ipam": {
"type": "dhcp",
"routes": [ { "dst": "10.3.0.0/16" }, { "dst": "10.4.0.0/16" } ]
}
// args may be ignored by plugins
"args": {
"labels" : {
"appVersion" : "1.0"
}
}
}
{
“ cniVersion ”:“ 0.4.0 ”,
“ name ”:“ wan ”,
“ type ”:“ macvlan ”,
// ipam specific
“ ipam ”:{
“ type ”:“ dhcp ”,
“ routes ”:[{ “ dst ”:“ 10.0.0。0/8 “,” gw“: ” 10.0.0.1 “ }]
}, ” dns “:{
” nameservers “:[ ” 10.0.0.1 “ ]
}
}
网络配置列表
网络配置列表提供了一种机制,可以按照定义的顺序为单个容器运行多个CNI插件,并将每个插件的结果传递给下一个插件。该列表由众所周知的字段和一个或多个标准CNI网络配置列表组成(见上文)。
该列表以JSON格式描述,可以存储在磁盘上,也可以由容器运行时从其他源生成。以下字段是众所周知的,具有以下含义:
-
cniVersion
(字符串):此配置列表和所有单个配置符合的CNI规范的语义版本2.0。 -
name
(字符串):网络名称。这在主机(或其他管理域)上的所有容器中应该是唯一的。 -
disableCheck
(字符串):true
或者是false
。如果disableCheck
是true
,则运行时不得调用CHECK
此网络配置列表。这允许管理员防止CHECK
已知插件组合返回虚假错误的位置。 -
plugins
(list):标准CNI网络配置字典列表(见上文)。
执行插件列表时,运行时必须使用列表本身的name
和cniVersion
字段替换列表中每个单独网络配置中的name
和cniVersion
字段。这可确保列表中所有插件执行的名称和CNI版本相同,从而防止插件之间的版本控制冲突。runtimeConfig
如果插件通过capabilities
其网络配置的密钥通告它支持特定功能,则运行时还可以将基于功能的密钥作为插件的配置JSON 的顶级密钥中的映射传递。传递的密钥runtimeConfig
必须与capabilities
插件网络配置的密钥匹配特定功能的名称。有关功能以及如何通过以下方式将其发送到插件的详细信息,请参阅CONVENTIONS.mdruntimeConfig
键。
对于ADD
操作,运行时还必须prevResult
在第一个插件之后的任何插件的配置JSON中添加一个字段,该插件必须是Result
JSON格式的前一个插件(如果有)的插件(见下文)。对于CHECK
和DEL
动作,运行时必须(除非它可能被省略,DEL
如果不可用)prevResult
向每个插件的配置JSON 添加一个字段,该字段必须是JSON格式的Result
前一个ADD
动作(见下文)。对于ADD
动作,插件应该回应内容prevResult
字段到它们的stdout以允许后续插件(和运行时)接收结果,除非他们希望修改或抑制先前的结果。允许插件修改或抑制全部或部分内容prevResult
。但是,支持包含该prevResult
字段的CNI规范版本的插件必须prevResult
通过传递,修改或明确禁止它来处理。违反此规范是不了解该prevResult
领域的。
运行时还必须使用相同的环境执行列表中的每个插件。
对于DEL
操作,运行时必须以反向顺序执行插件。
网络配置列表错误处理
当在插件列表上执行操作时发生错误(例如,ADD
或者DEL
),运行时必须停止执行列表。
如果ADD
操作失败,当运行时决定处理失败时,它应该对列表中的所有插件执行DEL
操作(ADD
与上面指定的相反的顺序),即使在ADD
操作期间未调用某些插件也是如此。
DEL
即使缺少某些资源,插件通常也应该完成一个没有错误的操作。例如,即使容器网络命名空间不再存在,IPAM插件通常也应该释放IP分配并返回成功,除非该网络命名空间对于IPAM管理至关重要。虽然DHCP通常可以在容器网络接口上发送“释放”消息,但由于DHCP租约具有生命周期,因此该释放操作不会被视为关键,并且不应返回错误。再举一个例子,bridge
即使容器网络命名空间和/或容器网络接口不再存在,插件也应该将DEL操作委托给IPAM插件并清理自己的资源(如果存在)。
示例网络配置列表
{
"cniVersion": "0.4.0",
"name": "dbnet",
"plugins": [
{
"type": "bridge",
// type (plugin) specific
"bridge": "cni0",
// args may be ignored by plugins
"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" ]
}
},
{
"type": "tuning",
"sysctl": {
"net.core.somaxconn": "500"
}
}
]
}
网络配置列表运行时示例
给定上面显示的网络配置列表JSON ,容器运行时将为该ADD
操作执行以下步骤。请注意,运行时将配置列表中的cniVersion
和name
字段添加到传递给每个插件的配置JSON,以确保列表中所有插件的版本控制和名称一致。
- 首先
bridge
使用以下JSON 调用该插件:
{
“ 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 “ ]
}
}
- 接下来
tuning
使用以下JSON 调用插件,包括prevResult
包含bridge
插件的JSON响应的字段:
{
"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列表,容器运行时将为该CHECK
操作执行以下步骤。
- 首先
bridge
使用以下JSON 调用插件,包括prevResult
包含操作的JSON响应的字段ADD
:
{
"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" ]
}
}
}
- 接下来
tuning
使用以下JSON 调用插件,包括prevResult
包含操作的JSON响应的字段ADD
:
{
"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列表,容器运行时将为该DEL
操作执行以下步骤。请注意,插件的执行顺序与ADD
和CHECK
动作相反。
- 首先
tuning
使用以下JSON 调用插件,包括prevResult
包含操作的JSON响应的字段ADD
:
{
"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" ]
}
}
}
- 接下来
bridge
使用以下JSON 调用插件,包括prevResult
包含来自ADD
操作的JSON响应的字段:
{
"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分配
作为其操作的一部分,期望CNI插件为接口分配(和维护)IP地址并安装与该接口相关的任何必要路由。这为CNI插件提供了极大的灵活性,但也给它带来了很大的负担。许多CNI插件需要具有相同的代码才能支持用户可能需要的几种IP管理方案(例如dhcp,host-local)。
为了减轻负担并使IP管理策略与CNI插件的类型正交,我们定义了第二种类型的插件 - IP地址管理插件(IPAM插件)。然而,CNI插件的责任是在其执行的适当时刻调用IPAM插件。IPAM插件必须确定接口IP /子网,网关和路由,并将此信息返回到“主”插件以应用。IPAM插件可以通过协议(例如dhcp),存储在本地文件系统上的数据,网络配置文件的“ipam”部分或上述的组合来获得信息。
IP地址管理(IPAM)接口
与CNI插件一样,通过运行可执行文件来调用IPAM插件。在预定义的路径列表中搜索可执行文件,通过CNI插件指示CNI_PATH
。IPAM插件必须接收传递给CNI插件的所有相同环境变量。就像CNI插件一样,IPAM插件通过stdin接收网络配置。
必须通过零返回代码指示成功,并将以下JSON打印到stdout(在ADD命令的情况下):
{
"cniVersion": "0.4.0",
"ips": [
{
"version": "<4-or-6>",
"address": "<ip-and-prefix-in-CIDR>",
"gateway": "<ip-address-of-the-gateway>" (optional)
},
...
],
"routes": [ (optional)
{
"dst": "<ip-and-prefix-in-cidr>",
"gw": "<ip-of-next-hop>" (optional)
},
...
]
"dns": { (optional)
"nameservers": <list-of-nameservers> (optional)
"domain": <name-of-local-domain> (optional)
"search": <list-of-search-domains> (optional)
"options": <list-of-options> (optional)
}
}
请注意,与常规CNI插件不同,IPAM插件应返回Result
不包含interfaces
密钥的缩写结构,因为IPAM插件应该不知道由其父插件配置的接口,除了IPAM特别需要的接口(例如,像dhcp
IPAM插件)。
cniVersion
指定IPAM插件使用的CNI规范的语义版本2.0。IPAM插件可能支持多个CNI规范版本(因为它通过VERSION
命令报告),此处cniVersion
结果中IPAM插件返回的内容必须与网络配置中cniVersion
指定的一致。如果IPAM插件不支持网络配置,则插件应返回错误代码1(有关详细信息,请参阅众所周知的错误代码)。cniVersion
该ips
字段是IP配置信息的列表。有关更多信息,请参阅IP知名结构部分。
该dns
字段包含由常见DNS信息组成的字典。有关更多信息,请参阅DNS知名结构部分。
错误和日志的传达方式与CNI插件相同。有关详细信息,请参阅CNI插件结果部分。
IPAM插件示例:
- host-local:在指定范围内选择未使用的(由同一主机上的其他容器)IP。
- dhcp:使用DHCP协议获取和维护租约。DHCP请求将通过创建的容器接口发送; 因此,相关网络必须支持广播。
笔记
- 预计路由将添加0度量标准。
- 可以通过“0.0.0.0/0”指定默认路由。由于另一个网络可能已经配置了默认路由,因此CNI插件应该准备跳过其默认路由定义。
着名的结构
IPs
"ips": [
{
"version": "<4-or-6>",
"address": "<ip-and-prefix-in-CIDR>",
"gateway": "<ip-address-of-the-gateway>", (optional)
"interface": <numeric index into 'interfaces' list> (not required for IPAM plugins)
},
...
]
该ips
字段是由插件确定的IP配置信息的列表。每个项目都是描述网络接口的IP配置的字典。多个网络接口的IP配置和单个接口的多个IP配置可以作为ips
列表中的单独项目返回。即使没有严格要求,也应提供插件已知的所有属性。
-
version
(字符串):“4”或“6”,对应于条目中IP地址的IP地址。提供的所有IP地址和网关必须对给定的有效version
。 -
address
(字符串):CIDR表示法中的IP地址(例如“192.168.1.3/24”)。 -
gateway
(字符串):此子网的默认网关(如果存在)。它不会指示CNI插件使用此网关添加任何路由:要添加的路由通过该routes
字段单独指定。使用此值的一个示例是CNIbridge
插件将此IP地址添加到Linux网桥以使其成为网关。 -
interface
(uint):CNI插件结果interfaces
列表的索引,指示应该将此IP配置应用于哪个接口。IPAM插件不应返回此密钥,因为它们没有关于网络接口的信息。
Routes
"routes": [
{
"dst": "<ip-and-prefix-in-cidr>",
"gw": "<ip-of-next-hop>" (optional)
},
...
]
- 每个
routes
条目都是包含以下字段的字典。routes
条目中的所有IP地址必须是相同的IP版本,4或6。-
dst
(字符串):以CIDR表示法指定的目标子网。 -
gw
(字符串):网关的IP。如果省略,则假定使用默认网关(由CNI插件确定)。
-
DNS
"dns": {
"nameservers": <list-of-nameservers> (optional)
"domain": <name-of-local-domain> (optional)
"search": <list-of-additional-search-domains> (optional)
"options": <list-of-options> (optional)
}
该dns
字段包含由常见DNS信息组成的字典。
-
nameservers
(字符串列表):此网络知道的DNS名称服务器的优先级排序列表。列表中的每个条目都是包含IPv4或IPv6地址的字符串。 -
domain
(字符串):用于短主机名查找的本地域。 -
search
(字符串列表):用于短主机名查找的优先级排序搜索域列表。domain
大多数解析器都会优先考虑。 -
options
(字符串列表):可以传递给解析程序的选项列表。有关详细信息,请参阅CNI插件结果部分。
众所周知的错误代码
除此处指定外,不得使用错误代码1-99。
-
1
- 不兼容的CNI版本 -
2
- 网络配置中不支持的字段。错误消息必须包含不受支持的字段的键和值。 -
3
- 容器未知或不存在。此错误意味着运行时不需要执行任何容器网络清理(例如,DEL
在容器上调用操作)。
网友评论