了解 Kube-OVN CNI
Kube-OVN 使用 Open Virtual Network (OVN) 和 Open vSwitch (OVS) 连接 Kubernetes Pod。它负责分配 Pod 地址、构建逻辑网络,以及实现网络策略和 Service 负载均衡。
本页介绍 Kube-OVN 架构、逻辑网络、配置更新和常见流量路径。此外,还提供组件检查示例和配置指南链接。
目录
网络模式和范围架构和组件控制平面组件kube-ovn-controllerovn-central节点组件ovs-ovnkube-ovn-cni监控和可选组件kube-ovn-pingerkube-ovn-monitorkube-ovn-speaker组件部署逻辑网络逻辑交换机和 SubnetIP 地址分配和 Subnet 选择join 交换机和节点接口覆盖封装网关模式网络隔离和访问控制网络变更如何成为流流量路径同一节点上的 Pod 到 Pod跨节点的 Pod 到 PodPod 到 ServicePod 到节点或 API serverPod 到外部网络高可用性检查集群中的组件列出工作负载查找 Pod 和容器检查滚动更新状态和事件资源使用量和限制kubectl-ko后续步骤网络模式和范围
Kube-OVN 支持 Overlay 和 Underlay 子网。网络模式决定 Pod 流量如何到达其他节点和物理网络。
本页中的流量路径示意图描述的是默认 VPC 中使用 Geneve 隧道的 Overlay 网络。Service 示意图还假设已为控制器和源子网启用 OVN Service 负载均衡。示例中显示的名称和 CIDR 作为默认值,可能与你的集群配置不同;请与管理员确认子网设置和已安装的 Kube-OVN 配置。
架构和组件
控制平面维护所需的网络状态,并将其转换为转发规则。节点组件连接 Pod 接口,并在 OVS 中实现这些规则。监控和可选组件提供运行状况信息及外部集成功能。

控制平面组件
kube-ovn-controller
kube-ovn-controller Deployment 监视与网络相关的 Kubernetes 资源,包括 Pod、Services、EndpointSlices、Nodes、NetworkPolicies、VPC、Subnets、VLANs 和 ProviderNetworks。
它为 Pod 分配地址,将逻辑端口以及所需的路由或策略写入 OVN northbound 数据库,并在 Pod 注解中记录已分配的网络信息,供节点智能体使用。
ovn-central
ovn-central Deployment 在其 ovn-central 容器中运行 OVN 控制平面服务:
ovn-nb:northbound 数据库存储所需的逻辑网络,包括交换机、路由器、端口、ACL 和负载均衡器。ovn-sb:southbound 数据库存储逻辑流、数据路径和端口绑定,以及 chassis 状态。ovn-northd:将 northbound 配置转换为逻辑流及 southbound 数据库使用的相关记录。
有关上游实现细节,请参阅 OVN 架构。有关组件故障的影响,请参阅高可用性。
节点组件
ovs-ovn
ovs-ovn DaemonSet 在每个符合条件的 Linux 节点上运行一个 openvswitch 容器。该容器包含本地 OVS 数据库、ovn-controller 和 ovs-vswitchd。OVS 数据库存储网桥和接口配置,ovn-controller 编写转发规则,ovs-vswitchd 则通过 OVS 数据路径管理数据包转发。
kube-ovn-cni
kube-ovn-cni DaemonSet 在每个符合条件的 Linux 节点上运行一个 cni-server 容器。其 install-cni init 容器会将 kube-ovn CNI 插件及支持二进制文件安装到主机的 CNI 二进制文件目录(默认为 /opt/cni/bin),并默认将 CNI 配置写入 /etc/cni/net.d。容器运行时会调用 kube-ovn 插件,该插件向本地 cni-server 发送 CNI 请求。
节点侧 CNI 插件和 cni-server 协同完成以下工作:
- 在 CNI ADD 期间配置 Pod 接口、IP 地址和路由,并在 CNI DEL 期间移除相应的连接。
- 将 Pod 接口连接到 OVS 端口,并维护其本地网络配置。
cni-server 守护进程还通过以下方式维护节点网络:
- 持续协调主机网关过滤、NAT 和路由规则。
- 创建并配置
ovn0,将主机网络连接到默认 VPC。
其他节点网络配置有各自的要求。请参阅准备 Underlay 物理网络和集群互联(Alpha)。
监控和可选组件
kube-ovn-pinger
kube-ovn-pinger DaemonSet 在每个符合条件的 Linux 节点上运行一个 pinger 容器,用于收集 OVS 状态信息,并探测网络连通性和延迟。
kube-ovn-monitor
kube-ovn-monitor Deployment 收集 OVN 状态信息和指标。在标准部署中,它运行于为 OVN 中央服务选定的节点上。
kube-ovn-speaker
此可选 DaemonSet 运行于为 BGP 通告选定的节点上,并将路由发布到外部网络,使外部网络可以直接通过 Pod IP 访问。有关安装和 BGP 选项,请参阅配置 BGP。
组件部署
下表介绍 OVN 控制平面与 ACP 安装在同一集群中的标准 ACP 安装。默认情况下,Kubernetes 工作负载使用 kube-system 命名空间。如果你的安装使用其他命名空间,或使用单独托管的 OVN 控制平面,请使用实际的命名空间和工作负载配置。
节点选择器、亲和性和容忍度决定哪些节点符合条件。Deployment 副本数取决于安装方式;DaemonSet 会在每个符合条件的节点上放置一个 Pod。可选的 speaker 按照配置 BGP中的说明单独安装。
有关命令和实际示例输出,请参阅检查集群中的组件。
逻辑网络
OVN 将集群网络建模为逻辑交换机和逻辑路由器,Kube-OVN 则将 Kubernetes 资源映射到这些组件上。VPC 会根据其逻辑路由配置将 Subnet 组织在一起。下图展示了默认 VPC,包括将其连接到主机的 join 交换机。自定义 VPC 拥有自己的逻辑路由器,并且需要单独配置路由和外部连接。有关资源字段,请参阅 VPC API 参考。

在此默认 VPC 覆盖网络中,Pod 连接到其 Subnet 的逻辑交换机,Subnet 网关将该交换机连接到 VPC 逻辑路由器,而 join 将路由器连接到节点的 ovn0 端口。OVS 在节点上实现逻辑交换和路由。跨节点覆盖流量使用隧道;发往主机或外部网络的流量通过相应的节点接口离开覆盖网络。以下各节将介绍其中的每个部分。
逻辑交换机和 Subnet
每个由 OVN 管理的 Subnet 都由一个逻辑交换机承载。连接到 Subnet 的 Pod 会成为逻辑交换机端口。Namespace 可以拥有自己的 Subnet,也可以与其他 Namespace 共享一个 Subnet。
kube-ovn-controller 从选定的 Subnet 分配 Pod IP 地址。可以为 Pod 指定 MAC 地址,也可以由 IPAM 生成。控制器会在 Pod 注解中记录已分配的 IP 和 MAC 地址,以及 Subnet CIDR、网关和逻辑交换机。节点侧 CNI 组件会结合这些信息及其他路由配置,配置 Pod 接口和路由。
默认 Subnet ovn-default 在标准默认 VPC 部署中承载 Pod 网络。自定义 VPC 拥有自己的逻辑路由器和 Subnet。为一个 Pod 连接多个接口是单独的配置,详见 Pod 多网络接口。
IP 地址分配和 Subnet 选择
Kube-OVN 会从为每个 Pod 接口选择的 Subnet 中分配地址。对于主网络,平台的项目或 Namespace 绑定决定可用的 Subnet,除非 Pod 显式选择了 Subnet。如果没有显式选择或绑定,Pod 将使用其 VPC 的默认 Subnet。有关平台分配规则,请参阅 配置 Subnet。
规划地址时,请考虑以下事项:
- 可用地址:Subnet CIDR 定义地址范围。
excludeIps中的保留地址不会自动分配;保留地址并不会将其分配给 Pod。 - IP 池:IPPool 将分配范围限制为 Subnet 内的一组地址。Namespace 或 Pod 设置会选择该地址池。在符合条件的地址池中地址耗尽,并不意味着 Pod 可以使用 Subnet 中其他位置的剩余地址。
- 地址耗尽:如果没有可用的符合条件的地址,Pod 网络设置将无法完成。请检查 Pod 事件,以及其选定 Subnet 或 IPPool 中的可用地址。
- Pod 替换:替换 Pod 不一定会通过自动分配获得之前 Pod 的地址。如果应用需要稳定的访问地址,请使用 Service。
请选择与集群配置匹配的 CIDR 和地址族。检查其是否与节点网络、Service CIDR、join 以及 Pod 必须访问的外部网络发生冲突。对于 Pod 的辅助接口,请按照 Pod 多网络接口 中的独立 Subnet 和网络附加配置进行操作。
join 交换机和节点接口
节点不属于 Pod Subnet。Kube-OVN 通过专用逻辑交换机 join(默认 CIDR 为 100.64.0.0/16)以及节点上名为 ovn0 的 OVS 内部端口,将每个节点连接到覆盖网络。
ovn0 将主机网络连接到默认 VPC。kube-ovn-controller 从 join Subnet 为节点分配地址,并将其记录在 Node 注解中;kube-ovn-cni 读取这些注解以创建和配置接口。下文的 Pod 到节点的路径 介绍了流量如何到达节点或该节点上的 API server 端点。
覆盖封装
在默认 Geneve 网络中,不同节点上的 OVS 实例通过隧道连接。ovn-controller 安装转发规则,OVS 将跨节点覆盖流量封装在 Geneve(UDP 6081)中,并将其发送到远程节点的封装地址。节点网络必须允许参与通信的节点之间传输此流量。有关由此产生的封装开销,请参阅 配置 MTU。
对于 underlay 流量,VLAN Subnet 通过 localnet 端口和 ProviderNetwork 的节点接口连接到物理网络。underlay 与 overlay Subnet 之间的连接需要适当的路由配置;请参阅 underlay 和 overlay Subnet 的自动互联。
网关模式
对于默认 VPC 中的 overlay Subnet,gatewayType 选择用于外部出口的节点。对于此 VPC 中除 join 之外的 Subnet,控制器会将省略的 gatewayType 设置为 distributed。
逻辑路由器使用策略路由,将这些流量定向到所选节点在 join 交换机上的地址:
- 分布式:每个节点都充当运行在其上的 Pod 的网关,因此南北向流量会通过本地节点退出。
- 集中式:外部出口会定向到选定的网关节点。默认情况下,多个网关节点使用主备模式;ECMP 需要
spec.enableEcmp: true。
这些模式控制外部出口;Pod 之间的流量或发往 Service 的流量不会自动通过集中式网关。请参阅下文的外部访问路径以及配置集中式网关。
网络隔离和访问控制
Namespace 或 Subnet 分配决定工作负载所属的位置以及其接收地址的方式。仅凭此分配,并不会阻止工作负载访问其他 Namespace 或 Subnet 中的工作负载。同一 VPC 中的 Subnet 可以通过其逻辑路由器进行通信,前提是路由和访问控制规则允许这样做。
请针对相应目的使用以下控制项:
对于标准 NetworkPolicy,入站和出站隔离会分别进行评估。当某个方向处于隔离状态时,该方向上的流量必须获得选择该 Pod 的策略允许;一个连接必须同时满足两端适用的规则。如果配置了集群范围的策略或 Subnet ACL,其操作和评估顺序也会影响结果。请参阅 Network Policy 和 Network Policy API。
使用 hostNetwork 的 Pod 共享节点网络,并且在 Subnet 上没有普通的 Pod 网络接口。请勿使用普通 Pod NetworkPolicy 假设来描述其隔离情况;应检查节点的访问控制以及已记录的策略限制。
网络变更如何成为流
Kubernetes 资源描述所需的网络状态。Kube-OVN 和 OVN 会将此配置转换为逐步细化的表示形式,直到每个节点都拥有转发数据包所需的 OpenFlow 规则。

箭头表示配置和状态更新。数据包转发在节点上的 OVS 中进行。
- 从 Kubernetes 资源到逻辑网络对象。
kube-ovn-controller监视 Pod、Subnet、Service 和 NetworkPolicy 等资源,并将其协调为 OVN northbound 数据库(ovn-nb)中的对象:逻辑交换机、路由器、端口、ACL 和负载均衡器描述所需的连接。 - 从逻辑网络对象到逻辑流。
ovn-northd读取 northbound 配置,并在 OVN southbound 数据库(ovn-sb)中构建逻辑处理管道。Logical_Flow记录描述匹配条件和操作;Datapath_Binding和Port_Binding记录标识逻辑数据路径和端口。 - 从逻辑流到节点本地 OpenFlow 规则。 每个节点上的
ovn-controller将 southbound 信息与其 chassis 标识和本地 OVS 接口状态结合起来。它会在本地 OVS 集成网桥br-int中安装 OpenFlow 规则,使 OVS 能够在该节点上实现逻辑网络。
Pod 接口设置会提供此过程所需的本地状态。创建 Pod 期间,节点侧 CNI 插件与 cni-server 协作,使用分配的 IP 和 MAC 地址配置 Pod 接口和 OVS 端口。OVS 接口的 external_ids:iface-id 标识对应的 OVN 逻辑端口,使 ovn-controller 能够将该端口与节点关联起来。ovn-controller 还会将 chassis 和端口绑定状态报告回 southbound 数据库。
管理员可以使用 kubectl-ko 检查这些层。
流量路径
下图描述了使用 Geneve 隧道的默认 VPC 覆盖网络。OVS 执行由 ovn-controller 安装的逻辑交换、路由和负载均衡规则。NetworkPolicy 和 Subnet ACL 可以允许或阻止这些路径上的流量。
底层网络和自定义 VPC 出口具有不同的拓扑。解读这些图时,请参考部署所采用的网络模式和范围。
同一节点上的 Pod 到 Pod
对于同一节点上同一 Subnet 中的两个 Pod,数据包会从源 Pod 接口经过本地 OVS 网桥 br-int,到达目标 Pod 接口。逻辑交换机提供转发规则;数据包不会经过物理 NIC 或 Geneve 隧道。

如果 Pod 属于同一 VPC 中的不同 Subnet,则由 VPC 逻辑路由器提供路由规则。如果两个 Pod 位于同一节点上,OVS 仍会在本地处理流量。
跨节点的 Pod 到 Pod
对于位于不同节点、但属于同一 Subnet 的 Pod,逻辑交换机会连接它们的逻辑端口,这些端口分别绑定到不同的节点 chassis。源 OVS 会将数据包封装到 Geneve 中,通过节点网络发送;目标 OVS 会对其解封装,并将其交付给目标 Pod。

如果 Pod 属于同一 VPC 中的不同 Subnet,逻辑路由器也会在 Subnet 之间路由数据包。跨节点的覆盖网络传输仍会使用 OVS 实例之间的 Geneve 隧道。
Pod 到 Service
为控制器和 Subnet 启用 OVN Service 负载均衡后,kube-ovn-controller 会在符合条件的 Subnet 逻辑交换机上维护 OVN 负载均衡器。OVS 会将 Service 虚拟 IP 和端口转换为选定后端端点的 IP 和目标端口。对于 Pod 后端,之后的转发会遵循上文介绍的同节点或跨节点路径。

join 交换机不会关联 OVN Service 负载均衡器。该图展示了使用 Pod 后端的普通覆盖网络 Pod 调用方。其他 Service 访问场景还需考虑以下条件:
有关创建和暴露 Service 的信息,请参阅配置 Service。将外部访问与集中式网关结合使用前,请先查看其主机端口和 hostport 限制。
Pod 到节点或 API server
对于发往节点内部 IP 的流量,默认 VPC 逻辑路由器会使用目标策略路由,将数据包导向该节点在 join 交换机上的地址。数据包通过目标主机的 ovn0 接口到达目标主机。发往远程节点的流量会在 OVS 实例之间通过 Geneve 传输;发往本地节点的流量则留在本地。

直接访问节点内部 IP 上的 API server 端点时,流量会遵循此节点访问路径。通过 kubernetes Service 虚拟 IP 访问时,首先会将 Service 地址转换为 API server 端点;之后的转发会遵循发往该端点的路由。通过外部 VIP 或负载均衡器暴露的 API 端点则遵循外部路由路径。
Pod 到外部网络
默认 VPC 逻辑路由器会使用源策略路由,选择出口节点在 join 交换机上的地址。数据包通过 ovn0 到达该节点,然后遵循主机的路由规则,经由出口 NIC 到达外部网络:
- 分布式网关:流量通过 Pod 所在的本地节点离开。
- 集中式网关:流量通过选定的网关节点离开。如果该网关位于远程节点,OVS 会通过 Geneve 将数据包传输到该节点。有关 active-backup 和 ECMP 行为,请参阅网关模式。

使用 natOutgoing: true 时,匹配的外部流量会在出口主机上进行源 NAT,具体取决于所配置的 NAT 策略。如果数据包离开出口主机时仍带有原始 Pod 源地址,则上游网络需要配置一条返回 Pod CIDR 的路由。有关网关配置,请参阅配置集中式网关。有关通过专用网关 Pod 为特定工作负载提供出口,请参阅出口网关及其与集中式网关的比较。
高可用性
在高可用部署中,ovn-central 使用 Raft 复制 northbound 和 southbound 数据库。每个数据库都需要其成员中的大多数可访问,才能提交更新。数据库可用性只是网络可用性的一部分:控制器、节点网络以及任何选定的网关也必须正常工作。
当 ovn-controller 必须在重启后重新加载网络状态时,它需要访问 southbound 数据库,然后配置本地 OVS。ovs-vswitchd 不会直接读取 southbound 数据库。节点的接口和转发规则恢复期间,连接可能会中断。
检查集群中的组件
使用为目标集群配置的 kubectl,以及拥有读取这些资源权限的账号。以下示例输出来自运行 Kube-OVN v1.16.13 的三节点测试集群。副本数、Pod 名称、节点名称、IP 地址、运行时长和事件因集群而异;请将这些示例用于理解输出,而不要将其视为必须遵循的配置值。
以下长输出已缩减为下文讨论的关键字段和代表性行。在摘录中,... 表示省略的行;运行命令会返回完整输出。
列出工作负载
示例输出:
示例输出:
将 Deployment 的 READY 列与其请求的副本数进行比较。对于每个 DaemonSet,请比较 DESIRED、CURRENT 和 READY;成功完成滚动更新后,符合条件的节点上的就绪数量应与期望数量一致。在此示例中,ovn-central 和 kube-ovn-controller 各有三个就绪副本,kube-ovn-monitor 有一个,且每个 DaemonSet 在全部三个符合条件的节点上都有一个就绪 Pod。
查找 Pod 和容器
列出 Pod,查看其实际调度位置和运行时状态:
示例输出(摘录;每个组件显示一个 Pod):
NODE 列显示每个 Pod 的运行位置。READY、STATUS 和 RESTARTS 有助于识别尚未就绪或正在重启的 Pod。ovs-ovn 的 Pod 选择器是 app=ovs;此列表中的其他组件使用其组件名称作为 app 的值。未安装的可选组件不会有匹配的 Pod;此示例集群未安装 kube-ovn-speaker。
例如,列出 OVN 和 OVS Pod 中的容器:
示例输出(摘录;每个工作负载显示一个 Pod):
对于标准部署,CONTAINERS 列会显示数据库 Pod 使用 ovn-central,OVS Pod 使用 openvswitch。NB、SB 和 ovn-northd 作为进程运行在 ovn-central 容器中;节点 OVS 数据库、ovs-vswitchd 和 ovn-controller 运行在 openvswitch 中。它们不是单独的 Kubernetes Pod 或容器。
检查滚动更新状态和事件
若要检查滚动更新详细信息和工作负载事件,请描述该工作负载。例如:
示例输出(摘录):
在此示例中,三个副本均可用,且 Available 和 Progressing 条件均为 True。
示例输出(摘录;省略重复的创建事件):
此处,期望、当前和可用节点数量均为三个,且没有 Pod 处于等待或失败状态。显示的 SuccessfulCreate 事件记录了一个 Pod 的创建。事件是临时的,因此较早创建的工作负载可能会显示 Events: <none>;请同时检查当前就绪状态和事件。
这些查询会显示部署和就绪状态。若要检查特定网络连接的行为,请参阅流量路径和相关配置指南。
资源使用量和限制
内存不足可能导致 openvswitch 容器处于 OOMKilled 状态;CPU 限流可能会延迟网络配置和数据包处理。出现这些症状时,请让集群管理员检查资源使用情况。
ACP Helm Chart 使用 ovs-ovn.requests 和 ovs-ovn.limits 设置资源。其升级模板会从现有的 ovs-ovn DaemonSet 读取 CPU 和内存值,因此管理员在更改或升级配置时,还必须核实该 DaemonSet 上实际生效的资源设置。
kubectl-ko
此 kubectl 插件可让集群管理员检查 OVN 数据库和节点 OVS 状态。它封装了 ovn-nbctl、ovn-sbctl、ovs-vsctl 和 ovs-ofctl 等命令。请使用适用于已安装 Kube-OVN 版本的插件版本,并确保拥有访问其组件所需的权限。