CNI规范(译)

Contents

本文翻译自 https://github.com/containernetworking/cni/blob/main/SPEC.md,为了更好的在中文的语境下理解原意,本译文可能在某些地方并未原封不动的翻译原文。

版本

当前规范版本为 1.0.0

注意,这个规范与 containernetworking/cni 中的代码是独立的。

下面是已经发布的规范版本:

tag spec permalink major changes
spec-v1.0.0 spec at v1.0.0 Removed non-list configurations; removed version field of interfaces array
spec-v0.4.0 spec at v0.4.0 Introduce the CHECK command and passing prevResult on DEL
spec-v0.3.1 spec at v0.3.1 none (typo fix only)
spec-v0.3.0 spec at v0.3.0 rich result type, plugin chaining
spec-v0.2.0 spec at v0.2.0 VERSION command
spec-v0.1.0 spec at v0.1.0 initial version

概览

本文档起草了容器网络的通用解决方案,即 CNI(Container Networking Interface)。

为了明确目的,我们定义了以下 3 个术语(译者注:为了表述更准确,直接贴上原文):

本文档主要目的是定义 runtimes 与 plugins 之间的接口。文档中的关键字 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、RECOMMENDED、MAY 和 OPTIONAL 的定义见 RFC 2119

总结

CNI 规范定义了如下内容:

  1. 管理员定义网络配置的格式(译者注:通常是配置文件)
  2. runtime 请求 plugin 的 protocol 格式
  3. plugin 执行网络配置的流程
  4. plugin 为其它 plugin 提供的功能
  5. plugin 返回给 runtime 的类型

译者注:为了方便理解上面的定义,整理一张图

Section 1:Network configuration format

CNI 为管理员定义了网络配置的格式。网络配置的消费者有 runtime 与 plugin。在执行 plugin 时,runtime 会将配置转换后,再传给 plugin。

通常来说,网络配置是静态的。虽然 CNI 规范没有要求网络配置的存储方式,但它通常保存在磁盘中。

Configuration format

一份网络配置包含一个 JSON 对象,对象包含如下字段:

Plugin configuration objects

Plugin 配置对象中除了本文档定义的字段,还可以包含额外的字段。runtime 必须将这些额外的字段原封不动的传给 plugin(详情见 section 3)。

Required keys
Optional keys,used by the protocol
Reserved keys,used by the protocol

这些字段由 runtime 在执行期间生成,所以不能在配置文件中使用。

Optional keys,well-known

这些字段不能被 protocol 使用,但是对于 plugin 来说是有意义的。如果 plugin 使用这些字段,应该(SHOULD)遵循它们的语义。

Other keys

这些字段只能被 plugin 识别。当 runtime 在使用网络配置时必须将这些字段保留下来。

Example configuration
{
  "cniVersion": "1.0.0",
  "name": "dbnet",
  "plugins": [
    {
      "type": "bridge",
      // plugin specific parameters
      "bridge": "cni0",
      "keyA": ["some more", "plugin specific", "configuration"],
      "ipam": {
        "type": "host-local",
        // ipam specific
        "subnet": "10.1.0.0/16",
        "gateway": "10.1.0.1",
        "routes": [
            {"dst": "0.0.0.0/0"}
        ]
      },
      "dns": {
        "nameservers": [ "10.1.0.1" ]
      }
    },
    {
      "type": "tuning",
      "capabilities": {
        "mac": true
      },
      "sysctl": {
        "net.core.somaxconn": "500"
      }
    },
    {
        "type": "portmap",
        "capabilities": {"portMappings": true}
    }
  ]
}

Section 2:Execution Protocol

Overview

CNI protocol 是 runtime 与 plugin 二进制之间的通信协议。

CNI plugin 主要负责以某种方式配置容器的网络接口。主要分为两大类:

Runtime 通过环境变量和配置(配置通过 sdtin 传递)传递参数给 plugin。Plugin 的执行结果(格式见 section 5)通过 stdout 或者 stderr 返回给 runtime。配置和执行结果都遵循 JSON 格式。

每次调用,runtime 传给 plugin 的参数通常是不同的,但其中配置是不变的(译者注:意思是每次调用只有环境变量会发生变化)。

Runtime 必须在它自己的网络隔离域中执行 plugin(通常是根网络命名空间 dom0)。

Parameters

Runtime 调用 plugin 使用的环境变量如下:

译者注:CNI_COMMANDCNI_CONTAINERID 共同组成 plugin 操作网络的唯一标识。

Errors

如果执行成功,插件返回 0;如果执行失败,插件返回特定的 JSON 对象(详情见 section 5)。

CNI operations

CNI 操作通过 CNI_COMMAND 传给 plugin,有如下 4 种操作:

ADD

向容器中添加网络。当 plugin 接受到 ADD 命令后,会完成以下两件事之一:

如果容器中已经存在相同的接口名,plugin 必须返回错误。

input

输入分为 3 部分:

DEL

从容器中删除网络。当 plugin 接受到 DEL 命令后,会完成以下两件事之一:

通常来说,在执行 DEL 的过程中,即使发生了某些错误(译者注:例如需要操作的容器网络命名空间被删除),也应该忽略。

input

输入分为 3 部分:

译者注:这里 CNI_NETNS 变成了可选参数

CHECK

Runtime 通过 CHECK 命令检查容器的网络是否符合预期。

对于 plugin 来说:

对于 runtime 来说:

input

输入分为 3 部分(对于同一个容器,所有参数除了 CNI_PATH,必须与 ADD 保持一致 ):

VERSION

检查 plugin 支持的版本。

input

输入分为 3 部分:

Section 3:Execution of Network Configurations

本节讨论 runtime 如何将配置转换成对 plugin 的各种 ADDDELVERSION 等操作。

将配置文件应用到容器上的操作称为 attachment,由 (CNI_CONTAINERID, CNI_IFNAME) 元组唯一标识。

Lifecycle & Ordering

Attachment Parameters

尽管不同 attachment 应该使用同一份配置文件,但是以下参数在不同 attachment 间是变化的:

另外,需要向 runtime 提供 plugin 的地址列表,这个列表还需要通过环境变量 CNI_PATH 传递给 plugin。

Adding an attachment

遍历配置文件中的 plugins 字段(plugins 字段的类型是 list),每次遍历依次完成如下工作:

注:过程中遇到错误则返回

Deleting an attachment

译者注:与 Adding an attachment 中的流程基本相同,具体区别见原文

Checking an attachment

Runtime 可以通过 plugin 检查 attachment 是否生效。检查时使用的参数与执行 ADD 时的参数保持一致。

译者注:与 Adding an attachment 中的流程基本相同,具体区别见原文

Deriving execution configuration from plugin configuration

配置文件中的 plugins 列表需要转换成 plugin 能识别的格式(即 plugin configuration 转换成 execution configuration)。转换过程中,大部分内容不会变更,除了向每个 plugin 的 execution configuration 中插入:

Deriving runtimeConfig

Runtime 需要移除 capabilities 字段,并将其转换成 plugin 能识别的方式。

转换前:

{
  "type": "myPlugin",
  "capabilities": {
    "portMappings": true
  }
}

转换后:

{
  "type": "myPlugin",
  "runtimeConfig": {
    "portMappings": [ { "hostPort": 8080, "containerPort": 80, "protocol": "tcp" } ]
  }
  ...
}

Section 4:Plugin Delegation

TODO

Section 5:Result Types

Plugin 通常返回以下 3 种类型之一:

Success

Runtime 会提供给 plugin 上一个 plugin 执行的结果 prevResult,然后将 prevResult 返回。这个过程中,plugin 可能会修改 prevResult 的值。如果 plugin 没有修改 prevResult,那么说明 plugin 的执行结果为 success。

执行 ADD 成功后,返回如下 JSON 结构:

Error

如果 plugin 在执行过程遇到错误,它应该返回如下格式的错误信息:

{
  "cniVersion": "1.0.0",
  "code": 7,
  "msg": "Invalid Configuration",
  "details": "Network 192.168.0.0/31 too small to allocate from."
}

错误码 0-99 为保留错误码。

错误码 错误描述
1 CNI 版本不兼容
2 配置文件中存在不支持的字段。错误信息中必须包含不支持的字段相关信息
3 容器不存在。如果返回这个错误,意味着 runtime 不用负责清理(例如,执行 DEL 动作)
4 无效的参数(如 CNI_COMMAND, CNI_CONTAINERID 等)
5 I/O 错误( 如无法从 stdin 中读取配置文件)
6 反序列化错误(如将配置文件反序列化成结构体出错)
7 配置文件无效
11 可以重试的错误

另外, stderr 可以输出非结构化的信息(如日志)

Version

执行 VERSION 成功后,返回如下 JSON 结构:

{
    "cniVersion": "1.0.0",
    "supportedVersions": [ "0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0" ]
}

Latest update: 2022/06/24

© 2019 - 2024 · Thinking Cell · Theme Simpleness Powered by Hugo ·