第271篇:云计算网络基础:虚拟交换机(OVS)
关键词
Open vSwitch、OVS、虚拟交换机、流表匹配、OVSDB、DPDK、OpenFlow、云网络虚拟化
一、虚拟交换机的产生
1.1 为什么需要虚拟交换机
物理数据中心 vs 虚拟化数据中心网络的区别:
物理数据中心: ┌─────────────────┐ │ 物理服务器 A │ │ App ──► NIC ──► │── Leaf 交换机 └─────────────────┘
一台物理服务器 = 一个网络节点 物理交换机提供端口隔离(VLAN)
虚拟化数据中心: | 物理服务器 ┌─────┐ ┌─────┐ ┌─────┐ └──┬──┘ └──┬──┘ └──┬──┘ ┌──┴───────┴───────┴──┐ └──────────┬──────────┘ ┌──┴──┐ | VM1 虚拟交换机(vSwitch) NIC | | VM2 ← 这就是 OVS | | VM3 | ... | ← 多台虚拟机 | | --- | --- | --- | --- | --- | --- | --- | --- |
虚拟交换机的功能: 同一台物理服务器上的 VM 互通 VM 通过物理 NIC 连接到外部网络 实现 VLAN/VXLAN/NAT/ACL 等网络功能
1.2 OVS 简介
Open vSwitch(OVS)是开源的虚拟交换机:
项目:https://www.openvswitch.org/ 语言:C(数据面) + Python(管理面) 协议:OpenFlow + OVSDB 许可证:Apache 2.0
OVS 的核心组件:
| ovs-vswitchd OpenFlow 控制面 | ← 守护进程(管理流表) |
|---|---|
| datapath(数据面) 快速转发路径 | ← 内核模块/DPDK |
| ovsdb-server 配置持久化 | ← OVSDB 数据库 |
| ovs-vsctl / ovs-ofctl 命令行配置 | ← 管理工具 |
二、OVS 基础操作
2.1 安装与基本命令
# Ubuntu 安装 OVS
apt-get install openvswitch-switch openvswitch-common
# 查看版本
ovs-vsctl --version
# 创建网桥(Bridge)
ovs-vsctl add-br br-int # 创建集成网桥
ovs-vsctl add-br br-ex # 创建外部网桥
# 查看网桥
ovs-vsctl show
Bridge br-int
Port br-int
Interface br-int
type: internal
Bridge br-ex
Port br-ex
Interface br-ex
type: internal
ovs_version: "2.17.0"
# 添加端口
# 将物理网卡 ens3 添加到 br-ex
ovs-vsctl add-port br-ex ens3
# 创建内部端口(类似虚拟网卡)
ovs-vsctl add-port br-int veth0 -- set Interface veth0 type=internal
# 查看端口
ovs-ofctl show br-int
2.2 网桥与端口概念
OVS 的逻辑模型:
Bridge br-int(集成网桥) Port tap1 ──► Interface tap1 (VM1) Port tap2 ──► Interface tap2 (VM2) Port vxlan0 ──► Interface vxlan0 Port br-int ──► Interface br-int VLAN 10: tap1 + tap3 VLAN 20: tap2
端口类型: 1. Normal(常规):物理 NIC 或 TAP 设备 2. Internal(内部):OVS 内部的虚拟网卡 3. Tunnel(隧道):VXLAN/GRE/Geneve 隧道端点 4. Patch(补丁):连接两个网桥 5. Bond(捆绑):链路聚合
三、流表(Flow Table)
3.1 OpenFlow 流表匹配
OVS 的核心机制——流表匹配转发:
流表条目(Flow Entry)格式:
匹配条件 + 优先级 + 动作
匹配条件(Match Fields):
in_port: 入端口
dl_src/dl_dst: 源/目的 MAC
dl_type: 以太网类型(0x0800=IP, 0x0806=ARP)
nw_src/nw_dst: 源/目的 IP
nw_proto: IP 协议(6=TCP, 17=UDP)
tp_src/tp_dst: TCP/UDP 端口
vlan_vid: VLAN ID
tunnel_id: VXLAN VNI
...
动作(Actions):
output: 转发到端口
drop: 丢弃
mod_vlan_vid: 修改 VLAN
set_field: 修改字段
resubmit: 重新匹配
goto_table: 跳转到下一流表
流表优先级:
数值越大,优先级越高
精确匹配 > 通配匹配
3.2 流表配置示例
# 基础流表配置
#
# 1. 查看当前流表
ovs-ofctl dump-flows br-int
# 2. 添加流表(VM1 → VM2 互通)
ovs-ofctl add-flow br-int \
"in_port=1,dl_dst=00:00:00:00:00:02,actions=output:2"
# 3. 添加 VLAN 流表
ovs-ofctl add-flow br-int \
"in_port=1,vlan_vid=10,actions=output:3"
# 4. 添加流表(匹配 IP)
ovs-ofctl add-flow br-int \
"ip,nw_src=192.168.1.0/24,nw_dst=10.0.0.0/8,actions=output:4"
# 5. 默认规则(丢弃)
ovs-ofctl add-flow br-int \
"priority=0,actions=drop"
# 6. 实际复杂场景(OpenStack Neutron 自动生成的流表)
#
# 流表 0:VLAN 标签处理
# 流表 1:MAC 学习
# 流表 2:安全组(ACL)
# 流表 3:路由
# 流表 4:输出
3.3 多级流表
OVS 支持多级流表(Pipeline),实现复杂网络逻辑:
| Table 0 分类 ingress | ──► | Table 1 VLAN 处理 | ──► | Table 2 ACL 安全策略 | ──► | Table 3 转发 output |
|---|---|---|---|---|---|---|
| │ │ │ │ | ||||||
| │ goto_table:1│ goto_table:2│ goto_table:3│ | ||||||
| ▼ ▼ ▼ ▼ |
多级流表的好处: 1. 模块化——每级负责一个功能 2. 性能——不匹配的流表快速跳过 3. 可编程——逻辑可组合
OpenStack Neutron 典型的 Pipeline: Table 0:端口分类(本地/隧道/网关) Table 1:VLAN or VXLAN 处理 Table 2:MAC 学习 / 转发 Table 3:安全组规则 Table 4:输出端口决策
四、OVS 数据面加速
4.1 内核态 vs 用户态
OVS 数据面的两种模式:
模式 1:内核态(Kernel Datapath,默认)
| 用户态 ovs-vswitchd(流表管理) | ||
|---|---|---|
| 内核态 openvswitch.ko(快速转发) ┌──────────────────────────┐ | 数据包 → 流表缓存 → 转发 缓存未命中 → 发到用户态 用户态计算 → 安装到内核 |
数据路径: 第一个包:数据包→内核→用户态ovs-vswitchd→计算流表→安装到内核→转发 后续包:数据包→内核(流表缓存命中)→直接转发 性能:~1M pps(取决于 CPU)
模式 2:DPDK(用户态,高性能)
| 用户态 ovs-vswitchd + DPDK pmd线程 ┌──────────────────────────┐ └──────────────────────────┘ | 轮询网卡(无中断) 用户态流表处理 用户态直接转发 | |
|---|---|---|
| 内核态(仅管理) |
数据路径: 所有包在用户态处理 无内核切换开销 轮询模式(无中断) 性能:10M+ pps(DPDK 优化)
4.2 DPDK 配置
# OVS + DPDK 配置
#
# 1. 配置大页内存
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
# 2. 加载 DPDK 驱动(以 Intel 82599 为例)
modprobe vfio-pci
dpdk-devbind.py -b vfio-pci 0000:02:00.0
# 3. 配置 OVS DPDK
ovs-vsctl set Open_vSwitch . other_config:dpdk-init=true
ovs-vsctl set Open_vSwitch . other_config:dpdk-lcore-mask=0x4
ovs-vsctl set Open_vSwitch . other_config:dpdk-socket-mem=1024
# 4. 重启 OVS
systemctl restart openvswitch-switch
# 5. 创建 DPDK 端口
ovs-vsctl add-port br-int dpdk0 \
-- set Interface dpdk0 type=dpdk \
-- set Interface dpdk0 options:dpdk-devargs=0000:02:00.0
# 6. 配置 PMD 线程
ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=0xF0
五、OVS 隧道封装
5.1 VXLAN/Geneve 隧道
OVS 支持多种隧道封装:
# VXLAN 隧道
ovs-vsctl add-port br-int vxlan0 \
-- set Interface vxlan0 type=vxlan \
-- set Interface vxlan0 options:remote_ip=10.1.1.2 \
-- set Interface vxlan0 options:key=10001
# Geneve 隧道(更灵活,支持更多元数据)
ovs-vsctl add-port br-int geneve0 \
-- set Interface geneve0 type=geneve \
-- set Interface geneve0 options:remote_ip=10.1.1.3 \
-- set Interface geneve0 options:key=20001
# 查看隧道
ovs-vsctl list interface vxlan0
# VXLAN 流表匹配示例
ovs-ofctl add-flow br-int \
"tun_id=10001,in_port=vxlan0,actions=output:1"
隧道相关流表:
# VXLAN 解封装 + 转发到 VM
ovs-ofctl add-flow br-int \
"tun_id=10001,dl_dst=00:00:00:00:00:01,actions=output:1"
# VM 流量封装 + 发送到隧道
ovs-ofctl add-flow br-int \
"in_port=1,dl_dst=00:00:00:00:00:02,actions=set_tunnel:10001,output:vxlan0"
5.2 OVN(Open Virtual Network)
OVN(Open Virtual Network)是 OVS 的控制面,提供云网络抽象:
OVN 架构:
| 云管理平台(OpenStack/K8s) | ||||
|---|---|---|---|---|
| Northbound DB ┌── Logical Switch ──┐ └────────────────────┘ | ← 逻辑网络抽象 Logical Router ACL / NAT / LB | |||
| ovn-northd | ← 转换逻辑→物理 | |||
| Southbound DB | ← 物理网络视图 | |||
| ┌── ovn-controller ──┐ ┌──────┐ | OVS(每个节点) | OVS |
OVN 的优势: 1. 逻辑网络抽象——租户看到交换机/路由器/防火墙 2. 分布式网关——每个节点都有网关能力 3. 自动 VXLAN/Geneve——OVN 管理隧道 4. 安全组——在 OVS 流表中实现
六、OVS 运维
6.1 常用调试命令
# 查看网桥详细信息
ovs-vsctl list bridge br-int
# 查看端口统计
ovs-ofctl dump-ports br-int
# 查看流表统计
ovs-ofctl dump-flows br-int
# 查看 Datapath 流表(内核态缓存)
ovs-dpctl dump-flows
# 跟踪数据包路径
ovs-appctl ofproto/trace br-int in_port=1,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02
# 实时日志
ovs-appctl vlog/set file:dbg
tail -f /var/log/openvswitch/ovs-vswitchd.log
6.2 性能监控
# 查看 OVS 统计信息
ovs-ofctl dump-aggregate br-int
# 查看接口统计
ovs-vsctl list interface tap1 | grep statistics
# OVS 日志级别
ovs-appctl vlog/set br_int:dbg # 开启调试日志
ovs-appctl vlog/set br_int:info # 恢复正常
# 核心指标
# 1. 流表命中率
ovs-dpctl dump-stats
Hit: 避免用户态查找
Missed: 需要用户态计算
# 2. 每秒包数
ovs-ofctl dump-ports br-int | grep pkts
七、总结
| 知识点 | 核心要点 |
|---|---|
| OVS 是什么 | 开源的虚拟交换机,支持 OpenFlow 和 OVSDB |
| 核心组件 | ovs-vswitchd(控制面)+ datapath(数据面)+ ovsdb-server |
| 流表 | 匹配条件 + 动作,决定数据包转发行为 |
| 多级流表 | 将网络逻辑分解为多个阶段(分类→VLAN→ACL→转发) |
| 数据面 | 内核态(默认)或 DPDK(高性能,用户态轮询) |
| 隧道封装 | VXLAN/Geneve/GRE,实现 Overlay 网络 |
| OVN | OVS 的控制面,提供逻辑网络抽象 |
| 加速 | DPDK + PMD 线程 + 大页内存 |
八、思考
- 为什么要使用虚拟交换机?在虚拟化环境中,物理服务器上的 VM 之间如何通信?
- OVS 的流表匹配规则如何工作?一个数据包到达 OVS 网桥时,匹配的流程是怎样的?
- 多级流表相比单级流表有什么优势?请描述一个典型的三级流表 Pipeline(分类→策略→转发)。
- OVS 内核态和 DPDK 模式的主要区别是什么?DPDK 为什么能获得更高的吞吐量?
- OVN 在 OVS 之上提供了哪些抽象?Logical Switch 和 Logical Router 与物理网络中的对应概念有何异同?
下篇预告:第272篇《OpenStack Neutron 网络:Provider 与 Self-Service》——OpenStack 的网络架构,Provider(扁平/VLAN)网络和 Self-Service(Overlay)网络的实现与选择。