4. TC(Traffic Control)原理:Linux TC框架、qdisc/class/filter、HTB与TBF算法
在 Kubernetes 网络拓扑排查与调度优化中,TC(Traffic Control) 是 Linux 内核流量整形与调度的核心组件。理解 TC 的框架结构、排队规则(qdisc)、分类(class)与过滤器(filter)机制,以及 HTB 与 TBF 两种经典算法,是精准追踪网络延迟、带宽限制与丢包根因的必备技能。
4.1 Linux TC 整体框架
Linux TC 工作在内核网络栈的出口(egress)与入口(ingress)方向,通过可插拔的排队规则对数据包进行调度、整形、过滤与丢弃。其核心组件包括:
- qdisc(排队规则):数据包进入网络设备前的队列管理策略,决定数据包的发送顺序与速率。
- class(类):qdisc 内部的子队列,用于实现分层流量整形。
- filter(过滤器):根据数据包特征(如 IP、端口、DSCP 标记)将流量导向指定的 class 或 qdisc。
- policer(策略器):对超出速率限制的流量执行丢弃或标记操作。
关键概念: TC 的出口方向(egress)通常挂载在设备根 qdisc 下,入口方向(ingress)则通过 mirred 动作重定向到 ifb(Intermediate Functional Block)设备进行二次整形。
4.2 qdisc、class 与 filter 的协作关系
TC 通过 qdisc → class → filter 的三层结构实现精细化的流量调度。每个网络设备至少有一个根 qdisc,根 qdisc 下可以挂载多个 class,每个 class 又可以嵌套子 qdisc。filter 则负责将数据包分类到对应的 class 中。
| 组件 | 作用 | 常见类型 | 配置示例 |
|---|---|---|---|
| qdisc | 数据包排队与调度策略 | pfifo_fast、HTB、TBF、fq_codel | tc qdisc add dev eth0 root handle 1: htb |
| class | qdisc 内部的子队列,定义带宽分配 | HTB class、CBQ class | tc class add dev eth0 parent 1: classid 1:10 htb rate 10mbit |
| filter | 根据匹配规则将流量导向指定 class | u32、bpf、flower、cgroup | tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip dport 80 0xffff flowid 1:10 |
实战提示: 在 Kubernetes 环境中,
tc filter 常与 cgroup 过滤器配合,将特定 Pod 的流量绑定到指定 class,实现 Pod 级别的带宽限制。
4.3 HTB(Hierarchical Bucket)算法
HTB 是目前最广泛使用的分层流量整形算法。它通过 令牌桶( Bucket) 机制,在多个层级之间按比例分配带宽,并支持借用(borrow)未使用的带宽。
4.3.1 HTB 核心参数
| 参数 | 含义 | 典型值 |
|---|---|---|
rate |
保证带宽(committed rate) | 10mbit、100mbit |
ceil |
最大带宽(burst 上限) | 20mbit、1gbit |
burst |
令牌桶容量,允许短时突发 | 15k、32k |
cburst |
ceil 对应的突发容量 | 15k、32k |
quantum |
每次调度发送的字节数(影响公平性) | 1500(默认) |
4.3.2 HTB 带宽借用机制
HTB 的 借用(borrow) 机制允许子类在父类带宽空闲时临时使用超出 rate 的带宽,但不超过 ceil。这一特性在 Kubernetes 多租户场景中非常实用:
- 保证带宽:每个 Pod 或命名空间获得最低保障带宽。
- 弹性借用:当集群整体带宽空闲时,活跃 Pod 可以借用更多带宽。
- 公平调度:同一层级内的多个 class 按
quantum比例分配剩余带宽。
HTB 配置示例(限制 Pod 带宽):
# 创建根 qdisc
tc qdisc add dev eth0 root handle 1: htb default 30
# 创建根类,总带宽 100mbit
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit
# 创建子类,保证 10mbit,最大 20mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 10mbit ceil 20mbit
# 创建子类,保证 30mbit,最大 50mbit
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 30mbit ceil 50mbit
# 将 Pod A 的流量(cgroup 标记)导向 class 1:10
tc filter add dev eth0 parent 1: protocol ip prio 1 cgroup match cgroup 1000 flowid 1:10
4.4 TBF( Bucket Filter)算法
TBF 是一种简单的单队列令牌桶算法,适用于对单个数据流进行严格的速率限制。与 HTB 不同,TBF 不支持分层结构,但实现更轻量、延迟更低。
4.4.1 TBF 核心参数
| 参数 | 含义 | 典型值 |
|---|---|---|
rate |
平均发送速率 | 1mbit、100mbit |
burst |
令牌桶容量,允许短时突发 | 10k、20k |
limit |
队列最大长度(字节数) | 10000、30000 |
latency |
队列中数据包的最大等待时间 | 50ms、100ms |
4.4.2 TBF 与 HTB 的对比
| 特性 | HTB | TBF |
|---|---|---|
| 分层支持 | 支持多层 class 嵌套 | 不支持,单队列 |
| 带宽借用 | 支持 borrow 机制 | 不支持 |
| 适用场景 | 多租户、多优先级流量整形 | 单流严格限速、低延迟场景 |
| CPU 开销 | 较高(需维护层级结构) | 较低(简单令牌桶) |
| 典型用途 | Pod 带宽限制、QoS 分级 | ICMP 限速、SYN 限速 |
避坑指南: 在 Kubernetes 节点上使用 TBF 时,如果
burst 设置过小,会导致 TCP 小包(如 ACK)被频繁丢弃,引发 TCP 重传和吞吐量骤降。建议 burst 至少为 2 × MTU(约 3000 字节)。
4.5 在 Kubernetes 网络拓扑排查中的应用
TC 原理在 Kubernetes 网络拓扑排查中的典型应用场景包括:
- Pod 带宽瓶颈定位:通过
tc -s qdisc show dev eth0查看丢包、超限、令牌桶空转等统计信息。 - 网络延迟根因分析:检查 HTB 子类的
overlimits计数,判断是否因带宽不足导致排队延迟。 - 多租户隔离验证:使用
tc filter show dev eth0确认 cgroup 过滤器是否正确匹配目标 Pod。 - 突发流量冲击排查:对比
burst与cburst的命中次数,判断令牌桶容量是否合理。
排查命令速查:
# 查看 eth0 的 qdisc 统计信息
tc -s qdisc show dev eth0
# 查看 eth0 的 class 统计信息
tc -s class show dev eth0
# 查看 eth0 的 filter 规则
tc filter show dev eth0
# 实时监控丢包(每秒刷新)
watch -n 1 'tc -s qdisc show dev eth0 | grep -E "dropped|overlimits|requeues"'
实战技巧: 当
overlimits 计数持续增长时,说明对应 class 的 rate 设置过低,导致大量数据包被延迟或丢弃。此时应结合 Pod 的实际流量特征,适当调高 rate 或 ceil。