基础操作:ovs-vsctl增删改查网桥/端口、ovs-ofctl查看流表、ovs-appctl调试命令

说实话,很多刚接触 OVS 的朋友,一上来就被这三个工具搞懵了。它们到底有什么区别?什么时候该用哪个?

我个人的理解很简单:ovs-vsctl 管配置,ovs-ofctl 管转发,ovs-appctl 管调试。打个比方,ovs-vsctl 是盖房子的图纸和施工队,ovs-ofctl 是房子里面的交通规则,ovs-appctl 则是物业的监控系统。今天我们就把这三大工具挨个捋一遍。

一、ovs-vsctl:网桥与端口的增删改查

这是你日常打交道最多的命令。说白了,它就是 OVS 的配置管理接口。我习惯把它当成 OVS 的「控制面板」。

1. 创建和删除网桥

创建一个网桥,其实就是创建一个虚拟交换机:

# 创建一个名为 br0 的网桥
ovs-vsctl add-br br0

# 查看所有网桥
ovs-vsctl list-br

# 删除网桥
ovs-vsctl del-br br0

嗯,这里要注意:删除网桥会同时删除它上面的所有端口。我曾经在生产环境上犯过这个错,手一抖把整个网桥删了,结果上面挂着的十几个虚拟机全断了网。所以删之前一定确认清楚。

2. 添加和移除端口

端口分两种:一种是物理端口(比如 eth0),另一种是虚拟端口(比如 veth 对)。添加方式都一样:

# 把物理网卡 eth0 添加到 br0
ovs-vsctl add-port br0 eth0

# 创建一个内部端口(类似 Linux 的虚拟网卡)
ovs-vsctl add-port br0 vport0 -- set Interface vport0 type=internal

# 查看端口列表
ovs-vsctl list-ports br0

# 查看端口的详细信息
ovs-vsctl list interface eth0

# 移除端口
ovs-vsctl del-port br0 eth0

我个人习惯在添加物理端口后,立刻用 ovs-vsctl show 看一眼整体拓扑。这个命令会把网桥、端口、状态全部列出来,非常直观。

3. 修改端口属性

有时候你需要调整端口的 VLAN 标签或者其它参数:

# 给端口设置 VLAN tag(access 模式)
ovs-vsctl set port eth0 tag=100

# 设置 trunk 端口(允许通过多个 VLAN)
ovs-vsctl set port eth0 trunks=100,200,300

# 修改端口的 MAC 地址
ovs-vsctl set interface eth0 mac="00:11:22:33:44:55"

避坑指南:我曾经在设置 VLAN 时,忘了把物理交换机端口也改成 trunk 模式,结果流量死活不通。记住,OVS 这端改了,对端设备也得同步改

二、ovs-ofctl:流表的查看与操作

如果说 ovs-vsctl 是控制面板,那 ovs-ofctl 就是 OVS 的「交通指挥中心」。它直接操作 OpenFlow 流表,决定数据包怎么走。

1. 查看流表

这是排查转发问题最常用的命令:

# 查看所有流表
ovs-ofctl dump-flows br0

# 只看某个 table(比如 table=0)
ovs-ofctl dump-flows br0 table=0

# 只看匹配特定条件的流
ovs-ofctl dump-flows br0 "in_port=1,dl_dst=00:11:22:33:44:55"

输出结果里,cookiedurationn_packetsn_bytes 这几个字段特别重要。我排查问题时,第一眼就看 n_packets——如果匹配到的包数量是 0,说明流表规则根本没命中。

2. 理解流表结构

每条流表记录长这样:

 cookie=0x0, duration=1234.567s, table=0, n_packets=100, n_bytes=12000, priority=100,ip,in_port=1 actions=output:2

拆开来看:

  • priority:优先级,数字越大越优先。默认是 0。
  • 匹配字段:比如 in_port、dl_src、dl_dst、nw_src、tp_dst 等。
  • actions:匹配后执行的动作,常见的有 output(转发)、drop(丢弃)、normal(走传统二层转发)。

你想想看,如果一条高优先级的流表匹配了所有流量,那低优先级的规则就永远没机会执行。这就是为什么有时候你加了规则却没效果——优先级被盖了。

3. 手动添加和删除流表

# 添加一条流:从端口 1 进来的包,转发到端口 2
ovs-ofctl add-flow br0 "in_port=1,actions=output:2"

# 添加带优先级的流
ovs-ofctl add-flow br0 "priority=100,ip,nw_dst=192.168.1.0/24,actions=output:3"

# 删除匹配的流
ovs-ofctl del-flows br0 "in_port=1"

# 清空所有流表(危险操作!)
ovs-ofctl del-flows br0
警告:清空流表会让 OVS 失去所有转发规则。我曾经在测试环境干过这事,结果忘了恢复,导致整个网络瘫痪了半小时。建议操作前先 ovs-ofctl dump-flows br0 > backup.txt 备份一下。

三、ovs-appctl:调试与诊断的瑞士军刀

这个工具我平时用得最多,因为它能深入到 OVS 内部去看状态。说白了,ovs-appctl 就是 OVS 的「体检中心」。

1. 查看 OVS 内部状态

# 查看所有模块的状态
ovs-appctl list-commands

# 查看网桥的详细信息(包括端口状态、连接数等)
ovs-appctl bridge/dump-info br0

# 查看 OVS 的版本和运行时间
ovs-appctl version

我个人最常用的是 bridge/dump-info,它能告诉你每个端口收发了多少包、有没有丢包、错误计数是多少。有一次客户反馈丢包严重,我一看这个输出,发现某个端口的 rx_errors 暴涨,最后定位到是网卡驱动的问题。

2. 调试 OpenFlow 连接

# 查看控制器连接状态
ovs-appctl ovsdb-server/get-db-status

# 查看 OpenFlow 连接信息
ovs-appctl ofproto/list

# 查看某个网桥的 OpenFlow 连接详情
ovs-appctl ofproto/trace br0 in_port=1,dl_dst=00:11:22:33:44:55

这里重点说一下 ofproto/trace,它是个调试神器。你可以模拟一个数据包进入 OVS,看它经过哪些流表、最终被转发到哪里。我排查「为什么这个包没到目的地」时,第一反应就是跑这个命令。

3. 内存和性能诊断

# 查看内存使用情况
ovs-appctl memory/show

# 查看线程状态
ovs-appctl list-threads

# 查看 dpdk 相关统计(如果启用了 DPDK)
ovs-appctl dpif-netdev/pmd-stats-show

嗯,这里有个小技巧:如果 OVS 性能突然下降,先跑 memory/show 看看内存有没有泄漏。我曾经遇到过一次,内存占用持续增长,最后发现是某个版本的 OVS 有内存泄漏 bug,升级后就好了。

四、三个工具的配合使用

实际工作中,这三个工具很少单独使用。我总结了一个排查流程:

  1. 先用 ovs-vsctl show 确认网桥和端口状态正常
  2. 再用 ovs-ofctl dump-flows 看流表有没有匹配到流量
  3. 最后用 ovs-appctl ofproto/trace 模拟数据包走一遍

举个例子,有一次用户说虚拟机 A 访问虚拟机 B 不通。我按这个流程走了一遍:

  • ovs-vsctl show 发现两个端口都在,状态是 UP
  • ovs-ofctl dump-flows 发现流表里有一条 drop 规则,优先级还特别高
  • ovs-appctl ofproto/trace 模拟了一下,果然被那条规则拦截了

最后发现是之前测试时加的规则忘了删。删掉后,网络就通了。

我的建议:把这三大工具的命令记熟,最好能写个脚本一键收集信息。遇到问题先跑一遍,80% 的问题都能定位到。剩下的 20%,嗯,那就得看日志和抓包了。

好了,基础操作就讲到这里。记住:ovs-vsctl 管配置,ovs-ofctl 管转发,ovs-appctl 管调试。这三个工具用熟了,OVS 对你来说就没有秘密了。