3

深入解读 CNI:容器网络接口

 1 month ago
source link: https://jimmysong.io/blog/cni-deep-dive/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击查看目录

在容器化环境中,有效管理网络是至关重要的。容器网络接口(CNI)是一个标准,定义了容器应如何配置网络。本文将深入探讨 CNI 的基础知识,并带你了解 CNI 与 CRI 的关系。

什么是 CNI?

CNI(容器网络接口)规范为容器运行时和网络插件之间提供了一个通用的接口,旨在实现容器网络配置的标准化。

CNI 规范包含以下几个核心组成部分:

  • 网络配置的格式:定义了管理员如何定义网络配置。
  • 请求协议:描述了容器运行时如何向网络插件发出网络配置或清理请求。
  • 插件执行过程:详细阐述了插件如何根据提供的配置执行网络设置或清理。
  • 插件委派:允许插件将特定功能委托给其他插件执行。
  • 结果返回:定义了插件执行完成后如何向运行时返回结果的数据格式。

CNI 规范通过定义这些核心组成部分,确保了不同的容器运行时和网络插件能够以一致的方式进行交互,实现网络配置的自动化和标准化。

CNI 规范的一些要点
  • CNI 是一个插件化的容器化网络解决方案
  • CNI 插件为可执行文件
  • 单个 CNI 插件的职责是单一的
  • CNI 插件是呈链式调用的
  • CNI 规范为一个容器定义一个 Linux 网络命名空间
  • CNI 的网络定义存储为 JSON 格式
  • 网络定义通过 STDIN 输入流传输到插件,这意味着宿主机上不会存储网络配置文件,其他的配置参数通过环境变量传递给插件

CNI 插件根据操作类型,接收相应的网络配置参数,执行网络配置或清理任务,并返回执行结果。这一流程确保了容器网络的动态配置与容器生命周期的同步。

下图展示了 CNI 包含了众多的网络插件。



Container Runtime
Container Network Interface (CNI)
Loopback Plugin
Bridge Plugin
PTP Plugin
MACvlan Plugin
IPvlan Plugin
3rd-Party Plugin

根据 CNI 规范 ,一个 CNI 插件负责以某种方式配置容器的网络接口。插件可分为两大类:

  • “接口"插件,负责在容器内部创建网络接口并确保其具有连通性。
  • “链式"插件,调整已创建接口的配置(但可能需要创建更多接口以完成此操作)。

CNI 与 CRI 的关系

CNI 和 CRI(容器运行时接口)是 Kubernetes 中两个关键的接口,它们分别处理容器的网络配置和运行时管理。在 Kubernetes 集群中,CRI 调用 CNI 插件来配置或清理容器的网络,这确保了网络配置的过程与容器的创建和销毁过程紧密协调。

下图直观地展示了 CNI 如何与 CRI 协同运行的:

PodContainer Network InterfaceContainer Runtime InterfaceKubeletPodContainer Network InterfaceContainer Runtime InterfaceKubelet创建 Pod 容器启动容器容器运行中容器准备就绪调用 CNI 进行网络设置连接网络网络配置完成Pod 网络就绪带有网络运行的 Pod
  1. Kubelet 到 CRI:Kubelet 指示 CRI 创建已调度的 Pod 的容器。
  2. CRI 到 Pod:容器运行时在 Pod 中启动容器。
  3. Pod 到 CRI:一旦容器运行,它会向容器运行时发出信号。
  4. CRI 到 Kubelet:容器运行时通知 Kubelet 容器已准备就绪。
  5. Kubelet 到 CNI:容器已启动,Kubelet 调用 CNI 为 Pod 设置网络。
  6. CNI 到 Pod:CNI 为 Pod 配置网络,将其连接到必要的网络接口。
  7. Pod 到 CNI:网络配置完成后,Pod 向 CNI 确认网络设置。
  8. CNI 到 Kubelet:CNI 通知 Kubelet Pod 的网络已准备就绪。
  9. Kubelet 到 Pod:现在 Pod 完全可操作,两个容器均已运行且网络已配置。

下图展示了在 Kubernetes 中为 Pod 设置网络所涉及的详细步骤:

IP Address ManagementNetwork SetupContainer Network InterfaceKubeletPodIP Address ManagementNetwork SetupContainer Network InterfaceKubeletPodPod 调度触发网络设置CNI 处理网络命名空间创建和 IP 地址分配调度 Pod请求网络设置调用 CNI创建网络命名空间命名空间已创建分配 IP 地址IP 地址已分配设置网络接口网络设置完成带有网络运行的 Pod
  1. Pod 调度:Kubelet 在节点上调度一个 Pod 运行。
  2. 请求网络设置:已调度的 Pod 请求 Kubelet 进行网络设置。
  3. 调用 CNI:Kubelet 调用 CNI 处理 Pod 的网络设置。
  4. 创建网络命名空间:CNI 为 Pod 创建一个网络命名空间,隔离其网络环境。
  5. 分配 IP 地址:CNI 通过其 IP 地址管理(IPAM)插件为 Pod 分配一个 IP 地址。
  6. 设置网络接口:CNI 在 Pod 的网络命名空间内设置必要的网络接口,将其连接到网络。
  7. 网络设置完成:Pod 通知 Kubelet 其网络设置已完成。
  8. 带有网络运行的 Pod:Pod 现在已经运行,并且其网络已配置,可以与 Kubernetes 集群中的其他 Pod 和服务通信。

CNI 工作流程

容器网络接口(CNI)规范定义了容器如何配置网络,其中包括 ADDCHECKDELETEGCVERSION 五种操作。容器运行时通过调用各种 CNI 插件来执行这些操作,从而实现容器网络的动态管理和更新。

IP Address ManagementNetwork SetupChained CNI PluginInterface CNI PluginCNI PluginsPodKubeletIP Address ManagementNetwork SetupChained CNI PluginInterface CNI PluginCNI PluginsPodKubeletCNI插件可以是接口类型或链式类型调度 Pod请求网络设置调用 CNI 插件调用接口插件设置网络接口调用链式插件分配 IP 地址IP 地址已分配应用网络策略链式配置完成网络设置完成带有网络运行的 Pod

为了详细说明序列图中描述的每个步骤,涉及 Kubelet、Pod、CNI 插件(包括接口和链式 CNI 插件)、网络设置和 IP 地址管理(IPAM)之间的交互,让我们深入了解这个过程:

  1. 调度 Pod:Kubelet 安排一个 Pod 在节点上运行。这一步启动了 Kubernetes 集群中 Pod 的生命周期。
  2. 请求网络设置:Pod 向 Kubelet 发出网络设置请求。这个请求触发了为 Pod 配置网络的过程,确保它可以在 Kubernetes 集群内进行通信。
  3. 调用 CNI 插件:Kubelet 调用配置的容器网络接口(CNI)插件。CNI 定义了一个标准化的方式,用于容器管理系统在 Linux 容器中配置网络接口。Kubelet 将必要的信息传递给 CNI 插件,以启动网络设置。
  4. 调用接口插件:CNI 框架调用一个接口 CNI 插件,负责为 Pod 设置主要的网络接口。这个插件可能会创建一个新的网络命名空间、连接一对 veth 或执行其他操作,以确保 Pod 具有所需的网络接口。
  5. 设置网络接口:接口 CNI 插件为 Pod 配置网络接口。这个设置包括分配 IP 地址、设置路由和确保接口准备好通信。
  6. 调用链式插件:在设置网络接口之后,接口 CNI 插件或 CNI 框架调用链式 CNI 插件。这些插件执行额外的网络配置任务,比如设置 IP 伪装、配置入口/出口规则或应用网络策略。
  7. 分配 IP 地址:作为链式过程的一部分,链式 CNI 插件中的一个可能涉及 IP 地址管理(IPAM)。IPAM 插件负责为 Pod 分配一个 IP 地址,确保每个 Pod 在集群或命名空间内具有唯一的 IP。
  8. IP 地址已分配:IPAM 插件分配了一个 IP 地址,并将分配信息返回给调用插件。这些信息通常包括 IP 地址本身、子网掩码和可能的网关。
  9. 应用网络策略:链式 CNI 插件将任何指定的网络策略应用于 Pod 的网络接口。这些策略可以规定允许的入口和出口流量,确保根据集群的配置要求进行网络安全和隔离。
  10. 链式配置完成:一旦所有链式插件完成了它们的任务,Pod 的整体网络配置被认为已完成。CNI 框架或链中的最后一个插件向 Kubelet 发送信号,表明网络设置已完成。
  11. 网络设置完成:Kubelet 收到了 Pod 的网络设置完成的确认。此时,Pod 具有完全配置的网络接口,具有 IP 地址、路由规则和应用的网络策略。
  12. 带有网络运行的 Pod:Pod 现在已经运行,并配置了网络。它可以与 Kubernetes 集群中的其他 Pod 通信,根据网络策略访问外部资源,并执行其指定的功能。

以下是针对 CNI 官方示例 中的 ADD 操作、CHECK 操作和 DELETE 操作的示例序列图以及详细说明。通过这些操作,容器运行时与 CNI 插件之间进行交互,实现容器网络配置的动态管理和更新。

ADD 操作示例

以下是 ADD 操作的示例序列图以及详细说明:

Host-local PluginBridge PluginTuning PluginPortmap PluginContainer RuntimeHost-local PluginBridge PluginTuning PluginPortmap PluginContainer RuntimeCNI_COMMAND=ADDPortmap 配置完成CNI_COMMAND=ADDTuning 配置完成CNI_COMMAND=ADDCNI_COMMAND=ADDIPAM 配置完成Bridge 配置完成
  1. 容器运行时调用 Portmap 插件:容器运行时通过调用 Portmap 插件执行 ADD 操作,配置容器的端口映射。
  2. Portmap 配置完成:Portmap 插件完成端口映射配置,并将结果返回给容器运行时。
  3. 容器运行时调用 Tuning 插件:容器运行时调用 Tuning 插件执行 ADD 操作,配置容器的网络调优参数。
  4. Tuning 配置完成:Tuning 插件完成网络调优参数配置,并将结果返回给容器运行时。
  5. 容器运行时调用 Bridge 插件:容器运行时调用 Bridge 插件执行 ADD 操作,配置容器的网络接口和 IP 地址。
  6. Bridge 插件调用 Host-local 插件:在完成自身配置之前,Bridge 插件调用 Host-local 插件执行 ADD 操作,配置容器的 IP 地址。
  7. IPAM 配置完成:Host-local 插件作为 IP 地址管理(IPAM)的授权方,完成 IP 地址分配,并将结果返回给 Bridge 插件。
  8. Bridge 配置完成:Bridge 插件完成网络接口和 IP 地址配置,并将结果返回给容器运行时。

这些操作确保了在容器启动时,其所需的网络配置能够按照预期进行设置,包括端口映射、网络调优和 IP 地址分配等。

CHECK 操作示例

以下是 CHECK 操作的示例序列图以及详细说明:

Tuning PluginHost-local PluginBridge PluginContainer RuntimeTuning PluginHost-local PluginBridge PluginContainer RuntimeCNI_COMMAND=CHECK with prevResultCNI_COMMAND=CHECK返回无错误返回 0 返回码CNI_COMMAND=CHECK with prevResult操作成功
  1. 容器运行时调用 Bridge 插件进行检查:容器运行时通过调用 Bridge 插件执行 CHECK 操作,检查容器的网络配置是否符合预期。
  2. Bridge 插件调用 Host-local 插件:Bridge 插件调用 Host-local 插件执行 CHECK 操作,检查 IP 地址分配是否正常。
  3. 返回无错误:Host-local 插件检查 IP 地址分配无异常,并返回无错误给 Bridge 插件。
  4. 返回 0 返回码:Bridge 插件检查网络配置无异常,并返回 0 返回码给容器运行时。
  5. 容器运行时调用 Tuning 插件进行检查:容器运行时调用 Tuning 插件执行 CHECK 操作,检查网络调优参数是否符合预期。
  6. 操作成功:Tuning 插件检查网络调优参数无异常,返回操作成功给容器运行时。

这些操作确保了在容器运行期间,其网络配置和网络调优参数能够按照预期进行检查和验证,以确保网络配置的一致性和正确性。

DELETE 操作示例

以下是 DELETE 操作的示例序列图以及详细说明:

Host-local PluginBridge PluginTuning PluginPortmap PluginContainer RuntimeHost-local PluginBridge PluginTuning PluginPortmap PluginContainer RuntimeCNI_COMMAND=DELPortmap 删除完成CNI_COMMAND=DELTuning 删除完成CNI_COMMAND=DELCNI_COMMAND=DELIPAM 删除完成Bridge 删除完成
  1. 容器运行时调用 Portmap 插件:容器运行时通过调用 Portmap 插件执行 DELETE 操作,删除容器的端口映射配置。
  2. Portmap 删除完成:Portmap 插件完成端口映射的删除,并将结果返回给容器运行时。
  3. 容器运行时调用 Tuning 插件:容器运行时调用 Tuning 插件执行 DELETE 操作,删除容器的网络调优参数配置。
  4. Tuning 删除完成:Tuning 插件完成网络调优参数的删除,并将结果返回给容器运行时。
  5. 容器运行时调用 Bridge 插件:容器运行时调用 Bridge 插件执行 DELETE 操作,删除容器的网络接口和 IP 地址配置。
  6. Bridge 插件调用 Host-local 插件:在完成自身删除之前,Bridge 插件调用 Host-local 插件执行 DELETE 操作,删除容器的 IP 地址分配。
  7. IPAM 删除完成:Host-local 插件完成 IP 地址分配的删除,并将结果返回给 Bridge 插件。
  8. Bridge 删除完成:Bridge 插件完成网络接口和 IP 地址的删除,并将结果返回给容器运行时。

这些操作确保了在容器停止运行时,其所需的网络配置能够被正确清理和移除,以确保网络资源的有效释放和管理。

通过对 ADD、CHECK 和 DELETE 操作的示例序列图及详细说明,可以清晰地了解容器运行时与 CNI 插件之间的交互过程,以及如何实现容器网络配置的动态管理和更新。

CNI 为容器化环境中的网络管理提供了一种标准化的接口,通过与 CRI 的配合,确保了 Kubernetes 集群中容器的网络配置高效且一致。通过深入理解 CNI,开发者和系统管理员可以更好地管理和优化其容器网络。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK