3、OVS 基本操作:ovs-vsctl 命令详解、Bridge/Port/Interface 管理、流表基础概念
好,咱们进入正题。上一章我们把 OVS 装上了,现在该动动手了。说实话,OVS 最常用的工具就是 ovs-vsctl,我几乎每天都要敲它几十遍。你把它想象成 OVS 的「遥控器」就行——所有对交换机、端口、隧道的配置,都靠它来下发。
3.1 ovs-vsctl 命令详解
ovs-vsctl 是 OVS 的管理工具,专门用来操作 ovsdb(OVS 的数据库)。说白了,你敲的每一条命令,最终都会写到数据库里,然后 OVS 的守护进程 ovs-vswitchd 会读取这些配置并生效。
我个人习惯把常用命令分成三类:查询类、增删改类、调试类。咱们一个个看。
3.1.1 查询类命令
刚接手一个环境,第一件事就是看当前有什么。我最常用的就是:
# 查看所有 Bridge(网桥)
ovs-vsctl list-br
# 查看某个 Bridge 上的所有 Port(端口)
ovs-vsctl list-ports br0
# 查看某个 Port 对应的 Interface(接口)详细信息
ovs-vsctl list interface veth0
# 查看整个 OVS 的配置概览
ovs-vsctl show
这里有个小细节:ovs-vsctl show 输出的是树形结构,一眼就能看清 Bridge、Port、Interface 的层级关系。我在项目里排查问题时,第一件事就是跑 show,看看拓扑对不对。
3.1.2 增删改类命令
创建和删除是日常操作。举个例子:
# 创建一个名为 br0 的 Bridge
ovs-vsctl add-br br0
# 给 br0 添加一个物理端口 eth0
ovs-vsctl add-port br0 eth0
# 删除一个端口
ovs-vsctl del-port br0 eth0
# 删除整个 Bridge(会连带删除所有端口)
ovs-vsctl del-br br0
嗯,这里要注意:add-port 的时候,如果这个端口已经被别的 Bridge 占用了,OVS 会报错。我曾经在测试环境里犯过这个错,折腾了半天才发现 eth0 已经被另一个 Bridge 绑定了。
3.1.3 调试类命令
有时候配置完了,发现流量不通。这时候我会用:
# 查看某个 Interface 的统计信息(收发包、丢包等)
ovs-vsctl list interface eth0
# 查看 Bridge 的流表统计
ovs-ofctl dump-flows br0
# 查看 OVS 的日志(定位问题利器)
tail -f /var/log/openvswitch/ovs-vswitchd.log
你想想看,如果流量不通,先看 Interface 的统计里有没有收到包,再看流表有没有命中。这两步走完,80% 的问题都能定位到。
3.2 Bridge / Port / Interface 管理
这三个概念是 OVS 的基石。我简单解释一下:
- Bridge:就是虚拟交换机。你可以创建多个 Bridge,每个 Bridge 独立工作。
- Port:Bridge 上的端口。一个 Port 可以对应一个物理网卡、一个虚拟网卡、或者一个隧道。
- Interface:Port 底层的实际接口。一个 Port 通常对应一个 Interface,但像 Bond 口(链路聚合)就是一个 Port 对应多个 Interface。
看个实际例子:
# 创建一个 Bridge
ovs-vsctl add-br br-int
# 添加一个内部端口(类似 Linux 的虚拟网卡)
ovs-vsctl add-port br-int vxlan0 -- set interface vxlan0 type=vxlan options:remote_ip=192.168.1.100
# 查看结构
ovs-vsctl show
输出大概长这样:
Bridge br-int
Port br-int
Interface br-int
type: internal
Port vxlan0
Interface vxlan0
type: vxlan
options: {remote_ip="192.168.1.100"}
看到了吗?br-int 这个 Bridge 有两个 Port:一个是它自己(内部端口),另一个是 VXLAN 隧道端口。每个 Port 下面挂着一个 Interface。
3.3 流表基础概念
流表是 OVS 的灵魂。没有流表,OVS 就是一个普通的 Linux Bridge。有了流表,它才能做 OpenFlow 交换机该做的事。
流表说白了就是一张规则表。每条规则包含两部分:匹配条件 和 动作。当数据包进入 OVS 时,它会从上到下匹配流表,找到第一条匹配的规则,然后执行对应的动作。
3.3.1 流表的结构
一条流表规则长这样:
# 匹配源 MAC 为 aa:bb:cc:dd:ee:ff 的数据包,转发到端口 1
ovs-ofctl add-flow br0 "dl_src=aa:bb:cc:dd:ee:ff, actions=output:1"
这里 dl_src 是匹配条件,output:1 是动作。你可以匹配的东西很多:MAC 地址、IP 地址、端口号、VLAN ID、隧道 ID 等等。
3.3.2 常用匹配条件
| 匹配字段 | 含义 | 示例 |
|---|---|---|
in_port |
入端口 | in_port=1 |
dl_src |
源 MAC | dl_src=00:11:22:33:44:55 |
dl_dst |
目的 MAC | dl_dst=ff:ff:ff:ff:ff:ff |
nw_src |
源 IP | nw_src=10.0.0.1 |
nw_dst |
目的 IP | nw_dst=10.0.0.0/24 |
tcp_src |
TCP 源端口 | tcp_src=80 |
tun_id |
隧道 ID(VNI) | tun_id=100 |
3.3.3 常用动作
| 动作 | 含义 | 示例 |
|---|---|---|
output:port |
转发到指定端口 | output:1 |
normal |
走传统二层交换(类似普通交换机) | actions=normal |
drop |
丢弃数据包 | actions=drop |
mod_dl_src |
修改源 MAC | mod_dl_src=00:11:22:33:44:55 |
mod_nw_src |
修改源 IP | mod_nw_src=10.0.0.2 |
set_tunnel |
设置隧道 ID | set_tunnel:100 |
3.3.4 流表优先级
流表是有优先级的。数值越大,优先级越高。默认是 0。我建议你给关键规则设置高优先级,避免被低优先级规则误匹配。
# 高优先级规则(匹配特定流量)
ovs-ofctl add-flow br0 "priority=100, dl_src=00:11:22:33:44:55, actions=output:2"
# 低优先级规则(默认转发)
ovs-ofctl add-flow br0 "priority=0, actions=normal"
actions=normal 让它走传统交换,要么自己写完整的流表规则。我第一次用 OVS 时就踩了这个坑——配完 Bridge 发现 ping 不通,查了半天才发现没加默认规则。
3.4 实战小练习
光说不练假把式。咱们来个小实验:
# 1. 创建 Bridge
ovs-vsctl add-br br-demo
# 2. 添加两个内部端口(模拟两台虚拟机)
ovs-vsctl add-port br-demo vm1 -- set interface vm1 type=internal
ovs-vsctl add-port br-demo vm2 -- set interface vm2 type=internal
# 3. 给内部端口配 IP
ip addr add 10.0.0.1/24 dev vm1
ip addr add 10.0.0.2/24 dev vm2
ip link set vm1 up
ip link set vm2 up
# 4. 添加流表:让 vm1 和 vm2 可以互通
ovs-ofctl add-flow br-demo "in_port=1, actions=output:2"
ovs-ofctl add-flow br-demo "in_port=2, actions=output:1"
# 5. 测试
ping -c 3 10.0.0.2 -I vm1
如果 ping 通了,恭喜你,你已经掌握了 OVS 的基本操作。如果没通,检查一下流表有没有生效:
ovs-ofctl dump-flows br-demo
嗯,到这里,OVS 的基本操作就讲完了。下一章咱们会深入 GRE 和 Geneve 隧道,到时候这些基础操作都会用上。你先把这些命令敲熟,后面就轻松了。