3、Linux TC与OVS QoS:TC原理简介、OVS如何利用TC实现限速
聊到OVS的QoS,绕不开Linux TC。说实话,很多刚接触SDN的朋友会觉得OVS的QoS是个黑盒子,配置完就完事了。但在我多年的运维经验里,不懂TC就去配OVS限速,出了问题你根本不知道从哪查起。
这一节,我就带你扒开OVS QoS的底层——看看它到底是怎么借助Linux TC来实现流量整形和限速的。
3.1 Linux TC是什么?
TC,全称Traffic Control,是Linux内核自带的流量控制工具。说白了,它就是内核里一个“交通警察”,负责决定数据包什么时候发、按什么顺序发、能不能发。
TC的核心组件有三个:
- qdisc(排队规则):数据包要出去,得先排队。qdisc就是管这个队的。
- class(类):把队列分成多个子队列,每个子队列可以有不同的规则。
- filter(过滤器):决定哪个数据包进哪个类。
你可以把网卡想象成一个收费站出口。qdisc就是收费站的排队通道,class是不同车型的专用道(小车、货车、ETC),filter就是收费员看你车牌把你引到对应车道。
核心要点:TC工作在出口方向(egress)和入口方向(ingress)。OVS主要利用的是出口方向的qdisc来做限速。
3.2 常用的qdisc类型
我个人在实际项目中用得最多的就三种:
| qdisc类型 | 特点 | 适用场景 |
|---|---|---|
| pfifo_fast | 默认qdisc,先入先出,三个优先级band | 普通场景,无特殊需求 |
| HTB(Hierarchical Token Bucket) | 分层令牌桶,支持带宽借用和层级结构 | 多级限速、租户隔离、带宽保证 |
| TBF(Token Bucket Filter) | 令牌桶,简单粗暴,精确限速 | 单端口固定速率限制 |
嗯,这里要注意。HTB是OVS QoS的默认选择。为什么?因为它支持分层。你想想看,一个物理网卡上可能跑着几十个虚拟机,每个虚拟机还要再细分不同的流量类型,HTB这种树形结构正好派上用场。
我的经验:曾经有个客户说OVS限速不准,我上去一看,他用的pfifo_fast。这玩意儿根本不限速,只排队。换成HTB后,问题立刻解决。
3.3 OVS如何利用TC实现限速?
OVS本身不直接操作网卡队列。它把限速任务“外包”给了Linux TC。具体流程是这样的:
- OVS创建一个内部端口(比如vnet0)
- OVS通过Netlink接口,调用TC命令在该端口上挂载qdisc
- TC根据qdisc规则,对经过该端口的数据包进行排队和丢弃
说白了,OVS只负责“告诉”TC要限多少速,具体怎么限、怎么丢包,全是TC干的活。
我们来看一个实际的例子。假设我要限制一个虚拟机网卡vnet0的出口带宽为100Mbps:
# OVS内部会执行类似这样的TC命令
tc qdisc add dev vnet0 root handle 1: htb default 30
tc class add dev vnet0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit
tc filter add dev vnet0 protocol ip parent 1:0 prio 1 u32 \
match ip dst 192.168.1.0/24 flowid 1:1
这段代码什么意思?
- 第一行:在vnet0上挂载一个HTB qdisc,根节点handle为1:
- 第二行:创建一个类1:1,保证速率和最大速率都是100Mbps
- 第三行:用u32过滤器,把去往192.168.1.0/24网段的数据包归到类1:1里
当然,OVS不会让你手动敲这些。它通过OpenFlow的QoS配置,自动帮你生成对应的TC规则。
3.4 OVS QoS与TC的映射关系
OVS里配置QoS时,你会接触到几个关键概念。它们和TC的对应关系是这样的:
| OVS概念 | 对应TC组件 | 说明 |
|---|---|---|
| QoS表项 | qdisc(根节点) | 定义限速策略类型(如linux-htb) |
| Queue队列 | class(子类) | 每个队列对应一个带宽限制 |
| Ingress Policing | ingress qdisc + filter | 入口方向的速率限制 |
我记得有一次排查一个限速不生效的问题。OVS里配了QoS,但TC规则没生成。后来发现是OVS的ovs-vswitchd进程没有权限调用TC。嗯,权限问题,老生常谈了。
避坑指南:我曾经遇到过OVS版本和内核TC不兼容的情况。OVS 2.5以下版本对HTB的支持有限,建议使用OVS 2.8及以上版本。另外,如果内核没有编译HTB模块,OVS的限速会直接失败。
3.5 查看TC规则的方法
当你配完OVS QoS后,怎么确认TC规则已经生效?用下面几条命令:
# 查看所有qdisc
tc qdisc show dev vnet0
# 查看所有class
tc class show dev vnet0
# 查看filter
tc filter show dev vnet0
# 实时监控流量
tc -s qdisc show dev vnet0
加上-s参数,能看到每个队列的发送字节数、丢包数、超限次数。这些数据对排查限速是否生效非常有用。
举个例子,如果你发现某个队列的丢包数一直在涨,但速率没达到上限,那可能是burst参数设置太小了。burst是令牌桶的突发容量,太小会导致瞬间流量被误杀。
3.6 小结
这一节我们讲了Linux TC的基本原理,以及OVS如何利用TC来实现限速。说白了,OVS的QoS就是个“翻译官”,把你的限速需求转成TC能理解的规则。
下一节,我会带你实战配置OVS的QoS,包括如何创建QoS表项、如何绑定Queue、如何验证限速效果。到时候我会用真实的抓包数据来展示限速前后的区别,敬请期待。