Skip to content

OVN 是什么 ​

这一章没有实验,是一次收束:把前面十九章的零件拼起来,看看一个完整的虚拟网络系统长什么样。

前面十九章缺了什么 ​

你现在会的东西已经不少了:

  • 建网桥、接端口、配 VLAN
  • 写流表实现任意转发策略
  • 建 VXLAN 隧道做 Overlay
  • 用 conntrack 做有状态防火墙
  • 接外部控制器

但如果真要用这些搭一个云平台的网络,会遇到一个很现实的问题:

500 台宿主机、3000 个虚拟机、200 个租户,每个租户有自己的子网、路由器、安全组。 这些流表谁来生成?虚拟机迁移了谁来更新?

手写不可能。实验 18 的反应式控制器也不行(延迟高、缓存爆炸)。

你需要的不是一个 OpenFlow 控制器,而是一个能把"我想要什么样的网络"翻译成流表的系统。 这就是 OVN。

OVN 的核心思想:声明式 ​

对比一下两种描述方式:

text
命令式(前面十九章在做的事)
   "在 br-int 的 table 20 加一条规则:
    匹配 dl_vlan=100,dl_dst=fa:16:3e:xx,
    动作 strip_vlan,set_field:100->tun_id,output:3"

声明式(OVN 的方式)
   "有一个逻辑交换机 ls1
    上面有三个逻辑端口 vm1、vm2、vm3
    ls1 连到逻辑路由器 lr1
    vm1 的安全组允许出站、拒绝入站"

你描述网络应该是什么样,OVN 负责把它翻译成每台宿主机上的流表。 虚拟机迁移了、新宿主机加进来了,OVN 自动重新计算并下发。

架构 ​

四个组件,各司其职:

组件在哪干什么
Northbound DB中心存逻辑网络定义:逻辑交换机、路由器、端口、ACL。这是用户/云平台写入的
ovn-northd中心翻译器。把逻辑定义编译成"逻辑流表"
Southbound DB中心存逻辑流表和物理拓扑(哪个端口在哪台宿主机上)
ovn-controller每台宿主机订阅 SB DB,把逻辑流表翻译成本机的 OpenFlow 流表下发给 ovs-vswitchd

两次翻译是关键设计

第一次(northd):逻辑定义 → 逻辑流表。这一步和物理拓扑无关,全局只做一次。

第二次(ovn-controller):逻辑流表 → 物理流表。每台宿主机只关心"和我有关的部分",本地完成。

这样中心节点的计算量不随宿主机数量增长,扩展性好得多。这是纯主动式(proactive)的,运行时不需要 packet-in。

它用到了你学过的每一个特性 ​

OVN 不是另起炉灶,它就是把前面十九章的东西组合起来:

你学过的OVN 拿它做什么
OVSDB 数据模型NB/SB 数据库用的就是 OVSDB
external_ids把 OVS 端口关联到逻辑端口
patch 端口连接 br-int 和 br-ex
多级流表逻辑流水线有二十多张表
resubmit实现逻辑端口之间的跳转
VLAN tag本机内标识逻辑交换机
Geneve 隧道跨宿主机传输,用可变元数据携带逻辑端口 ID
options:key=flow一个隧道端口承载所有逻辑网络
conntrack + zone实现安全组,每个逻辑端口一个 zone
fail_mode=secure保证控制面故障时不泄露

你已经理解了 OVN 的每一块砖。

为什么 OVN 选 Geneve 而不是 VXLAN ​

实验 13 提过 Geneve 支持可变长度的元数据选项。OVN 需要在隧道头里携带:

  • 源逻辑端口 ID
  • 目的逻辑端口 ID
  • 逻辑数据路径 ID

VXLAN 的头是固定的,只有 24 位 VNI,塞不下这些。Geneve 的 TLV 选项正好合适。

逻辑流水线 ​

OVN 把转发拆成两条流水线:

text
   入口流水线(在源宿主机上执行)
   ┌─────────────────────────────────────────┐
   │ 0  端口安全(反 MAC/IP 欺骗)              │
   │ 1  ACL 前处理(送 conntrack)             │
   │ 2  ACL(安全组规则)                      │
   │ 3  ARP/ND 应答(本地代答,不广播)          │
   │ 4  逻辑交换机转发(查逻辑 MAC 表)          │
   │ 5  逻辑路由器(三层转发、NAT)             │
   │ ...                                     │
   └─────────────────────────────────────────┘
                    │ Geneve 隧道
   ┌────────────────▼────────────────────────┐
   │ 出口流水线(在目的宿主机上执行)             │
   │ 0  ACL(入站安全组)                      │
   │ 1  端口安全                              │
   │ 2  交付到逻辑端口                         │
   └─────────────────────────────────────────┘

ARP 本地代答很值得注意

传统二层网络里 ARP 是广播。OVN 知道每个逻辑端口的 IP 和 MAC,所以直接在源宿主机上构造 ARP 应答返回,广播根本不出宿主机。

几千个虚拟机的环境里,这一条就消灭了绝大部分广播流量。

看真实环境里的逻辑流表:

bash
ovn-sbctl lflow-list

会看到几百上千条,每条形如:

text
table=8 (ls_in_l2_lkup), priority=50,
  match=(eth.dst == fa:16:3e:11:22:33),
  action=(outport = "vm1"; output;)

这是一种中间语言,不是 OpenFlow。ovn-controller 会把它翻译成本机真实的 OpenFlow 规则。

常用命令 ​

bash
# 逻辑网络定义(写 NB DB)
ovn-nbctl ls-add ls1                          # 建逻辑交换机
ovn-nbctl lsp-add ls1 vm1                     # 加逻辑端口
ovn-nbctl lsp-set-addresses vm1 "fa:16:3e:00:00:01 10.0.0.11"
ovn-nbctl lr-add lr1                          # 建逻辑路由器
ovn-nbctl acl-add ls1 to-lport 1000 "ip4.src == 10.0.0.0/24" allow
ovn-nbctl show                                # 看逻辑拓扑

# 看编译结果(读 SB DB)
ovn-sbctl show                                # 物理拓扑:哪个端口在哪台机器
ovn-sbctl lflow-list                          # 逻辑流表

# 排错
ovn-trace ls1 'inport=="vm1" && eth.dst==...' # 逻辑层面的 trace
ovs-appctl ofproto/trace br-int '<流>'        # 物理层面的 trace

ovn-trace 和 ofproto/trace 是两个层面

ovn-trace 走的是逻辑流水线,告诉你"按逻辑网络定义,这个包该怎么走"。

ofproto/trace(实验 8)走的是物理流表,告诉你"这台机器上实际会怎么处理"。

排错时先用 ovn-trace 确认逻辑对不对,再用 ofproto/trace 确认翻译对不对。

谁在用 ​

平台怎么用 OVN
OpenStack Neutronovn 驱动已经是默认,取代了老的 ovs + agent 方案
ovn-kubernetesKubernetes CNI,Red Hat OpenShift 的默认网络
oVirt / RHV虚拟化平台的网络层

Antrea 是另一个 Kubernetes CNI,直接用 OVS 而不经过 OVN,自己实现控制面。

该不该用 OVN ​

该用:

  • 要做多租户虚拟网络(逻辑交换机、路由器、安全组、浮动 IP)
  • 规模在几十台宿主机以上
  • 已经在用 OpenStack 或 Kubernetes

不该用:

  • 单机或几台机器 —— 直接用 OVS 更简单
  • 只需要固定的、不常变的网络策略 —— 手写流表或脚本生成就够
  • 网络需求很特殊,OVN 的逻辑模型表达不了

OVN 引入了不小的复杂度

两个数据库、两次翻译、几十张逻辑表。排错时你可能要同时看 NB DB、SB DB、逻辑流表、物理流表四个层面。

没有多租户需求就别上 OVN。 前面十九章的东西足够解决绝大多数问题。

小结 ​

  • OVN 解决的是**"流表谁来生成、谁来维护"**,而不是"怎么转发"
  • 核心是声明式:描述逻辑网络,OVN 翻译成流表
  • 四个组件:NB DB(逻辑定义)→ northd(翻译)→ SB DB(逻辑流表)→ ovn-controller(每机翻译成 OpenFlow)
  • 两次翻译让中心节点的计算量不随宿主机数量增长,且是纯主动式
  • OVN 用到了你学过的每一个特性:OVSDB、patch、多级流表、Geneve、conntrack zone、fail_mode
  • 选 Geneve 是因为要在隧道头里携带逻辑端口 ID,VXLAN 的固定头塞不下
  • ARP 本地代答消灭了绝大部分广播
  • 排错要分层:ovn-trace 看逻辑,ofproto/trace 看物理
  • 规模不够就别上 OVN,复杂度不是免费的

第 5 部分到此结束。最后一部分是排错与实践 —— 把前面所有工具串成一套可执行的方法论。