第271篇:云计算网络基础:虚拟交换机(OVS)

关键词:OVS、Open vSwitch、虚拟交换机、虚拟化网络、VLAN、VXLAN、流表


一、引言

在云计算环境中,虚拟机(VM)和容器需要通过网络进行通信。传统物理交换机无法直接连接运行在同一台物理服务器上的虚拟机,因此需要虚拟交换机(Virtual Switch)来实现虚拟机之间的二层连接以及虚拟机到外部网络的连接。

Open vSwitch(OVS)是目前最流行的开源虚拟交换机,被OpenStack、Kubernetes、VMware等主流云平台广泛采用。OVS不仅提供了传统交换机的基本功能,还通过OpenFlow协议实现了可编程的数据转发能力。

二、核心概念

2.1 虚拟交换机的角色

虚拟交换机与物理交换机的对比:

特性 物理交换机 虚拟交换机(OVS)
运行环境 专用硬件 宿主机操作系统内核/用户空间
端口 物理端口 虚拟端口(vNIC/Tap)
转发方式 ASIC硬件转发 软件转发/DPDK硬件卸载
可编程性 有限 高(OpenFlow流表)
管理方式 CLI/SNMP CLI/REST API/SDN控制器
扩展性 固定端口数 动态端口

2.2 OVS 架构

OVS 架构 - 图示

OVS核心组件:

组件 说明
ovs-vswitchd 核心转发守护进程,维护流表,处理数据转发
ovsdb-server 配置数据库服务,存储交换机配置
ovs-vsctl 命令行管理工具
ovs-ofctl OpenFlow流表管理工具
datapath 数据转发路径(内核模式或DPDK模式)

2.3 OVS 网桥类型

网桥类型 说明 适用场景
Internal Bridge 内部网桥,端口在同一宿主机 VM间通信
Integrated Bridge 集成网桥,连接物理网卡 VM到外部网络
Patch Port 补丁端口,连接两个网桥 网桥间互联
VLAN Bridge VLAN标记网桥 VLAN隔离

三、技术细节

2.4 OVS 流表转发

OVS基于OpenFlow流表实现数据包转发,流表由多个表项(Flow Entry)组成:

流表结构:

字段 说明
Priority 优先级,高优先级表项优先匹配
Match 匹配条件(源MAC、目的MAC、VLAN、IP、端口等)
Actions 动作(转发、丢弃、修改、输出等)
Duration 表项存活时间
Packet/Byte Count 匹配的数据包和字节统计

常用流表动作:

动作 说明 示例
OUTPUT 从指定端口输出 OUTPUT:2
DROP 丢弃报文 DROP
SET_FIELD 修改报文字段 SET_FIELD:0x0800->eth_type
PUSH_VLAN 推送VLAN标签 PUSH_VLAN;SET_FIELD:100->vlan_vid
POP_VLAN 弹出VLAN标签 POP_VLAN
NORMAL 传统交换机行为 NORMAL

3.2 OVS 与物理网络对接

OVS通过集成网桥(Integrated Bridge)与物理网络对接:

OVS 与物理网络对接 - 图示

2.6 OVS 的 DPDK 加速

DPDK(Data Plane Development Kit)是OVS的软件加速方案:

模式 转发方式 性能 CPU占用
Kernel Mode 内核网络栈 10-50万pps 高
DPDK Mode 用户空间轮询 1000万+pps 中(绑核)
HW Offload 网卡硬件卸载 线速 极低

2.6 OVS 高级功能:QoS 与 镜像

端口级限速(QoS):

OVS支持在端口级别实施流量限速,适用于多租户环境中的带宽保障:

# 1. 创建QoS策略
ovs-vsctl -- --id=@qos create qos type=linux-htb other-config:max-rate=1000000000 \
    -- --id=@port get port tap-vm1 \
    -- set port tap-vm1 qos=@qos

# 2. 创建带权重的子带宽限制
ovs-vsctl -- --id=@qos create qos type=linux-htb other-config:max-rate=5000000000 \
    -- --id=@band1 create band type=htb-direct-max other-config:max-rate=1000000000 other-config:priority=1 \
    -- --id=@band2 create band type=htb-direct-max other-config:max-rate=2000000000 other-config:priority=2 \
    -- set qos @qos bands=@band1,@band2
QoS类型 说明 适用场景
linux-htb 基于HTB令牌桶的分级限速 多级带宽保障
linux-hfsc 基于HFSC的层次化调度 复杂调度策略
simple 简单限速 单速率限制

端口镜像(SPAN):

# 创建镜像端口
ovs-vsctl add-br br-mirror
ovs-vsctl add-port br-mirror mirror-port

# 配置镜像规则
ovs-vsctl -- --id=@m create mirror name=mirror1 \
    select-all=true \
    output-port=mirror-port \
    -- set bridge br-int mirrors=@m

2.7 OVS 流表编程:高级匹配与动作

多字段组合匹配示例:

# 1. 基于VLAN+IP+端口的精确匹配
ovs-ofctl add-flow br-int \
    "priority=100,vlan_tci=0x0100,nw_src=192.168.1.0/24,nw_dst=10.0.0.0/8,tp_dst=443,\
     actions=output:3"

# 2. 并发洪泛动作(发送到多个端口)
ovs-ofctl add-flow br-int \
    "priority=50,dl_type=0x0806,\
     actions:flood"

# 3. 修改MAC地址后转发
ovs-ofctl add-flow br-int \
    "priority=80,in_port=1,dl_src=aa:bb:cc:dd:ee:01,\
     actions:set_field:11:22:33:44:55:66->dl_src,output:2"

# 4. 基于计数器的流表(用于流量统计)
ovs-ofctl add-flow br-int \
    "priority=90,in_port=2,nw_proto=6,tp_dst=80,\
     actions=counter,output:3"
高级动作 说明 典型应用
RESUBMIT 将报文重新提交到指定表 多级流表联动
GOTO 跳转到指定表继续匹配 模块化流表设计
GROUP 调用Group Table 负载均衡/广播
METER 通过Meter Table限速 端口级限速
SET_QUEUE 设置输出队列 QoS队列映射

2.8 OVS Group Table 实现负载均衡

Group Table是OVS实现高级转发的关键机制:

# 创建轮询(Group Type=select)
ovs-ofctl add-group br-int group_id=1,type=select, \
    bucket=watch_port=2,output:2; \
    bucket=watch_port=3,output:3

# 创建故障转移(Group Type=failover)
ovs-ofctl add-group br-int group_id=2,type=failover, \
    bucket=watch_port=4,output:4; \
    bucket=watch_port=5,output:5

# 流表引用Group
ovs-ofctl add-flow br-int "priority=100,nw_dst=10.0.0.1,\
    actions group:1"
Group类型 说明 应用场景
Select 从bucket中选择(支持权重/轮询) 负载均衡
Failover 按优先级选择首个存活bucket 主备切换
Indirect 所有bucket执行相同动作 广播/组播
All 发送到所有bucket 泛洪

2.9 OVS 流表管理最佳实践

最佳实践 说明 原因
流表分层设计 使用多表(multiple tables)分工 避免单表过大,提升匹配效率
优先级规划 精确匹配高优先级,泛洪低优先级 确保关键流量优先处理
表ID规划 表0:ACL过滤→表10:VLAN→表20:路由→表30:输出 清晰的流水线模型
流表版本管理 使用ovs-ofctl dump-flows定期备份 故障恢复和审计
避免流表膨胀 限制流表数量(<10000条) 防止内存溢出和匹配性能下降
使用Group替代重复规则 通过Group Table复用bucket 减少流表项数量

四、实战配置/案例分析

4.1 OVS 基础配置

# 1. 安装OVS
yum install openvswitch

# 2. 创建网桥
ovs-vsctl add-br br-int

# 3. 添加VM的虚拟端口
ovs-vsctl add-port br-int tap-vm1
ovs-vsctl add-port br-int tap-vm2

# 4. 添加物理端口(集成网桥)
ovs-vsctl add-port br-int eth0

# 5. 查看网桥配置
ovs-vsctl show

# 6. 查看流表
ovs-ofctl dump-flows br-int

4.2 OVS VLAN 配置

# 1. 创建VLAN网桥
ovs-vsctl add-br br-vlan

# 2. 添加带VLAN标签的端口
ovs-vsctl add-port br-vlan tap-vm1 tag=100
ovs-vsctl add-port br-vlan tap-vm2 tag=100
ovs-vsctl add-port br-vlan tap-vm3 tag=200

# 3. 添加Trunk端口(连接物理网络)
ovs-vsctl add-port br-vlan eth0 tag=none
# tag=none表示Trunk模式, 允许所有VLAN通过

# 4. 验证VLAN隔离
ovs-ofctl dump-flows br-vlan

4.3 OVS VXLAN 配置

# 1. 创建VXLAN端口
ovs-vsctl add-br br-vxlan
ovs-vsctl add-port br-vxlan vxlan1 \
    -- set interface vxlan1 type=vxlan \
    options:remote_ip=10.255.2.1 \
    options:key=10001

# 2. 创建内部网桥并添加VM端口
ovs-vsctl add-br br-int
ovs-vsctl add-port br-int tap-vm1

# 3. 使用Patch Port连接两个网桥
ovs-vsctl add-port br-int patch-vxlan \
    -- set interface patch-vxlan type=patch options:peer=patch-int
ovs-vsctl add-port br-vxlan patch-int \
    -- set interface patch-int type=patch options:peer=patch-vxlan

# 4. 在VXLAN网桥上配置流表(将VLAN映射到VNI)
ovs-ofctl add-flow br-vxlan \
    "priority=1,in_port=patch-int,vlan_tci=0x0100,\
     actions=set_field:10001->tun_id,output=vxlan1"

4.4 故障案例:OVS流表冲突导致VM通信中断

现象:某OpenStack环境中,两台VM无法通信,但同一网桥上的其他VM通信正常。

排查过程:

# 1. 检查OVS网桥状态
ovs-vsctl show
# 网桥和端口状态正常

# 2. 检查流表
ovs-ofctl dump-flows br-int

# 发现两条冲突的流表项:
# 表项1: priority=1, in_port=1, actions=output:2
# 表项2: priority=2, in_port=1, dl_src=aa:bb:cc:dd:ee:01, actions=drop
# 表项2优先级更高, 将VM1的流量全部丢弃

# 3. 检查流表来源
# 表项2是由安全组规则自动生成的, 但由于规则配置错误,
# 匹配条件过于宽泛, 拦截了所有VM1的出方向流量

根因:Neutron安全组规则翻译为OVS流表时,优先级配置错误。一条drop规则的优先级(2)高于正常的forward规则(1),导致VM的流量被错误丢弃。

解决: 1. 修正安全组规则,确保drop规则的优先级低于forward规则 2. 检查Neutron的OVS流表生成逻辑 3. 使用ovs-ofctl del-flows手动删除冲突流表项作为紧急恢复措施

五、总结

OVS特性 说明 应用
软件转发 基于内核/用户空间 通用场景
DPDK加速 用户空间轮询转发 高性能场景
OpenFlow 可编程流表 SDN/网络虚拟化
VLAN支持 802.1Q VLAN 多租户隔离
VXLAN支持 Overlay隧道 跨主机二层扩展
Patch Port 网桥间互联 复杂网络拓扑
Group Table 高级转发(负载均衡/故障转移) 服务高可用
QoS 端口级限速 带宽保障
端口镜像 SPAN流量复制 故障排查/安全审计
运维命令 说明
ovs-vsctl show 查看网桥拓扑
ovs-ofctl dump-flows 查看流表
ovs-appctl dpif/dump-flows 查看datapath流表
ovs-vsctl add-br 创建网桥
ovs-vsctl add-port 添加端口
ovs-ofctl add-group 添加Group条目
ovs-ofctl dump-groups 查看Group表

思考

  1. OVS的软件转发性能远低于物理交换机(ASIC),什么场景下使用OVS仍然合理?
  2. OVS的DPDK模式需要将CPU核心绑定到DPDK线程,这会带来什么管理和调度上的挑战?
  3. OVS流表的优先级机制如何影响转发行为?如果两条流表的匹配条件有重叠但优先级不同,会发生什么?
  4. OVS的Group Table如何实现负载均衡?与ECMP在网络设备中的负载均衡有何异同?
  5. OVS的多表流水线模型(multi-table pipeline)相比单表设计有什么优势?

下篇预告:第272篇:OpenStack Neutron 网络:Provider 与 Self-Service