Linux流量控制-TC框架
TC(Traffic Control)是Linux操作系统中的流量控制器,用于Linux内核的流量控制。它通过在输出端口处建立一个队列来实现流量控制,可以限速、整形和策略控制网络流量的带宽、延迟、丢包等参数,从而实现网络流量的优化和管理
TC是Linux自带的模块,一般情况下不需要另行安装,可以用 man tc 查看tc 相关命令细节,tc 要求内核 2.4.18 以上
Linux中的QoS分为入口(Ingress)部分和出口(Egress)部分,入口部分主要用于进行入口流量限速(policing),出口部分主要用于队列调度(queuingscheduling)。大多数排队规则(qdisc)都是用于输出方向的,输入方向只有一个排队规则,即ingressqdisc。ingressqdisc本身的功能很有限,输入方向只有一个排队规则,即ingressqdisc(因为没有缓存只能实现流量的drop)但可用于重定向incomingpackets。通过Ingressqdisc把输入方向的数据包重定向到虚拟设备ifb,而ifb的输出方向可以配置多种qdisc,就可以达到对输入方向的流量做队列调度的目的。
即:
- 我们能控制出方向,通过 Shaping 将出的流量控制成我们自己想要的模样。如 QOS(Quality of Service)
- 至于入方向, 我们无法控制,只能通过 Policy 将包丢弃。
Ingress 限速只能对整个网卡入流量限速,无队列之分
|
|
而对于 Egress 利用队列规定建立处理数据包的队列,并定义队列中的数据包被发送的方式,从而实现对流量的控制。TC 模块实现流量控制功能使用的队列规定分为两类,一类是无类队列规定,另一类是分类队列规定。无类队列规定相对简单,而分类队列规定则引出了分类和过滤器等概念,使其流量控制功能增强。
TC 规则
流量控制包括以下的几种方式。
流量控制方式
Shaping(限制):当流量被限制时,它的传输速率就被控制在某个值之下,限制值可以远远小于有效带宽,这样可以平滑掉突发的数据流量,使得网络更为稳定。
SCHEDULING(调度):通过调度数据包的传输,可以在带宽范围内,按照优先级分配带宽,SCHEDULING(调度)也只适用于 Egress 流量。
POLICING(策略):SHAPPING 用于处理外向的流量,而 POLICING(策略)处于接收到数据
DROPPING(丢弃):如果流量超过某个设定的带宽,就丢弃数据包,不管是向内还是向外
流量控制处理的对象
- qdisc(排队规则):流量控制(traffic control)的基础。无论何时,内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的qdisc(排队规则)把数据包加入队列。然后,内核会尽可能多地从qdisc里面取出数据包,把它们交给网络适配器驱动模块。最简单的QDisc是pfifo它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。不过,它会保存网络接口一时无法处理的数据包。下面会
- class(类别):某些QDisc(排队规则)可以包含一些类别,不同的类别中可以包含更深入的QDisc(排队规则),通过这些细分的QDisc还可以为进入的队列的数据包排队。通过设置各种类别数据包的离队次序,QDisc可以为设置网络数据流量的优先级。
- filter(过滤器):决定它们按照何种QDisc进入队列。无论何时数据包进入一个划分子类的类别中,都需要进行分类。分类的方法可以有多种,使用fileter(过滤器)就是其中之一。使用filter(过滤器)分类时,内核会调用附属于这个类(class)的所有过滤器,直到返回一个判决。如果没有判决返回,就作进一步的处理,而处理方式和QDISC有关。需要注意的是,filter(过滤器)是在QDisc内部,它们不能作为主体。
TC 命令
tc 命令使用以下
|
|
控制网络的 QoS 的方式
在 Linux 下,可以通过 TC 控制网络的 QoS,主要就是通过队列的方式。
无类别排队规则
无类别排队规则(Classless Queuing Disciplines) ,这是一种把不同的网络包分类的技术。
pfifo_fast
pfifo_fast 是三个先入先出的队列,根据网络报的 TOS ,看到这个包到底应该进入哪个队列,TOS 有 4 位组成,
0 - F 其实就是 0x00 - 0xFF , 表示不同的 TOS 进入哪种队列
|
|
- 扩展知识 qdisc
qdisc 全称是 queuing discipline,中文叫 排队规则。如果需要通过某个网络接口发送数据包,他都需要为这个接口配置 qdisc(排队规则)把数据包加入队列。
最简单的 qdisc 是 pfifo,他不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。pfifo_fast 稍微复杂一点。它的队列包括三个波段(band),在每个波段里面,使用先进先出的规则。
(如下,执行 ip a
命令可以看到 ens33 有个 qdisc pfifo_fast )
|
|
三个波段(band)的优先级也不相同,band 0 优先级最高。band 2 优先级最低。
数据包是按照服务类型(Type of Service, TOS) 分配到三个波段 (band)中的。TOS 是 IP 头里面的一个字段的,代表了当前的包是最高优先级还是最低优先级的。
随机公平队列(SFQ,Stochastic Fair Queuing)
会建立很多的 FIFO 队列, TCP Session 会计算 hash 值,通过 hash 值分配到某个队列,在队列的另一端,网络报会通过轮询的策略从各个队列取出发送。
令牌桶规则(TBF, Token Bucket Filte)
所有的网络报排成队列进行发送 ,但不是到了队头才能发送,而是必须拿到 令牌才可以发送,所以 TBF 可以用来进行限速。
基于类别的队列规则
基于类别的队列规则(Classful Queuing Disciplines) , 其中典型的为 分层令牌桶(HTB, Hierarchical Token Bucket)。
HTB 往往是一棵树, 可以使用 TC 为Linux 下的网卡 ens33 创建一个 HTB 的队列规则,需要付给他一个句柄(:1)。
这是整课树的根节点,接下来会有分支,例如图中的三个分支。分别为 (:10)、(:11)、(:12) 。最后的参数default 12, 表示默认发送给 1:12 ,也即发送给第三个分支。
|
|
对于这个网卡,需要规定发送的速度,一般有2个速度可以配置,一个是rate,表示一般情况下的速度,一个是 ceil,表示最高情况下的速度,对于根节点来讲,这两个速度是一样的,于是创建一个 root class,速度为 (rate=100kbps, ceil=100kbps)
|
|
接下来创建3个分支,也即创建3个子class。每个子 class 统一有2个速度,三个分支分别是 (rate=30kbps, ceil=100kbps)、(rate=10kbps, ceil=100kbps)、(rate=60kbps, ceil=100kbps)。
|
|
可以看到三个 rate 加起来,是整个网卡允许的最大速度。(30+10+60)
HTB 有一个很好的特性,同一个 root class 下的子类可以相互借流量,如果不直接在队列规则下面创建一个 root class。而是直接创建三个 class,它们是不能直接互相借流量的。
最后创建 叶子队列规则,分别是 fifo 和 sfq。
|
|
基于这个队列规则,可以设置 TC 设定的发送规则:从 150.158.101.167 来的包,发送给 80 端口的包,从第一个分支 1:10 走;其他从 150.158.101.167 发送来的包从第二个分支 1:11 走,其他的走默认分支。
|
|
实际使用
针对端口限速
在使用git拉取代码时很容易跑满带宽,为了控制带宽的使用,配置如下:
|
|
针对IP进行限速
因为带宽资源有限(20Mbit≈2Mbyte),使用git上传代码的时候导致带宽资源告警,所以对git进行限速,要求:内网不限速;外网上传速度为1M左右。
|
|
下面是限速的效果
限速前:
1 2 3 4 5 6 7 8 9 10
# speedtest-cli Retrieving speedtest.net configuration... Testing from China Unicom (123.112.69.232)... Retrieving speedtest.net server list... Selecting best server based on ping... Hosted by China Unicom (Mianyang) [1413.88 km]: 118.96 ms Testing download speed................................................................................ Download: 7.84 Mbit/s Testing upload speed...................................................................................................... Upload: 10.59 Mbit/s
限速后:(为了演示效果,上传限速1Mbit / s)
1 2 3 4 5 6 7 8 9 10 11
# speedtest-cli Retrieving speedtest.net configuration... Testing from China Unicom (123.112.69.232)... Retrieving speedtest.net server list... Selecting best server based on ping... Hosted by China Unicom 5G (Shanghai) [1072.57 km]: 57.737 ms Testing download speed................................................................................ Download: 8.68 Mbit/s Testing upload speed...................................................................................................... Upload: 1.39 Mbit/s
针对IP进行丢包
|
|
执行后的效果
1 2 3 4 5 6 7 8 9
# ping 110.242.68.66 PING 110.242.68.66 (110.242.68.66) 56(84) bytes of data. 64 bytes from 110.242.68.66: icmp_seq=1 ttl=128 time=15.2 ms ... 64 bytes from 110.242.68.66: icmp_seq=25 ttl=128 time=19.7 ms ^C --- 110.242.68.66 ping statistics --- 28 packets transmitted, 14 received, 50% packet loss, time 27337ms rtt min/avg/max/mdev = 15.145/49.997/123.787/31.840 ms
更多的 netem 模拟网络波动的方法:使用 TC 和 Netem 模拟网络异常
限速脚本
|
|
limit \ VIP1 \ VIP2 需要自行补全才能执行