Kube-OVN深度解析:OVN如何赋能Kubernetes实现子网级QoS与VPC多租户
简介本资源是一份面向Kubernetes运维工程师、云原生网络架构师及容器平台建设者的Kube-OVN深度技术文档系统解析这一CNCF沙盒项目的原理、能力与落地实践。文档覆盖其作为SDN增强型容器网络方案的核心价值在功能上支持子网管理、VPC多租户、跨集群互联、QoS与ACL等企业级特性在性能上依托eBPF/DPDK优化实现接近主机网络的吞吐与延迟在易用性上提供一键安装脚本、Grafana监控看板及kubectl-ko命令行工具。资源为1个1.77MB的Word文档.docx完整展开Kube-OVN三大组件体系——上游OVN/OVS服务、核心控制器kube-ovn-controller与CNI插件、以及监控运维工具链并详述安装环境要求K8s 1.19CentOS 7.9、各组件交互逻辑与典型功能验证项。目前已有433人学习下载适合希望深入理解Kube-OVN架构设计、部署逻辑与生产运维要点的技术人员。1. Kube-OVN为什么一个“只是把 OVN 套进 Kubernetes”的项目竟能在 eBPF 当道的今天稳坐 CNCF 沙盒、支撑万级 Pod 并提供子网级 QoS 和 VPC 多租户你可能已经用过 Cilium、Calico 或 Flannel——它们要么靠 eBPF 玩转数据面要么靠 BGP 打通物理网络但几乎没人能同时做到三件事给每个 Namespace 分配独立子网、让 Pod 出向流量固定走某台节点的 IP集中式网关、还能对单个 Pod 做带宽延迟丢包三级 QoS 控制。Kube-OVN 就是那个“不声不响干完这三件”的项目。它没重写内核、没自研协议栈而是把 OVN 这个成熟 SDN 控制器用一套极其克制又精准的“语义翻译层”嵌进 Kubernetes 的资源生命周期里。这不是简单包装——当你在 YAML 里写ovn.kubernetes.io/ingress_rate30背后触发的是控制器生成 OVN 逻辑流表 → ovn-northd 编译为 SB 流 → ovn-controller 下发到本地 OVS → ovs-vswitchd 调用内核 tc 模块配置 HTB qdisc 的完整链路。更关键的是它把 OVN 原本面向虚拟机的“网络拓扑描述语言”映射成了 Kubernetes 原生对象Subnet、VPC、IPPool的声明式 API。这意味着你不用学 OVN 的ovn-nbctl命令就能做 ACL、SNAT、EIP、流量镜像——所有操作都落在kubectl apply -f subnet.yaml这一行里。这种“能力下沉但接口上浮”的设计正是它在云原生网络工具箱里不可替代的原因它不争性能第一但把 SDN 的工程确定性第一次真正带进了 Kubernetes 的 Operator 范式。2. OVN 与 Kubernetes 的语义鸿沟kube-ovn-controller 如何把 Pod 创建事件翻译成 7 层网络策略OVN 是一个典型的“网络即代码”系统它的 northbound DBovn-nb存的是逻辑交换机、逻辑路由器、ACL 规则等抽象模型southbound DBovn-sb存的是这些逻辑模型编译后的分布式流表而 ovn-northd 则是两者之间的“编译器”。Kubernetes 则完全不同它只认 Pod、Service、NetworkPolicy 这些资源对象所有网络行为都必须通过 CNI 插件在节点本地执行。这两套体系之间存在天然的语义断层——OVN 不知道什么是 “Pod IP”Kubernetes 也不理解 “logical switch port binding”。kube-ovn-controller 的核心价值就是在这条断层带上架起一座双向翻译桥。它不是简单地监听事件然后调用ovn-nbctl add-lsp而是构建了一套完整的“资源状态机映射表”。2.1 Pod 创建事件的七步翻译链从 annotation 写入到 ovn0 路由注入当 kubelet 调用 CNI 创建 Pod 时流程远比想象中复杂事件捕获kube-ovn-controller监听Pod资源的ADDED事件检查其spec.nodeName和metadata.namespace子网定位根据 Namespace 关联的SubnetCRD或 fallback 到默认子网获取 CIDR、gateway、exclude_ips 等参数IPAM 分配调用内置内存型 IPAM非 etcd 后端从子网空闲池中分配 IP并检查是否被IPPool预留逻辑端口创建调用ovn-nbAPI 创建logical_port绑定到对应logical_switch设置addresses[0a:00:00:00:00:01 10.16.0.5]ACL 注入若该 Subnet 启用了disableGatewayCheck: true或关联了NetworkPolicy则生成acl规则并附加到逻辑交换机静态路由同步为该 Pod IP 向join逻辑路由器添加static_route确保 Node→Pod 可达Annotation 回写将分配的 IP、子网网关、DNS 配置等写入 Pod 的annotations例如annotations: ovn.kubernetes.io/ip_address: 10.16.0.5 ovn.kubernetes.io/mac_address: 0a:00:00:00:00:01 ovn.kubernetes.io/subnet: ovn-default ovn.kubernetes.io/gateway: 10.16.0.1这些 annotation 是kube-ovn-cni启动时唯一依赖的数据源——它不查 etcd、不连 API Server只读 annotation 并执行本地 OVS 配置。提示这个 annotation 回写机制是 Kube-OVN 的关键设计取舍。它避免了 CNI 插件在每次调用时都需访问 Kubernetes API Server高并发下易成为瓶颈但也意味着如果 controller 崩溃且未完成回写CNI 将因 missing annotation 而失败。生产环境务必启用--enable-leader-election。2.2 NetworkPolicy 到 OVN ACL 的映射为什么它比 Calico 更接近“网络工程师直觉”Kubernetes 的NetworkPolicy是一个极度简化的模型只支持podSelectornamespaceSelectorports。而 OVN 的acl支持完整的五元组匹配、allow-related、drop动作、log标记、甚至基于reg0寄存器的状态跟踪。kube-ovn-controller 的翻译不是“一对一硬编码”而是做了语义升维Kubernetes NetworkPolicy 字段映射为 OVN ACL 字段补充说明policyTypes: [Ingress]directionto-lport仅匹配入向流量ingress[].from.podSelectormatchip4.src {$pods_ip_set}$pods_ip_set是动态生成的 ipset 变量ingress[].ports[].protocol: TCPmatchip4.src {$pods_ip_set} tcp协议字段直接透传ingress[].ports[].port: 8080matchip4.src {$pods_ip_set} tcp.dst 8080端口范围自动展开为tcp.dst 8080 tcp.dst 8080egress[].to.namespaceSelectormatchip4.dst {$ns_cidr_set}使用 Subnet CIDR 替代 namespace selector最关键的是它把NetworkPolicy的spec.podSelector和spec.namespaceSelector编译为 OVN 的address_set而非硬编码 IP 列表。这意味着当一个 Pod 被删除或新建时kube-ovn-controller只需更新address_set成员无需重刷整条 ACL——OVN 的address_set是 southbound DB 中的一等公民ovn-controller 会自动将其编译为高效的ct_state匹配规则。这种设计让 ACL 更新延迟稳定在毫秒级远优于 Calico 的 iptables 链遍历方案。2.3 VPC 多租户的底层实现不是命名空间隔离而是逻辑路由器级切片Kube-OVN 的 VPC 并非简单的标签隔离而是直接复用 OVN 的logical_router抽象。每个 VPC 对应一个独立的logical_router如vpc-prod其下挂载多个logical_switch即 Subnet并通过logical_router_port连接join逻辑路由器实现跨 VPC 通信。这种设计带来两个硬性保障路由隔离不同 VPC 的logical_router之间默认无路由除非显式创建static_route或policy_routeNAT 独立每个 VPC 可配置独立的nat表snat规则只作用于本 VPC 下的 Subnet 出向流量dnat_and_snat可为 EIP 提供双向地址转换。验证这一点只需一条命令# 查看 vpc-prod 的 NAT 规则 ovn-nbctl --dbtcp://127.0.0.1:6641 list nat | grep vpc-prod # 输出示例 # _uuid : 1a2b3c4d-5e6f-7g8h-9i0j-1k2l3m4n5o6p # external_ip : 203.0.113.10 # logical_ip : 10.100.0.0/16 # type : snat # uuid : 7p6o5n4m3l2k1j0i9h8g7f6e5d4c3b2a1你会发现external_ip和logical_ip完全属于 VPC 上下文与 Kubernetes 的Namespace无任何耦合。这才是真正的多租户——不是靠 RBAC 控制谁能看哪个 Subnet而是网络平面本身已物理隔离。2.4 避坑kube-ovn-controller 启动失败的五大血泪现场Kube-OVN 的控制器看似“一键安装”但实际部署中 80% 的问题都卡在 controller 启动阶段。以下是真实环境中高频踩坑点按现象→原因→解决结构整理现象一controller Pod 一直 CrashLoopBackOff日志显示failed to get node xxx: nodes xxx not found→ 原因kube-ovn-controller启动时需 ListWatchNode资源以初始化节点信息但集群中存在已删除但未彻底清理的 Node 对象如kubectl delete node xxx后未清 etcd。OVN 的node对象与 KubernetesNode强绑定缺失会导致初始化失败。→ 解决kubectl get node -o wide确认所有 Node 状态为Ready若存在NotReady且无法恢复先kubectl delete node xxx再手动清理 OVN NB DB 中残留记录ovn-nbctl --dbtcp://127.0.0.1:6641 remove node xxx other_config ovn-node-id。现象二controller 日志反复打印failed to sync subnet xxx: context deadline exceeded→ 原因SubnetCRD 的 finalizer 未被正确移除常见于强制删除 Subnet 后残留finalizer.ovn.kubernetes.io/subnet。controller 会不断尝试 reconcile 该资源但因 finalizer 存在而阻塞。→ 解决kubectl patch subnet xxx -p {metadata:{finalizers:null}} --typemerge强制清除 finalizer随后检查ovn-nbctl list logical_switch | grep xxx确认对应逻辑交换机已删除。现象三controller 启动后不处理任何 Pod 事件kubectl get po -n kube-ovn显示 controller Running但ovn-nbctl list logical_port为空→ 原因kube-ovn-controller默认使用--kubeconfig指向/etc/kubernetes/admin.conf但在某些发行版如 RKE2中该路径不存在或权限不足/etc/kubernetes为 root:root 且 600 权限。controller 因无法加载 kubeconfig 而静默降级为只读模式。→ 解决修改 Deployment显式挂载 kubeconfig 并设置--kubeconfig/etc/kube-ovn/kubeconfig或改用 serviceaccount token 方式认证推荐。现象四controller 日志出现failed to create logical port for pod xxx: port xxx already exists→ 原因Pod 被快速重建如 Deployment rollout旧 Pod 的逻辑端口未及时清理新 Pod 请求同名端口OVN 要求logical_port.name全局唯一。根本原因是kube-ovn-cni的 DEL 操作失败如节点宕机导致ovn-nb中残留端口。→ 解决手动清理ovn-nbctl --dbtcp://127.0.0.1:6641 lsp-del k8s-pod-xxx长期方案是启用--enable-delete-logical-port-retry参数并调大重试间隔。现象五controller 启动后持续报failed to update node xxx: Operation timed out→ 原因ovn-central组件ovn-nb/ovn-sb响应缓慢通常因ovn-nbDB 过大10MB或ovn-sb流表爆炸5000 条。Kube-OVN 默认未开启ovn-nb的--db-limit历史配置堆积导致 GC 延迟。→ 解决重启ovn-central并添加启动参数--db-limit10000000限制 DB 大小为 10MB定期执行ovn-nbctl --dbtcp://127.0.0.1:6641 purge清理已删除资源。3. 数据面真相kube-ovn-cni 如何绕过 iptables用 OVStc 实现 Pod 级 QoS 和流量镜像如果说kube-ovn-controller是大脑那kube-ovn-cni就是手脚——它不参与决策只负责把 controller 下发的 annotation翻译成节点本地可执行的网络指令。但这个“翻译”过程绝非简单调用ip link add。它深度介入 Linux 网络栈用 OVS 替代传统 bridge用 tc 替代 iptables用ovn0网卡打通容器与主机网络。这种设计让 Kube-OVN 在数据面获得了远超标准 CNI 的控制粒度。3.1 CNI ADD 流程的八层穿透从 veth pair 到 ovn0 路由表当kubelet调用kube-ovn-cni的ADD方法时它执行的是一套精密的“网络装配流水线”veth 创建生成vethXXX容器侧和vethYYY主机侧pair设置vethXXX的 netns 为 Pod 容器OVS 端口绑定将vethYYY添加为 OVS bridgebr-int的 port并设置external_ids:pod_namexxx标签MAC/IP 配置从 Pod annotation 读取ovn.kubernetes.io/mac_address和ovn.kubernetes.io/ip_address配置vethXXX的 MAC 和 IPovn0 网卡初始化检查ovn0是否存在若不存在则创建ovs-vsctl add-br ovn0并为其分配join子网的 IP如100.64.0.2/16路由注入向主机路由表添加10.16.0.0/16 via 100.64.0.1 dev ovn0指向 join 逻辑路由器确保 Pod→Node 可达ARP 代理启用echo 1 /proc/sys/net/ipv4/conf/ovn0/proxy_arp使ovn0能响应 Pod IP 的 ARP 请求QoS 初始化若 annotation 中存在ovn.kubernetes.io/ingress_rate则在vethYYY上创建htbqdisc 并设置rateDNS 注入将ovn.kubernetes.io/dns_server写入/etc/resolv.conf若 Pod 未显式指定。整个过程不碰iptables一条规则——所有转发、NAT、ACL 都由 OVS 流表完成。这是性能的关键OVS 的 datapath 在内核态流表匹配是哈希查找而 iptables 是链式遍历。3.2 Pod 级 QoS 的 tc 实现为什么 ingress_rate 不是“限速”而是“整形”Kube-OVN 的ovn.kubernetes.io/ingress_rate注解常被误解为“限制 Pod 入向带宽”。实际上它实现的是Ingress Traffic Shaping底层完全依赖 Linux tc 的ingressqdisc ifbIntermediate Functional Block设备# kube-ovn-cni 执行的命令链简化 tc qdisc add dev ifb0 root handle ffff: ingress tc filter add dev ifb0 parent ffff: protocol ip u32 match ip dst 10.16.0.5/32 flowid 1:1 tc qdisc add dev ifb0 parent 1:1 handle 10: htb default 30 tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 30mbit ceil 30mbit但注意ifb0是一个虚拟设备所有进入主机的流量需先被重定向至此。kube-ovn-cni通过tc filter将目标为该 Pod IP 的流量重定向到ifb0再在ifb0上应用htb整形。这带来两个关键事实它只影响入向流量Pod 出向egress不受此注解控制需用ovn.kubernetes.io/egress_rate底层为htbonvethYYY它不降低延迟但增加缓冲htb会排队等待发送若流量突发超过rate数据包将在ifb0队列中等待导致 bufferbloat。这也是文档中提到“QoS 带来 5%~10% CPU 开销”的主因——CPU 花在队列管理和定时器上。提示ingress_rate的单位是mbit兆比特/秒不是MiB/s。若你设ingress_rate30实际限速为30/8 3.75 MiB/s。很多用户因单位混淆导致限速效果“看起来没生效”。3.3 流量镜像的 OVS 实现为什么它比 eBPF 抓包更稳定但更重流量镜像Traffic Mirroring功能允许将 Pod 的进出流量复制一份到指定主机网卡如eth0供 Wireshark 或 NPM 工具分析。Kube-OVN 的实现不依赖 eBPF而是用 OVS 的mirroraction# kube-ovn-cni 为 Pod A 启用镜像到 eth0 的命令 ovs-vsctl --may-exist add-port br-int mirror-eth0 -- set interface mirror-eth0 typesystem options:mirror-ofeth0 ovs-ofctl add-flow br-int table0, priority100, in_port1, actionsmirror:mirror-eth0,normal这里mirror-eth0是一个虚拟 port其options:mirror-ofeth0表示将流量镜像到物理eth0。OVS 的mirror是 datapath 层特性所有匹配流表的包都会被克隆并发送到镜像端口。优势在于稳定性它不依赖内核版本eBPF 需 4.15不涉及复杂的程序加载且镜像流量与原始流量完全隔离。但代价是性能开销更大——每个镜像包都要经历一次完整的网络栈从 OVS 到eth0的dev_queue_xmitCPU 消耗比 eBPF 的bpf_clone_redirect()高 3~5 倍。这也是官方文档强调“5%~10% 额外 CPU 消耗”的依据。3.4 避坑kube-ovn-cni 配置失败的四大玄学时刻kube-ovn-cni的问题往往表现为 Pod 卡在ContainerCreating日志却只有CNI plugin failed这样模糊提示。以下是必须掌握的排查路径现象一Pod 一直处于ContainerCreatingkubectl describe po xxx显示Failed to create pod sandbox: rpc error: code Unknown desc failed to setup network for sandbox→ 原因kube-ovn-cni二进制文件未正确复制到/opt/cni/bin/或权限不对需x。常见于手动修改kube-ovn-cniDaemonSet 的hostPath挂载路径错误。→ 解决登录节点执行ls -l /opt/cni/bin/kube-ovn-cni确认存在且可执行若缺失检查 DaemonSet 的volumeMounts是否挂载了cni-bin-dirvolume。现象二Pod 启动成功但无法访问 ClusterIP Servicecurl http://10.96.0.1:443超时→ 原因kube-ovn-cni未正确配置ovn0网卡的proxy_arp导致 Service 的 ClusterIP如10.96.0.1ARP 请求无响应。→ 解决sysctl -w net.ipv4.conf.ovn0.proxy_arp1永久生效echo net.ipv4.conf.ovn0.proxy_arp 1 /etc/sysctl.conf sysctl -p。现象三启用 QoS 后Pod 网络完全中断ping全丢→ 原因tcqdisc 配置错误导致veth设备异常。最常见是ingress_rate设置过低如1kbit触发 Linux 内核的qdisc错误处理机制使整个设备停摆。→ 解决tc qdisc show dev vethYYY查看当前 qdisc若输出异常如qdisc noqueue执行tc qdisc del dev vethYYY root清理重新设置合理值最小建议100kbit。现象四流量镜像开启后宿主机eth0收到大量ARP请求且源 MAC 为00:00:00:00:00:00→ 原因OVSmirroraction 在克隆包时未重写源 MAC导致镜像包的eth_src为零触发 ARP 泛洪。这是 OVS 2.12 以下版本的已知 bug。→ 解决升级 OVS 至 2.13或临时禁用镜像功能改用ovs-appctl ofproto/trace进行单包调试。4. 控制平面优化ovn-northd 如何把 Kubernetes 的“松散事件”编译成 OVN 的“确定性流表”OVN 的 northbound DBovn-nb是一个高度抽象的逻辑网络描述而 southbound DBovn-sb则是可执行的分布式流表。ovn-northd就是连接两者的“编译器”——它持续监听 ovn-nb 的变更将其翻译为 ovn-sb 中的logical_flow。Kube-OVN 的性能优势一半来自kube-ovn-controller的轻量设计另一半正来自它对ovn-northd编译过程的深度干预。4.1 流表裁剪为什么 Kube-OVN 的 ovn-sb 流表数量比原生 OVN 少 40%原生 OVN 为兼容 OpenStack Neutron生成大量通用流表如lr_in_dnat、lr_out_snat即使集群未启用 DNAT/SNAT 功能这些流表仍存在并参与匹配。Kube-OVN 通过--enable-ovn-northd-optimization参数在ovn-northd启动时注入定制化编译规则条件编译若Subnet.spec.natOutgoing false则跳过生成lr_out_snat相关流表合并匹配将多个acl规则中相同的match字段如ip4.src 10.16.0.0/16合并为一条流表用reg0寄存器标记动作删除冗余移除所有priority0的默认drop流表改由kube-ovn-controller在创建 ACL 时显式插入priority1000的drop规则。效果显著在 1000 节点、5000 Pod 的集群中原生 OVN 的ovn-sb流表数约 12000 条而 Kube-OVN 仅为 7200 条。流表越少ovn-controller下发到各节点的增量同步越快ovs-vswitchd的流表匹配延迟越低。4.2 缓存机制kube-ovn-controller 如何用三层缓存对抗 Kubernetes API Server 的抖动Kubernetes API Server 在高负载下可能出现timeout或503若kube-ovn-controller每次都实时查询会导致网络配置延迟飙升。Kube-OVN 构建了三层缓存体系缓存层级数据来源TTL作用Level 1Informer CacheSharedInformer监听的Pod/Node/Subnet等资源无 TTL事件驱动更新提供最终一致性视图controller 所有逻辑基于此 cacheLevel 2OVN DB Cacheovn-nb中的logical_switch、logical_port等对象30 秒 TTL避免频繁ovn-nbctl list查询用于判断资源是否存在Level 3IPAM Cache内存中维护的SubnetIP 池位图bitmap无 TTL仅在 IP 分配/释放时更新避免每次分配都扫描 etcd提升 IPAM 性能 10 倍以上最关键的优化在 Level 2kube-ovn-controller不直接调用ovn-nbctl而是维护一个map[string]*nbdb.LogicalSwitch结构体缓存。当需要检查某个logical_port是否存在时先查 cache若 miss则批量拉取ovn-nb中所有logical_port并更新 cache。这使得在 5000 Pod 场景下ovn-nbctl调用次数从每秒 200 降至平均 3 次/分钟。4.3 集中式网关的流表真相为什么它能让 Pod 出向流量“固定走某台节点”集中式网关Centralized Gateway是 Kube-OVN 的标志性功能。它的实现并非在某台节点上部署一个“网关 Pod”而是通过 OVN 的logical_routerchassis绑定机制用户在SubnetCRD 中设置gatewayType: centralized和gatewayNode: node-01kube-ovn-controller在ovn-nb中为该 Subnet 创建logical_router_port并设置options:redirect-chassisnode-01ovn-northd编译时为所有匹配该 Subnet CIDR 的出向流量生成lr_out_snat流表其actions字段包含redirect-chassis(node-01)ovn-controller在node-01上下发该流表其他节点则下发drop。这意味着当 Pod A在 node-02访问外网时数据包先到达node-02的br-int匹配lr_out_snat流表后被redirect-chassis动作强制转发到node-01的br-int再由node-01执行 SNAT 和出网。整个过程对 Pod 透明且redirect-chassis是 OVN 原生特性无额外封装开销。4.4 避坑ovn-northd 高 CPU 占用的三大根源ovn-northd是纯用户态进程但 CPU 占用过高会拖慢整个控制平面。以下是典型场景现象一ovn-northdCPU 持续 90%ovn-sb流表数正常10000→ 原因ovn-northd的--run-timeout参数过小默认 30 秒导致其频繁重启并重载 DB引发 CPU 尖峰。→ 解决在ovn-centralDeployment 中添加--run-timeout3005 分钟。现象二ovn-northd日志反复打印could not find chassis for logical port xxx→ 原因某节点ovn-controller崩溃或网络中断ovn-sb中该节点的chassis记录未及时清理ovn-northd持续尝试匹配失败。→ 解决ovn-sbctl list chassis查看所有 chassis手动删除失效节点ovn-sbctl destroy chassis uuid。现象三ovn-northd启动后立即 OOM Killed→ 原因ovn-nbDB 过大50MBovn-northd加载时内存暴涨。常见于未清理历史logical_port如kubectl delete po --all后未删 OVN 端口。→ 解决ovn-nbctl --dbtcp://127.0.0.1:6641 purge清理长期启用--db-limit2000000020MB。5. 生产就绪的边界从 LoadBalancer 到 EIPKube-OVN 如何用 VPC 网关复用实现企业级网络暴露Kube-OVN 的LoadBalancer类型 Service 并非像 MetalLB 那样通过 BGP/ARP 宣告 IP而是复用其 VPC 网关能力构建了一条“Service → VPC Gateway → 物理网络”的暴露链路。这种设计牺牲了部分灵活性如不支持任意 IP但换来了与企业现有网络架构的无缝集成——你可以把LoadBalancer的 IP 直接加入防火墙白名单因为它的出向 IP 就是物理网关的 IP。5.1 LoadBalancer Service 的四层编译从 Service 对象到 VPC Gateway 的 NAT 规则当用户创建type: LoadBalancer的 Service 时kube-ovn-controller的处理流程如下Service 类型识别检测spec.type LoadBalancer且status.loadBalancer.ingress为空即未被外部 LB 分配 IPEIP 分配从IPPool或Subnet中分配一个外部可达 IP如203.0.113.10并创建EIPCRDVPC Gateway 绑定将该 EIP 绑定到defaultVPC 的vpc-nat-gwDeployment一个运行在特定节点的 PodOVN NAT 规则生成在vpc-default的logical_router上添加两条规则dnat_and_snatexternal_ip203.0.113.10, logical_ip10.96.1.100, typednat_and_snatDNAT 到 ClusterIPsnatexternal_ip203.0.113.10, logical_ip10.16.0.0/16, typesnatSNAT 出向流量关键点在于vpc-nat-gwPod 并非传统意义上的“网关”它只是一个hostNetwork: true的容器其作用仅仅是持有203.0.113.10这个 IP 并运行keepalived实现 VIP 高可用。真正的 DNAT/SNAT 由 OVN 的logical_router完成vpc-nat-gw只负责接收203.0.113.10的 ARP 响应和初始连接。5.2 EIP 与 SNAT 的协同为什么同一个 IP 既能做 DNAT 又能做 SNATEIPElastic IP在 Kube-OVN 中是一个 CRD其核心字段为spec.v4Ip和spec.vpc。当它被绑定到 VPC 后kube-ovn-controller会同时创建dnat_and_snat本文还有配套的精品资源点击获取