Linux tc qdisc的使用案例
在linux下通过tc qdisc 很容易对rt延时、丢包、带宽进行控制,这样的话方便重现各种网络问题
延时
1 | 1. give packets from eth0 a delay of 2ms |
模拟网络丢包
1 | tc qdisc add dev eth0 root netem loss 1% |
指定ip 172.31.65.30延时17ms, 测试发现181和183这两句命令顺序无所谓。恢复正常:179行命令
1 | 179 tc qdisc del dev eth0 root |
指定ip和端口延时
指定 eth0 网卡,来源 ip 是 10.0.1.1,目的端口是 3306 的访问延迟 20ms,上下浮动 2ms 100.100.146.3
1 | # 指定 eth0 网卡,来源 ip 是 10.0.1.1,目的端口是 3306 的访问延迟 20ms,上下浮动 2ms |
0 layer 代表 sport
2 layer 代表 dport
指定端口34001上,延时5ms
1 | tc qdisc add dev eth0 root handle 1: prio |
控制网卡的带宽、延时、乱序、丢包
1 | sudo tc qdisc add dev bond0 root handle 1: netem delay 10ms reorder 25% 50% loss 0.2% |
在eth0上设置一个tbf队列,网络带宽为200kbit,延迟10ms以内,超出的包会被drop掉,缓冲区为1540个字节
rate表示令牌的产生速率, sustained maximum rate
latency表示数据包在队列中的最长等待时间, packets with higher latency get dropped
burst参数表示 maximum allowed burst:
burst means the maximum amount of bytes that tokens can be available for instantaneously.
如果数据包的到达速率与令牌的产生速率一致,即200kbit,则数据不会排队,令牌也不会剩余
如果数据包的到达速率小于令牌的产生速率,则令牌会有一定的剩余。
如果后续某一会数据包的到达速率超过了令牌的产生速率,则可以一次性的消耗一定量的令牌。
burst就是用于限制这“一次性”消耗的令牌的数量的,以字节数为单位。
tbf: use the token buffer filter to manipulate traffic rates
限制10MB,排队等待超过100ms就触发丢包,只限制了出去的流量,没有限制进来的流量:
1 | tc qdisc ls dev eth0 // 查看eth0上的队列规则 |
乱序
1 | 1001 [2024-08-08 15:12:01] sudo tc qdisc add dev bond0 root handle 1: prio |
两地三中心模拟
针对不同的ip地址可以限制不同的带宽和网络延时,htb较prio多了一个带宽控制
通过htb 只限制带宽和延时
1 | //对10.0.3.228、229延时1ms,对 10.0.3.232延时30ms 两地三中心限制延时和带宽 |
通过prio 只限制延时
1 | //两地三中心限制不同的延时,htb才可以加带宽限制 |
qdisc的类别
QDisc(排队规则)是queueing discipline的简写,它是理解流量控制(traffic control)的基础。无论何时,内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的qdisc(排队规则)把数据包加入队列。然后,内核会尽可能多地从qdisc里面取出数据包,把它们交给网络适配器驱动模块。最简单的QDisc是pfifo它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。不过,它会保存网络接口一时无法处理的数据包。
一个网络接口上如果没有设置QDisc,pfifo_fast就作为缺省的QDisc。
CLASSFUL QDISC(分类QDisc),可分类的qdisc包括:
- CBQ: CBQ是Class Based Queueing(基于类别排队)的缩写。它实现了一个丰富的连接共享类别结构,既有限制(shaping)带宽的能力,也具有带宽优先级管理的能力。带宽限制是通过计算连接的空闲时间完成的。空闲时间的计算标准是数据包离队事件的频率和下层连接(数据链路层)的带宽。
- HTB: HTB是Hierarchy Token Bucket的缩写。通过在实践基础上的改进,它实现了一个丰富的连接共享类别体系。使用HTB可以很容易地保证每个类别的带宽,它也允许特定的类可以突破带宽上限,占用别的类的带宽。HTB可以通过TBF(Token Bucket Filter)实现带宽限制,也能够划分类别的优先级。
- PRIO: PRIO QDisc 不能限制带宽,因为属于不同类别的数据包是顺序离队的。使用PRIO QDisc可以很容易对流量进行优先级管理,只有属于高优先级类别的数据包全部发送完毕,才会发送属于低优先级类别的数据包。为了方便管理,需要使用iptables或者ipchains处理数据包的服务类型(Type Of Service,ToS)。
htb分类 qdisc
tbf能对流量无差别控制,htb可以进一步进行更精细的控制
针对IP、端口限速案例
1 | cat qdisc_bw.sh |
限流100MB后的实际监控效果
docker 中使用 tc
docker里无法使用的bug 可以参考 https://bugzilla.redhat.com/show_bug.cgi?id=1152231,解决方法就是升级tc版本,tc qdisc add 时加上direct_qlen参数
场景:
故障注入的docker: 10.1.1.149
10.1.1.149上会模拟各种网络故障,但是中控机到该docker的连接需要不受影响
DEVICE_NAME=eth0
1 | # 根规则,direct_qlen 1000必须加,否则在docker的虚拟网络跑不了 |
恢复网络
1 | #让网络恢复正常 |
参考资料
https://netbeez.net/blog/how-to-use-the-linux-traffic-control/
https://bootlin.com/blog/multi-queue-improvements-in-linux-kernel-ethernet-mvneta/