Open vSwitch 在 KVM 虚拟机网络中的高级应用

Open vSwitch(OVS)是一款开源的高性能虚拟交换机,广泛应用于KVM等虚拟化平台,为虚拟机提供网络连接 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园)。相比传统的Linux Bridge,OVS支持更丰富的网络功能和可编程管理接口(如OpenFlow),在云计算环境中能够实现大规模的网络自动化配置和监控 (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)。下文将详细介绍OVS在KVM虚拟机网络中的高级应用,包括网络桥接、流表与OpenFlow、隧道组网、多租户VPC模拟、安全组原理、OVS与KVM的集成、OVSDB持久化、典型拓扑分析以及性能优化策略等方面。

1. 网络桥接实现:Linux Bridge 与 OVS 对比

在虚拟化环境中,网络桥接允许虚拟机通过宿主机的虚拟交换设备互通,并可连接到外部物理网络。Linux内核提供的Linux Bridge(网桥)是传统方式,它工作在OSI二层,根据报文的目的MAC地址决定转发端口,实现与物理交换机类似的学习转发机制 (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置) (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)。OVS则是Linux Bridge的“加强版”,同样在二层实现转发,但增加了多层次(L2/L3)转发能力和丰富的扩展特性 (Open vSwitch系列——之一:从linux bridge到OvS_openvswitch br-CSDN博客) (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)。

*Linux Bridge特点: (apachecn-linux-zh/docs/master-kvm-virtual/04.md at master · apachecn/apachecn-linux-zh · GitHub)e是内核原生支持的模块,稳定可靠且部署简单 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园)。其转发逻辑基于MAC地址学习表:当收到新报文时记录源MAC和入口端口;查找目的MAC对应出口端口并转发;找不到则泛洪广播 (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)。Linux Bridge支持生成树协议(STP)、VLAN子接口等基本功能,适合小规模静态网络,维护和 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园) (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园) (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园) **OVS特点:**OVS同样作为二层交换机运行,但设计目标面向大规模多主机环境, (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园) (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园) (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园)OVS通过软件仿真实现了硬件交换 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园)LAN隔离、流量ACL控制、安全组、QoS队列、端口镜像等高级网络特性 (1.2Open vSwitch流表管理 - ChuenSan - 博客园)和控制虚拟网络流量 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园) (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)。OVS内置支持GRE、VX (OVS Vxlan一对一模式VS一对多模式_vxlan key=flow-CSDN博客) (OVS Vxlan一对一模式VS一对多模式_vxlan key=flow-CSDN博客)层网络搭建 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园)。它还兼容标准的管理接口( (ovs默认安全组流表分析 | Ian21c's Blog) (ovs默认安全组流表分析 | Ian21c's Blog)合)并可对接OpenFlow控制器,实现软件定义网络(SDN)的集中控制 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园) (Open vSwitch with Libvirt — Open vSwitch 3.5.90 documentation) (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园)。得益于不断优化,现代OVS的数据转发性能与Linux Bri (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑) (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)一筹 (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)。

**两者比较:**总体而言,Linux Bridge胜在架构简 (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)能要求极高且网络结构固定的场景 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园)。OVS则提供企业级 (DPDK — 数据平台优化技术 - 知乎专栏),支持大规模虚拟网络的自动化和多租户隔离,在云环境中应用更为广泛 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园) (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园)。例如,OVS可以通过OpenFlow下发精细的流表规则、建立GRE/VXLAN隧道实现跨主机二层网络,而这些是Linux Bridge所不具备或支持有限的。需要注意的是,OVS功能更复杂,对管理员的学习和操作提出了更高要求 (OVS与Linux Bridge的区别整理 - Jcpeng_std - 博客园);而Linux Bridge作为内核自带功能,不需要额外安装软件,在资源受限或对新技术接受度低的环境中依然有用武之地。

在KVM虚拟机网络中,如果只是简单地将VM接入宿主机网络,Linux Bridge即可胜任。但在构建对外提供服务的商业云平台时,往往需要OVS的高级特性来实现网络多样性和可编程控制。下面章节将聚焦OVS的高级用法,探讨其如何实现更复杂的虚拟网络功能。

2. 流表规则书写与 OpenFlow 管理

OVS的核心优势在于支持OpenFlow协议,允许通过流表(Flow Table)精细控制数据包转发路径 (Open vSwitch系列——之一:从linux bridge到OvS_openvswitch br-CSDN博客)。每条流表项定义了报文匹配条件和相应动作,可以实现灵活的转发策略、ACL规则、NAT处理等功能。OVS默认将用户空间的ovs-vswitchd作为OpenFlow交换机,实现流表的维护和下发 (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置) (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)。

流表基本概念:流表由若干条流规则组成,每条规则包含匹配域(如输入端口、源MAC、目的IP、协议类型等)和动作集(如转发到某端口、丢弃、修改报头等) (openvswitch流表转发原理原创 - CSDN博客)。OVS的数据面(内核模块)收到数据包时,会根据报文头字段匹配已有流表:若命中则按动作处理,未命中则上送用户空间,让ovs-vswitchd决定(通常通过OpenFlow控制器或静态配置下发新规则) (《深入浅出DPDK》——OVS中的DPDK性能加速_dpdk加速-CSDN博客)。这种设计结合了高速缓存和按需下发,既保证了内核转发性能,又赋予了控制平面极大的灵活性。

**OpenFlow管理:**在没有外部SDN控制器时,管理员可以使用ovs-ofctl工具直接对OVS流表进行查询和修改 (1.2Open vSwitch流表管理 - ChuenSan - 博客园)。常用命令包括:

例如,下面演示在名为br0的OVS桥上添加一条流表规则,将进入端口3的流量重定向输出到端口2: (1.2Open vSwitch流表管理 - ChuenSan - 博客园)

# ovs-ofctl add-flow br0 priority=100,in_port=3,actions=output:2
# ovs-ofctl dump-flows br0

上述命令添加规则后,再次dump-flows可以看到新增的流表项,其作用是“将端口3接收到的数据包从端口2输出” (1.2Open vSwitch流表管理 - ChuenSan - 博客园)。通过这种方式,管理员可以编程化地定义转发策略。例如,可以实现端口镜像(output到多个端口),基于IP段的访问控制(匹配nw_src或nw_dst)、基于TCP/UDP端口的流量过滤等复杂逻辑。

OVS还支持多张流表和流水线处理(Pipeline)。通过actions=resubmit(,<table_id>)可以将报文送入后续表继续匹配,实现分阶段处理(例如先实施安全组规则,再决定路由转发)。OpenFlow控制器(如OpenDaylight、Ryu等)可以连接OVS(通常OVS设置Controller地址),集中下发流表,实现集中式SDN管控 (Open vSwitch系列——之一:从linux bridge到OvS_openvswitch br-CSDN博客)。若未配置控制器,OVS可以工作在独立模式(standalone),通常默认行为是使用NORMAL动作执行类似传统交换机的MAC学习转发,使其在无流表时也能充当普通二层交换机使用 (apachecn-linux-zh/docs/master-kvm-virtual/04.md at master · apachecn/apachecn-linux-zh · GitHub)。

需要注意流表的优先级(priority)超时:优先级决定匹配规则的次序(数值越大优先级越高),超时包括硬超时和空闲超时,用于自动移除长期不活动的流,防止流表膨胀。合理规划流规则的匹配范围和优先级,有助于避免冲突并提升查找效率。

通过OpenFlow流表,OVS能够实现极大的网络控制灵活性。例如,可以指定不同VM流量走不同的物理路径,实现策略路由;或动态下发黑名单规则阻断恶意流量,实现精细的安全防护。这些都是传统Linux Bridge难以实现的高级功能,也正是OVS广受青睐的原因。

3. VXLAN/GRE 隧道配置与多主机通信

在单台宿主机内部,OVS桥即可让本机VM互通。但在云环境中,不同物理宿主机上的VM往往需要互联。为在三层网络上传输二层流量,OVS支持创建隧道接口(Tunnel Port),通过GRE、VXLAN等协议封装,实现跨主机通信的覆盖网络(Overlay) (OVS Vxlan一对一模式VS一对多模式_vxlan key=flow-CSDN博客)。

**隧道原理:**VXLAN和GRE都是典型的overlay隧道协议,其将二层以太网帧封装在IP包中,在底层网络(Underlay)上进行传输 (Open vSwitch 入门实践(6)VXLAN实验 | 没有理想的人不伤心) (Open vSwitch 入门实践(6)VXLAN实验 | 没有理想的人不伤心)。VXLAN使用UDP协议(默认目的端口4789)封装,并加入24位的VXLAN网络标识符(VNI),可提供高达16万的虚拟网络隔离 (Open vSwitch 入门实践(6)VXLAN实验 | 没有理想的人不伤心)(突破了VLAN只有4096个网络的限制 (Open vSwitch 入门实践(6)VXLAN实验 | 没有理想的人不伤心))。GRE则是更早的通用路由封装协议,直接在IP包上附加GRE Header实现。隧道端点称为VTEP(VXLAN Tunnel Endpoint):OVS充当软件VTEP,在发送VM流量前封装,在收到封装报文后解封,使虚拟机本身无需感知隧道存在 (Open vSwitch 入门实践(6)VXLAN实验 | 没有理想的人不伤心)。

**配置VXLAN隧道:**OVS创建VXLAN隧道有两种模式:

**VXLAN一对一示例:**假设Host1和Host2之间建立VXLAN隧道,使用VNI为42。本地主机Host1执行:

ovs-vsctl add-br br-vxlan       # 创建OVS桥
ovs-vsctl add-port br-vxlan vxlan42 -- set interface vxlan42 type=vxlan \
    options:local_ip=Host1_IP options:remote_ip=Host2_IP options:key=42

Host2上执行对应命令,将local_ipremote_ip对调。options:key用于指定VXLAN的VNI(VXLAN Network Identifier),相当于VXLAN隧道的“虚拟LAN ID”。配置完成后,可将各自宿主机上的虚拟机端口加入到br-vxlan桥,这样两台主机上的VM就通过VXLAN隧道处于同一个二层网络中。VXLAN封装报文会在Host1和Host2的IP网络中传输,解封后再交付给目标VM。 (OVS+VXLAN实现两个宿主机上的VM间的通信 - 七连长 - 博客园)

*VXLAN一对多示例:在规模更大的环境中,一对一模式需要N(N-1)/2条隧道,运维复杂度高。此时可采用*remote_ip=flow*模式,即每台主机只配置一个VXLAN端口,不指定单一远端,而是在流表中为不同目标动态设置封装目的IP (OVS Vxlan一对一模式VS一对多模式_vxlan key=flow-CSDN博客) (OVS Vxlan一对一模式VS一对多模式_vxlan key=flow-CSDN博客)。例如,为VXLAN端口添加OpenFlow规则:

通过以上规则,Host1发送给VM2的流量经OVS会封装VXLAN发往Host2;反之亦然。而OVS桥自身只需一个VXLAN接口即可,与每台远端通信时均复用该接口。一对多模式显著减少了接口数量,更适合动态大规模场景,不过需要借助控制器或预先下发流表来维护主机IP与隧道ID的映射关系。

**GRE隧道配置:**GRE的配置与VXLAN类似,只是接口类型为gre,没有VNI概念但可结合Linux的flowid或OVS的key模拟多个GRE隧道。命令示例:

ovs-vsctl add-port br-gre gre1 -- set interface gre1 type=gre \
    options:remote_ip=Host2_IP

这将在Host1上创建一个GRE隧道端口指向Host2。同理在Host2上创建指向Host1的gre端口,即可建立起GRE隧道。之后将VM端口加入各自主机的br-gre桥,VM间通信就会通过GRE封装转发。

多主机通信:无论VXLAN还是GRE,都可以让不同物理机上的VM仿佛在同一二层网络下。典型部署是每台KVM宿主机运行一个OVS网桥(如OpenStack中常称为br-int),所有VM的虚拟接口接入该网桥。OVS通过隧道端口互联各主机,实现二层转发的跨主机扩展。底层物理网络(Underlay)只需三层可达,无需了解虚拟网络的细节和租户隔离,这降低了对物理网络配置的依赖 (Open vSwitch 入门实践(6)VXLAN实验 | 没有理想的人不伤心)。VXLAN封装报文中携带了VNI,用于区分不同虚拟网络(等同不同租户的二层广播域),从而实现多租户隔离:只有相同VNI的主机才会互相转发封装流量,彼此隔离。

需要关注的是MTU和性能。VXLAN/GRE封装增加了额外头部(VXLAN约50字节),可能导致封装后的报文超过物理网络MTU而分片。通常可以将物理网络MTU适当调大(如1600字节)或在VM内部减小MTU(如1450字节)以避免分片性能损耗。另外,隧道封装增加了CPU开销,不过现代CPU和OVS优化(如大流缓存多队列并行)使其仍能满足高吞吐需求。如有更高性能需求,可考虑OVS的DPDK加速或硬件VTEP方案(后续性能优化部分讨论)。

4. VPC 网络模拟实现

**虚拟私有云(VPC)**是公有云中提供给租户的隔离网络环境,每个租户拥有独立的IP地址空间、子网、路由和安全策略。利用OVS可以在KVM环境下模拟出类似VPC的网络架构,实现多租户隔离和灵活的虚拟网络配置。

在VPC模型中,每个租户通常有多个子网(二层域),子网之间及子网到公网的流量通过虚拟路由器转发。要在单台或多台KVM主机上模拟这一点,可采用如下思路:

  • **二层隔离:**使用OVS为不同租户创建独立的二层网络。可以为每个租户建立单独的OVS网桥,或使用同一网桥配合VLAN/VXLAN进行隔离。例如,使用VXLAN VNI区分租户网络,Host上每个OVS桥为所有租户统一承载,通过VNI隔离流量 (Open vSwitch 入门实践(6)VXLAN实验 | 没有理想的人不伤心)。Linux Bridge因VLAN数量限制和缺乏VXLAN支持,无法支撑大规模租户隔离,而OVS可以提供2^24个VXLAN隔离网络,充分满足需求 (Open vSwitch 入门实践(6)VXLAN实验 | 没有理想的人不伤心)。

  • **虚拟路由器:**在每个租户内部署一个软件路由器,将其多个子网连接起来,并提供出入口。实现方式可以是在宿主机上为租户创建一个Linux网络命名空间作为路由器,用常规Linux路由+iptables做三层转发和NAT;该路由器命名空间通过veth或OVS内部端口连接到OVS桥的各个租户子网。OVS本身主要负责二层转发和封装,不直接执行IP路由,但可通过将不同子网接口加入路由器来打通三层。不同租户的路由器和网络彼此隔离,无交集。

  • **DHCP和其他服务:**可在租户命名空间中运行DHCP服务器(或中继)给VM分配IP,或者使用云平台集中组件。OVS可配合这些网络命名空间(通常OpenStack Neutron就是采用网络namespace + OVS的方式)共同完成VPC内的各种网络功能。

举一个具体的模拟案例:假设有租户A和租户B,各有两个子网,需要互相隔离。可以在每台计算节点上:

  1. 创建一个OVS集成桥br-int,启用VXLAN隧道,使所有计算节点的br-int互联(类似前述隧道配置)。
  2. 对于租户A的两个子网,分配两个VXLAN VNI,比如1001和1002;租户B的子网用VNI2001、2002。创建对应的逻辑网络时,在OVS中并不需要新建多个桥,而是使用流表或OVS的内部机制,将不同VNI的流量隔离。当VM加入网络时,Neutron等上层会为VM的接口配置一个VXLAN标识,使其发送流量打上相应VNI封装。
  3. 在网络节点(或某台宿主机)上为租户A建立一个路由器命名空间,其内部创建两个接口,分别连接到VXLAN 1001和1002所在的OVS桥(通常通过在br-int上创建两个内部端口,tag设置相应VNI,veth一端进namespace,一端留在OVS桥上)。这样路由器namespace就能收到租户A各子网的流量,并根据路由转发。租户B同理配置自己的路由器namespace。
  4. 路由器namespace再通过另一个接口接入外部网络(比如连接到br-ex外部桥),提供租户出公网功能。如果需要弹性IP(Floating IP),可以在此路由器上做DNAT,将公网IP映射到租户内VM。

上述流程就是OpenStack Neutron中OVS ML2 + DVR架构的简化说明,其本质是在OVS的overlay网络之上,叠加Linux namespace实现三层路由,从而形成完整的VPC网络。OVS负责二层/隧道,Linux负责三层路由/NAT,各司其职。这种组合可以模拟出类似AWS VPC那样,每个租户有隔离二层网络和自主管理的路由、ACL的环境。

需要强调,OVS本身也支持一定的三层功能(例如通过OpenFlow流表修改IP和MAC头,实现路由转发),但实现复杂且不易管理。因此实际方案多采用外部路由器(软件或硬件)配合。正如物理网络中不同VLAN之间通信需要三层设备一样 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑),虚拟网络里我们也引入虚拟路由器来完成子网互通和出口。这符合网络分层设计的思想,OVS聚焦于二层交换及隧道封装,而将三层转发逻辑交由更上层处理。

通过OVS的隧道、VLAN等机制,完全可以搭建起一个多租户隔离、各租户内部自由划分子网和路由的虚拟网络体系,即VPC的雏形。配合安全组(下一节讨论)等策略,还可对租户流量进行细粒度安全管控。

5. 安全组实现原理与落地方式

**安全组(Security Group)**是云环境中常用的虚拟防火墙机制,用于控制虚拟机接口的入站和出站流量,确保租户网络隔离和安全策略。OVS环境下安全组的实现可以有不同方式,主要分为基于iptables的传统方案和基于OVS流表的方案。

**传统方案(iptables):**早期在OVS中无法直接应用iptables规则,因为OVS端口不属于Linux网桥,iptables的FORWARD链对其不生效 (ovs默认安全组流表分析 | Ian21c's Blog)。OpenStack Neutron曾采用一种“混合驱动”:在每个虚拟机接口(tap设备)和OVS桥之间插入一个Linux Bridge,将安全组规则以iptables形式应用在该Linux Bridge上,实现流量过滤 (ovs默认安全组流表分析 | Ian21c's Blog)。具体来说,每个VM接口都有一对veth或Linux Bridge(如qvb、qvo设备),iptables安全组规则附加在Linux Bridge,控制进出VM的流量。这种方法功能上可行,但增加了额外的转发hop,带来性能开销和运维复杂度。

**OVS流表方案:为提升性能和简化架构,新版OpenStack引入了基于OVS原生流表的安全组实现。要求是内核和OVS版本支持连接跟踪(ConnTrack)**功能,用于实现有状态防火墙 (ovs默认安全组流表分析 | Ian21c's Blog)。OVS 2.5以后结合内核4.3+支持ConnTrack,能够在OpenFlow规则中使用状态匹配(如ct_state)和动作,从而实现类似iptables的状态ful检测 (ovs默认安全组流表分析 | Ian21c's Blog)。Neutron的OVS Agent在这种模式下,会为每个VM端口下发一组OpenFlow规则,典型做法是利用多个表分阶段检查:

  • 表0:捕获并drop不符合基本策略的流量(如反射性的无状态规则,防止IP/MAC欺骗等)。
  • 表某处(比如表[60]):应用安全组规则,允许特定IP/端口的报文,拒绝不匹配的报文 (ovs默认安全组流表分析 | Ian21c's Blog)。OVS通过ct_state来区分新建连接与已有连接,例如允许已建立和相关的流量自由通过,而对新建连接按安全组规则过滤。这和iptables的ESTABLISHED,RELATED类似。
  • 结尾用resubmitNORMAL将通过检查的流量送回主流程转发 (ovs默认安全组流表分析 | Ian21c's Blog)。

这样实现的安全组本质上是一组流表项组合成的防火墙。例如OpenStack的默认安全组规则会转化为许多条OVS流(不同表)来允许各类必要的流量,并丢弃其他流量 (ovs默认安全组流表分析 | Ian21c's Blog)。由于每个端口的规则独立,会产生较多流表项,但经过优化(如分组match、合理的表分区),性能仍可接受。在部署了数千台云主机的环境下,采用OVS流表实现安全组避免了每个接口一个Linux Bridge的开销,提高了可扩展性 (ovs默认安全组流表分析 | Ian21c's Blog)。

自定义实现:在没有OpenStack等框架时,也可以手工利用OVS的OpenFlow规则实现安全组功能。思路是在VM接入的OVS桥上添加流规则,根据源/目的IP、协议、端口等字段决定放行或丢弃。比如,禁止某VM访问TCP 22端口,可在OVS添加规则:匹配in_port=<VM_PORT>, tcp,tp_dst=22执行drop动作,同时还需添加出方向对称规则。如果要实现有状态,可以借助ct动作:对入站流量执行ct(zone=NX)跟踪,然后匹配ct_state=+trk+est放行已建立连接的数据包,匹配ct_state=+trk+new的新连接再根据安全组规则判断 (ovs默认安全组流表分析 | Ian21c's Blog)。手工配置略显复杂,但借助OVS的conntrack和多表,已经能够做到和iptables类似的过滤效果,包括防止ARP欺骗DHCP投毒等(通过匹配ARP、DHCP报文的字段)。

OVS安全组方案落地,需要注意OVS与内核的版本匹配,以及开启连接跟踪支持。一般Linux发行版自4.3内核起已默认包含必要模块。使用ovs-vsctl get Open_vSwitch . other_config:iface-types可查看是否支持internal, geneve, vxlan, gre等类型,ConnTrack支持通过ovs-appctl -t ovs-vswitchd dpif/show等命令可确认。如果环境满足,强烈建议使用OVS流表实现安全组,因为它减少了一层转发开销,规则更新也更原子可控(通过事务性ovsdb和OpenFlow协议)。

总的来说,安全组在OVS上的实现已经从“OVS+iptables”进化到“纯OVS流表”模式 (ovs默认安全组流表分析 | Ian21c's Blog)。这使OVS既充当虚拟交换机,又兼顾了端口防火墙的角色。一套精心设计的流规则即可保证租户VM只收到允许的流量,提高云网络的安全隔离。借助这种机制,我们可以为不同租户定义不同的安全策略,并在OVS中统一下发管理,充分发挥SDN的优势。

6. OVS 与 libvirt/KVM 的集成方法

将OVS应用于KVM虚拟机,需要将VM的虚拟网卡接口连接到OVS桥。Libvirt作为虚拟机管理层,默认使用Linux Bridge实现NAT网络(virbr0),但也支持桥接模式与OVS集成。自libvirt 0.9.11起已默认包含对OVS的支持 (Open vSwitch with Libvirt — Open vSwitch 3.5.90 documentation)。

手动桥接VM到OVS:通常的做法是先用ovs-vsctl创建OVS网桥(如ovs-vsctl add-br ovsbr0),然后在VM的XML配置中将接口类型改为该OVS桥。 (Open vSwitch with Libvirt — Open vSwitch 3.5.90 documentation)具体步骤:

  1. 使用ovs-vsctl在宿主机上创建OVS桥并配置上联物理网口(如需要):

    ovs-vsctl add-br ovsbr0
    ovs-vsctl add-port ovsbr0 eth0        # 将宿主机物理口接入OVS桥(可选)
    

    这样OVS桥ovsbr0就相当于原来的Linux Bridge或交换机,准备就绪。

  2. 定义或编辑虚拟机,使其网卡接口指向ovsbr0桥。在VM的libvirt域XML中,将<interface>部分修改如下: (Open vSwitch with Libvirt — Open vSwitch 3.5.90 documentation)

    <interface type='bridge'>
        <mac address='52:54:00:71:b1:b6'/>
        <source bridge='ovsbr0'/>
        <virtualport type='openvswitch'/>
        <model type='virtio'/>
    </interface>
    

    关键是将接口类型设为bridge并指定source bridge为OVS桥名,同时添加<virtualport type='openvswitch'/>以告知libvirt这是一个OVS虚拟端口。 (Open vSwitch with Libvirt — Open vSwitch 3.5.90 documentation)这样libvirt不会尝试用Linux Bridge管理该接口,而是直接连接到已有的OVS。

  3. 启动虚拟机后,其网卡(一般命名为vnet0)将被加入到ovsbr0桥中。可以通过ovs-vsctl show查看,应该能看到Port vnet0附加在Bridge ovsbr0下。这表明VM的流量将通过OVS转发。

需要注意,如果之前libvirt使用<network>定义了NAT网络(virbr0),应改为使用上述桥接配置,因为libvirt不支持对内部管理型网络使用OVS (Open vSwitch with Libvirt — Open vSwitch 3.5.90 documentation)。即OVS不能作为libvirt自管的虚拟网络,只能用在手动创建的桥接网络中。

**virsh命令方式:**除了直接编辑XML,还可以使用命令行:先定义桥接网络XML或者通过virsh attach-interface。例如:

virsh attach-interface --domain vm1 --type bridge \
    --source ovsbr0 --model virtio --virtualport type=openvswitch --persistent

这会为运行中的VM1附加一块连接到ovsbr0的网卡(–persistent保证重启仍有效)。前提是VM1的Guest OS需要配置好第二块网卡。通常最好在定义VM时就配置好接口。

通过上述集成,KVM虚拟机的网络即交由OVS来交换。这样一来,可以利用OVS的所有高级功能(隧道、OpenFlow规则、安全组等)来管理VM流量。例如,一个应用是QoS限速:OVS支持在Port上配置带宽队列,通过ovs-vsctl set interface vnet0 ingress_policing_rate=10000限制VM网卡带宽为10Mbps等,从而实现网络带宽管控,比Linux Bridge通过tc配置更直观 (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置) (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)。

Libvirt与OVS的结合,为虚拟机提供了更强大的网络能力。在OpenStack等云平台部署时,通常计算节点的虚机接口就是直接连到OVS桥(由Neutron管理),而非Linux Bridge。这种模式下,多数网络配置改由OVSDB统一管理,libvirt仅负责连接,简化了网络管理逻辑。需要注意维护时可以用常规OVS命令(ovs-vsctl等)查看和调试VM端口状态,libvirt本身对这些端口不再做额外配置。

综上,OVS与KVM集成的关键是在VM接口定义中指定OVS桥。一旦接入OVS,虚拟机网络栈就完全受控于OVS,实现比如跨主机VXLAN、OpenFlow策略、安全组等都成为可能,为构建灵活的虚拟网络奠定了基础。

7. OVSDB 数据结构与配置持久化

OVS除了转发平面,还有一个重要组件:OVS数据库(OVSDB)。OVSDB负责存储交换机的配置和状态,并保证配置的持久化保存 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)。理解OVSDB的结构和工作方式,有助于深入掌握OVS配置管理和持久化机制。

**架构组件:**OVS运行时包含三个主要部分:ovs-vswitchd(用户态守护进程,负责流表和控制逻辑)、ovsdb-server(数据库服务进程)和内核中的openvswitch模块(数据面) (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)。 (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置)上图显示了OVS架构各模块及交互关系。ovs-vswitchd通过Unix套接字与ovsdb-server通讯,从中读取配置(如网桥、端口、协议配置等),并在配置变化时写回数据库 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)。管理员使用ovs-vsctl等命令行工具时,其操作实际上由ovsdb-server执行,对应修改OVSDB中的记录 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)。内核模块通过netlink与ovs-vswitchd交互,以实现数据包上报和流表下发等。

OVSDB数据模型:OVSDB采用面向对象的表-记录结构,默认数据库文件名为ConfDB(通常保存在/etc/openvswitch/conf.db)。其中包含十多个表,用于描述OVS的各种配置项 (apachecn-linux-zh/docs/master-kvm-virtual/04.md at master · apachecn/apachecn-linux-zh · GitHub)。主要表包括:

  • Open_vSwitch:全局配置表,存放整体UUID标识,以及指向其他表的引用等。
  • Bridge:每个OVS桥对应一条记录,字段包括桥名、控制器、fail-mode、所属端口列表等。
  • Port:每个端口(无论物理、虚拟还是内部)都有记录,字段包括端口名、所属接口列表、tag(VLAN ID)等。一个Bridge下可以有多个Port。
  • Interface:端口下的接口,一般一一对应。字段包括接口名、类型(系统、internal、vxlan等)、MAC地址、MTU等配置。
  • 其他如Controller(控制器信息)、QoS(服务质量配置)、Mirror(流量镜像)、Flow_Table(静态流表)等等,用于存储各类拓展配置。

这种层次结构类似于:Bridge包含Port列表,Port包含Interface列表。通过UUID关联实现引用关系。例如,ovs-vsctl add-br br0会在Bridge表新增记录br0,同时在Port表和Interface表各新增一条br0(网桥本身也作为一个端口和接口存在)。再执行ovs-vsctl add-port br0 tap1,则Bridge表br0的ports字段增加一个指向Port表新记录tap1,该Port记录的interfaces字段指向Interface表的新记录tap1。这样OVSDB完整地描述了当前交换机的拓扑结构。

配置持久化:由于OVSDB是持续运行的数据库服务,因此通过ovs-vsctl等写入的配置更改会实时更新在内存数据库,并同步写入磁盘文件(类似检查点)。即使系统或OVS服务重启,之前配置的网桥、端口等信息仍保存在conf.db中,OVS启动时ovsdb-server会加载它,从而恢复原有配置 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)。这意味着OVS的配置是持久化的,不像纯内核的Linux Bridge那样需要额外用脚本保存/恢复 (OVS技术介绍 - 知乎专栏)。管理员不必每次重启后重新配置网桥和端口。

需要注意OVSDB与流表的区别:OVSDB存储的是网桥和端口等配置类信息(Control Plane配置),而OpenFlow流表属于转发平面状态,不在OVSDB中长期保存。当OVS关闭或重启后,流表会丢失,需要控制器或脚本重新下发。 (apachecn-linux-zh/docs/master-kvm-virtual/04.md at master · apachecn/apachecn-linux-zh · GitHub)OVSDB有一个Flow_Table表,但通常并不用于持久化一般的数据面流表(更多用于静态配置一些默认流)。因此,OVSDB的持久化主要体现在拓扑配置上,而非动态转发规则上。

OVSDB操作与接口:除了ovs-vsctl,还有ovsdb-clientovsdb-tool等可直接操作OVSDB的命令行工具 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑) (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)。OVSDB也提供远程管理接口(基于JSON-RPC的OVSDB协议) (apachecn-linux-zh/docs/master-kvm-virtual/04.md at master · apachecn/apachecn-linux-zh · GitHub)。这允许外部控制器通过TCP连接ovsdb-server,对OVS配置进行查询和更改。例如OpenStack的Neutron就通过OVSDB接口下发隧道端口配置、QoS策略等。当使用外部SDN控制器(如OVN)时,控制器可以统一管理多个OVS的配置数据库,实现多交换机集群的集中配置 (apachecn-linux-zh/docs/master-kvm-virtual/04.md at master · apachecn/apachecn-linux-zh · GitHub)。值得一提的是,OVSDB模式使OVS具备分布式交换机的能力:多台服务器上的OVS实例可以在控制器协调下共享一个逻辑配置,不需要逐台手动配置每个交换机 (apachecn-linux-zh/docs/master-kvm-virtual/04.md at master · apachecn/apachecn-linux-zh · GitHub)。

**示例:**执行ovs-vsctl show可以得到当前OVSDB的内容摘要,例如:

ovs_version: "2.15.0"
Bridge "br0"
    Port "br0"
        Interface "br0"
            type: internal
    Port "tap1"
        Interface "tap1"
            type: internal

这表示OVS版本2.15,存在一个Bridge br0,它有两个端口(br0tap1),均为internal类型接口。这些信息对应OVSDB中的记录关系。可以看到,OVSDB将网络配置清晰地结构化,这对大型部署和自动化管理非常有利。

总的来说,OVSDB提供了事务性、持久化的配置管理 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)。管理员对OVS的所有配置改动都会反映在OVSDB中,由它负责同步保存和与转发进程交互。这种设计保证了OVS配置的一致性和持久性,使OVS能够稳定运行于长期服务的生产环境中,不会因为服务重启或主机重启而遗失配置。在对接云平台时,也能方便地通过API方式批量管理OVS设备的网络状态。

8. 典型网络拓扑与案例分析

下面通过分析几个典型拓扑案例,来加深对OVS在虚拟化环境中应用的理解。

案例一:单主机多VM桥接外网。场景:一台KVM宿主机运行多台VM,希望它们共享宿主机物理网络。可以使用一个OVS桥连接宿主机物理网卡和所有VM虚拟网卡,从而形成与物理交换机相连的虚拟二层网络 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)。 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)上图展示了这种拓扑:Host1上OVS(vSwitch)连接了三台VM的虚拟端口(Port1-Port3)以及宿主机的物理接口作为上行(Port5)。这样VM之间通过OVS直接二层互通,同时外部网络进出则通过物理网卡转发 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑) (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)。对于外部交换机而言,OVS桥上的多个VM就像挂在一个交换机上的多台主机。OVS可以像普通交换机一样学习VM的MAC并转发,从而实现无差别的连接。此外,OVS还能对通过的流量施加策略,例如对某个VM端口配置VLAN Tag,则该VM的流量将被打上相应VLAN后再进入物理网络,使其逻辑上归属某个外部VLAN,这对于与现有数据中心网络集成很有用。

案例二:多主机Overlay网络互联。场景:两台宿主机Host1和Host2,上面各有若干VM,需要在二层互通且隔离于其他流量。可以在两台主机上都部署OVS,并建立VXLAN隧道相连(参考前文VXLAN配置)。每台Host的OVS上创建一个内部桥(如br-int)承载VM端口,并创建一个VXLAN类型端口指向对端Host的IP。所有VM加入br-int后,OVS会将目的MAC不在本地的流量封装VXLAN发送到远端Host对等的VXLAN端口,完成二层转发。 (《OpenvSwitch玄机解读》|〖1〗OvS数据包转发原理及命令解析总结-电子工程专辑)这样,无需依赖物理网络提供二层跨机能力,OVS自管的VXLAN网络就构建了一个overlay二层。此拓扑中,如果有第三台Host加入,也可以在每台Host的OVS配置VXLAN到其他两台,实现全互联(或使用remote_ip=flow模式由控制器动态转发)。这种Overlay方案适用于云平台的大规模多计算节点场景,也是OpenStack等系统采用的基础架构之一。其优点是租户网络完全由软件定义,物理网络只承载UDP封装流量,配置简单灵活;缺点是封装有一定性能开销,但可通过前述优化技术减轻。

案例三:东西向+南北向路由的云网络。场景:综合案例,包括租户内部VM互通(东西向流量)和对外访问(南北向流量)。拓扑可参考OpenStack Neutron经典架构:计算节点运行OVS负责东西向Overlay,网络节点运行OVS负责南北向接入。具体而言,每个计算节点有br-int (OVS)连接VM和VXLAN隧道,所有租户流量通过VXLAN送往网络节点;网络节点上OVS接收VXLAN后,与本地路由器namespace相连实现三层转发到外部br-ex,最后通过物理网卡出去。这是一种分布式-集中式结合的拓扑,OVS在其中承担了隧道交换和外网桥接两种角色。此案例展示OVS如何在云环境中同时支持多租户Overlay出口网关功能:在计算节点上OVS隔离租户流量并高效转发,在网络节点上OVS配合路由器完成南北向NAT和路由。通过合理的流表配置,可以实现例如DVR(分布式虚拟路由)——把南北向路由下沉到计算节点,从而进一步降低集中节点的瓶颈。这些都属于云平台网络的高级应用场景。

案例四:容器编排网络中的OVS。随着容器化的发展,OVS也被用于Kubernetes等环境(比如OVN-Kubernetes网络插件)。拓扑上通常是在每个节点运行一个OVS,将该节点上的容器Pods连接到OVS桥,再通过VXLAN/Geneve将各节点OVS互联,提供容器跨主机二层/三层网络。OVS的ACL能力可用来实现K8s的Network Policy,OVS的多租户隔离也用于区分不同命名空间或租户的容器网络(类似VPC)。案例表明,OVS在容器网络中同样发挥虚拟交换机作用,保证了方案的一致性。

通过以上案例分析,可以看到OVS的灵活多变:既能充当简单桥接交换机,又能构建复杂的Overlay网络,还能与路由/NAT组合形成完整虚拟网络架构。OVS的高可配置性使得架构设计者可以针对不同需求绘制出不同拓扑,满足性能、隔离和可管理性的要求。例如,在追求极致性能的NFV场景,可以结合OVS-DPDK直通加速;在多租户云中,则强调VXLAN隔离和集中管控。无论哪种拓扑,OVS都提供了统一的接口和机制来实现,不需要更换不同的软件,对运维而言极大减少了学习成本。

最后,从性能角度看,OVS通过内核快速路径和用户态缓存设计,单机转发性能已相当接近Linux Bridge (云宏大讲坛 | 两大虚拟交换机介绍:Linux Bridge和Open VSwitch_配置);跨主机场景下,引入封装可能有所损耗,但通过合理的拓扑(例如尽量本地交换、本地路由),以及OVS本身的优化(DPDK、硬件卸载等),完全能够支撑商业环境下大量租户VM的并发网络通信。下一节我们将专门讨论性能优化策略,以确保在复杂拓扑下OVS依然高效运行。

9. 性能优化策略

在大型虚拟化网络中,保证OVS的转发性能对整体系统尤为关键。本节总结一些OVS常见的性能优化策略,帮助在商用环境下提升吞吐、降低延迟。

  • **DPDK 加速数据面:**OVS从2.4版本开始支持DPDK加速,即在用户态采用DPDK库收发包,绕过内核协议栈,大幅提升转发性能 (DPDK — 数据平台优化技术 - 知乎专栏)。DPDK使用轮询模式驱动(PMD)和巨页内存,减少中断和内存拷贝开销,可将传统OVS性能提升数倍之多 (DPDK — 数据平台优化技术 - 知乎专栏)。实测表明,启用OVS-DPDK后,虚拟交换性能可接近SR-IOV直通的水平 (DPDK — 数据平台优化技术 - 知乎专栏)。优化措施包括:为DPDK线程绑定CPU和NUMA节点 (第9 章规划您的OVS-DPDK 部署)、使用vhost-user接口加速VM virtio通信、调优DPDK转发核心线程数等。在高性能NFV(网络功能虚拟化)场景,建议使用OVS-DPDK模式,以获得每秒几百万包以上的处理能力 (突破性能瓶颈,火山引擎自研vSwitch技术实践揭秘)。当然DPDK模式下OVS运行在用户态,需要占用CPU轮询,对小流量业务而言可能有些浪费资源,所以需按需取舍。

  • NIC 硬件卸载:现代高端网卡支持将OVS的部分功能卸载到硬件,比如Mellanox ConnectX系列可以通过SR-IOV VF Representor配合TCFlower,把OVS流表下发到网卡硬件转发。OVS从2.8起配合Linux内核TC实现了OVS Offload功能。启用后,热点流或大流量的转发不再经过OVS CPU处理,直接由网卡完成,从而降低CPU负载、提高吞吐。常见卸载包括:VXLAN/GENEVE封装卸载、ACL规则卸载等。这种优化需要支持的NIC和驱动,以及配置ovs-vsctl set Open_vSwitch . other_config:hw-offload=true来打开硬件卸载开关。对于流量模式稳定、数据平面负载重的云平台,硬件卸载能在保持OVS灵活性的同时接近线速性能。

  • **多队列与CPU亲和:OVS的用户态进程ovs-vswitchd默认会创建处理线程(handler)校验线程(revalidator)**来处理内核上报报文和验证流表缓存 (1.4. 网络性能优化 | Red Hat Product Documentation)。在大流量场景下,可以增加处理线程数量(使用ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-maskn-handler-threads等参数)以并行处理多队列数据,提高多核利用率。同时,应当将OVS的关键线程绑核到特定CPU,以避免与虚拟机vCPU争抢。常用做法是为ovs-vswitchdovsdb-server设置CPU亲和,比如将ovs-vswitchd主线程和PMD线程绑在一组隔离的物理核上,确保调度稳定 (1.4. 网络性能优化 | Red Hat Product Documentation)。Linux可通过systemd或taskset来实现这一点。Red Hat发行版中甚至默认对OVS服务应用了CPU亲和和线程限制优化 (1.4. 网络性能优化 | Red Hat Product Documentation),可见其重要性。

  • **调整内核和OVS参数:**一些系统参数也会影响OVS性能。如no-mlockall设置,默认OVS会锁定内存以减少分页开销,但在内存较小时可能影响其他进程,酌情可以禁用锁定 (1.4. 网络性能优化 | Red Hat Product Documentation)。再如,可以关闭不必要的包分片重组、调整NIC中断moderation等。对于VXLAN流量,如果硬件支持UDP checksum卸载,应确保开启以减少CPU计算校验和负担。OVS自身的other_config中也有一些优化开关,例如max-idle(流缓存空闲过期时间)、flow-eviction-threshold等,可根据流表命中率调优,减少频繁上报用户态的开销。一般来说,这些优化需要在了解实际流量特征的基础上调整。

  • 流表设计优化:合理规划OpenFlow流表有助于性能。具体策略包括:使用通配符(wildcard)规则减少流表项数量,让更多流量命中同一规则;避免过多使用超高优先级的细粒度规则(可能绕过内核缓存fast path);利用分级流表(mega flow cache)机制,将相似规则合并在一起缓存。 (OVS性能优化之道:代码调优的实战案例- CSDN文库)OVS对每个数据包的第一次匹配在用户态完成,随后类似报文会以mega flow形式缓存到内核,加快后续匹配。管理员应确保flow的匹配字段顺序、粒度在性能和功能间取得平衡。例如安全组实现时,可以把允许的网段和端口尽量合并成少数规则,从而缩短匹配链长度。OVS默认启用了流缓存和批处理发送,通常无需特别调整(续上)通常无需对这些机制特别干预,但设计流表时应避免使每个数据包都走慢速路径。好的流表规则应当既满足功能又考虑性能,尽量利用OVS自动缓存和合并机制来减少CPU消耗。

  • **监控与调优:**最后,持续的性能监控和调优必不可少。可以使用ovs-appctl命令查看OVS内部统计,如ovs-appctl dpif/show了解数据平面处理情况,ovs-appctl bond/show查看链路聚合状态,ovs-appctl pmd/stats-show获取DPDK轮询线程的包处理统计等。通过监控,可以及时发现瓶颈(例如某核CPU 100%、某端口丢包等),从而有针对性地调整参数。启用OVS日志中的性能日志级别,或使用系统工具(如perftop)分析OVS进程的CPU利用,也是优化的重要手段。当部署规模和复杂度提高时,定期审视OVS的流表项数量、隧道数量、CPU负载等指标,结合上述各种策略进行调优,可确保OVS始终在高效运行。

综上所述,Open vSwitch 为 KVM 虚拟机网络提供了灵活强大的功能,从基础的二层桥接到高级的隧道组网、虚拟路由、安全策略等,均可通过OVS实现。OVS与传统Linux Bridge相比更适用于大规模和多租户场景,通过OpenFlow流表和OVSDB配置实现软件定义网络的弹性和自动化。在商用环境落地时,需要根据具体需求选择合适的架构拓扑,并通过合理的配置和优化保证性能。掌握本文介绍的各项高级应用技巧,运维人员就能够搭建起面向云计算的高效虚拟网络,并充分发挥Open vSwitch的潜力。

参考资料:

  • 【1】Jcpeng_std:《OVS与Linux Bridge的区别整理》
  • 【2】Jcpeng_std:《OVS与Linux Bridge的区别整理》
  • 【3】Jcpeng_std:OVS功能示意图
  • 【4】ChuenSan:《Open vSwitch流表管理》
  • 【5】CSDN_ambzheng:《OVS Vxlan一对一模式VS一对多模式》
  • 【6】Ian21c:《ovs默认安全组流表分析》
  • 【7】OVS官方文档:《Open vSwitch with Libvirt》
  • 【8】Linux二进制:《OvS数据包转发原理及命令解析》
  • 【9】云宏Winhong:《Linux Bridge和Open VSwitch对比》
  • 【10】知乎专栏:《Open vSwitch硬件加速应用说明》