34.7. 使用 tc-ctinfo 工具配置数据包的速率限制
您可以使用速率限制来限制网络流量,并防止网络中资源耗尽。通过速率限制,您还可以通过限制特定时间段内重复的数据包请求来减少服务器上的负载。另外,您可以通过使用 tc-ctinfo
工具在内核中配置流量控制来管理带宽率。
连接跟踪条目存储 Netfilter
标记和连接信息。当路由器转发来自防火墙的数据包时,路由器会删除或修改数据包的连接跟踪条目。连接跟踪信息(ctinfo
)模块将数据从连接跟踪标记检索到各个字段。此内核模块通过将 Netfilter 标记复制到套接字缓冲区(skb
)标记元数据字段来保留 Netfilter
标记。
先决条件
-
iperf3
工具安装在服务器和客户端上。
流程
在服务器上执行以下步骤:
在网络接口中添加一个虚拟链接:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ip link add name ifb4eth0 numtxqueues 48 numrxqueues 48 type ifb
# ip link add name ifb4eth0 numtxqueues 48 numrxqueues 48 type ifb
这个命令有以下参数:
name ifb4eth0
- 设置新的虚拟设备接口。
numtxqueues 48
- 设置传输队列的数量。
numrxqueues 48
- 设置接收队列的数量。
type ifb
- 设置新设备的类型。
更改接口的状态:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ip link set dev ifb4eth0 up
# ip link set dev ifb4eth0 up
在物理网络接口上添加
qdisc
属性,并将其应用到传入流量:Copy to Clipboard Copied! Toggle word wrap Toggle overflow tc qdisc add dev enp1s0 handle ffff: ingress
# tc qdisc add dev enp1s0 handle ffff: ingress
在
handle ffff:
选项中,handle
参数将主号ffff:
作为默认值分配给enp1s0
物理网络接口上的类qdisc
,其中qdisc
是一个分析流量控制的排队规则参数。在
ip
协议的物理接口上添加一个过滤器,以对数据包进行分类:Copy to Clipboard Copied! Toggle word wrap Toggle overflow tc filter add dev enp1s0 parent ffff: protocol ip u32 match u32 0 0 action ctinfo cpmark 100 action mirred egress redirect dev ifb4eth0
# tc filter add dev enp1s0 parent ffff: protocol ip u32 match u32 0 0 action ctinfo cpmark 100 action mirred egress redirect dev ifb4eth0
这个命令有以下属性:
parent ffff:
-
为父
qdisc
设置主号ffff:
。 u32 match u32 0 0
-
设置
u32
过滤器,以匹配
u32
模式的 IP 标头。第一个0
表示 IP 标头的第二个字节,另一个0
用于掩码匹配,告知过滤器要匹配哪个位。 action ctinfo
- 设置操作,以将连接跟踪标记的数据检索到各个字段。
cpmark 100
-
将连接跟踪标记(connmark)
100
复制到数据包 IP 标头字段中。 action mirred egress redirect dev ifb4eth0
-
将
操作
设置为mirred
将接收的数据包重定向到ifb4eth0
目的地接口。
向接口中添加类
qdisc
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow tc qdisc add dev ifb4eth0 root handle 1: htb default 1000
# tc qdisc add dev ifb4eth0 root handle 1: htb default 1000
此命令将主号
1
设置为 rootqdisc
,并将htb
层次结构令牌存储桶与 minor-id1000
的类qdisc
一起使用。将接口上的流量限制为 1 Mbit/s,上限为 2 Mbit/s:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow tc class add dev ifb4eth0 parent 1:1 classid 1:100 htb ceil 2mbit rate 1mbit prio 100
# tc class add dev ifb4eth0 parent 1:1 classid 1:100 htb ceil 2mbit rate 1mbit prio 100
这个命令有以下参数:
parent 1:1
-
将
parent
设为classid
为1
,将root
设为1
。 classid 1:100
-
将
classid
设置为1:100
,其中1
是父qdisc
的数量,100
是父qdisc
的类的数量。 htb ceil 2mbit
-
htb
类qdisc
允许上限带宽2 Mbit/s
作为ceil
速率限制。
将无类别
qdisc
的 Stochastic Fairness Queuing (sfq
)应用到 时间间隔为60
秒的接口,以减少队列算法的影响:Copy to Clipboard Copied! Toggle word wrap Toggle overflow tc qdisc add dev ifb4eth0 parent 1:100 sfq perturb 60
# tc qdisc add dev ifb4eth0 parent 1:100 sfq perturb 60
在接口中添加防火墙标记(
fw
)过滤器:Copy to Clipboard Copied! Toggle word wrap Toggle overflow tc filter add dev ifb4eth0 parent 1:0 protocol ip prio 100 handle 100 fw classid 1:100
# tc filter add dev ifb4eth0 parent 1:0 protocol ip prio 100 handle 100 fw classid 1:100
从连接标记(
CONNMARK
)恢复数据包元标记:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add rule ip mangle PREROUTING counter meta mark set ct mark
# nft add rule ip mangle PREROUTING counter meta mark set ct mark
在这个命令中,
nft
工具有一个带有PREROUTING
链规则规范的mangle
表,该表在路由之前更改传入的数据包,来将数据包标记替换为CONNMARK
。如果没有
nft
表和链存在,请创建一个表并添加一个链规则:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add table ip mangle nft add chain ip mangle PREROUTING {type filter hook prerouting priority mangle \;}
# nft add table ip mangle # nft add chain ip mangle PREROUTING {type filter hook prerouting priority mangle \;}
在指定目标地址
192.0.2.3
上接收的tcp
数据包上设置 meta 标记:Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add rule ip mangle PREROUTING ip daddr 192.0.2.3 counter meta mark set 0x64
# nft add rule ip mangle PREROUTING ip daddr 192.0.2.3 counter meta mark set 0x64
将数据包标记保存到连接标记中:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow nft add rule ip mangle PREROUTING counter ct mark set mark
# nft add rule ip mangle PREROUTING counter ct mark set mark
使用
-s
参数在系统上运行iperf3
工具来作为服务器,然后服务器等待客户端连接的响应:Copy to Clipboard Copied! Toggle word wrap Toggle overflow iperf3 -s
# iperf3 -s
在客户端上,将
iperf3
作为客户端运行,并连接到在 IP 地址192.0.2.3
上侦听定期的 HTTP 请求响应时间戳的服务器:Copy to Clipboard Copied! Toggle word wrap Toggle overflow iperf3 -c 192.0.2.3 -t TCP_STREAM | tee rate
# iperf3 -c 192.0.2.3 -t TCP_STREAM | tee rate
192.0.2.3
是服务器的 IP 地址,而192.0.2.4
是客户端的 IP 地址。按 Ctrl+C 终止服务器上的
iperf3
工具:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Accepted connection from 192.0.2.4, port 52128 [5] local 192.0.2.3 port 5201 connected to 192.0.2.4 port 52130 [ID] Interval Transfer Bitrate [5] 0.00-1.00 sec 119 KBytes 973 Kbits/sec [5] 1.00-2.00 sec 116 KBytes 950 Kbits/sec ... [ID] Interval Transfer Bitrate [5] 0.00-14.81 sec 1.51 MBytes 853 Kbits/sec receiver iperf3: interrupt - the server has terminated
Accepted connection from 192.0.2.4, port 52128 [5] local 192.0.2.3 port 5201 connected to 192.0.2.4 port 52130 [ID] Interval Transfer Bitrate [5] 0.00-1.00 sec 119 KBytes 973 Kbits/sec [5] 1.00-2.00 sec 116 KBytes 950 Kbits/sec ... [ID] Interval Transfer Bitrate [5] 0.00-14.81 sec 1.51 MBytes 853 Kbits/sec receiver iperf3: interrupt - the server has terminated
按 Ctrl+C 终止客户端上的
iperf3
工具:Copy to Clipboard Copied! Toggle word wrap Toggle overflow Connecting to host 192.0.2.3, port 5201 [5] local 192.0.2.4 port 52130 connected to 192.0.2.3 port 5201 [ID] Interval Transfer Bitrate Retr Cwnd [5] 0.00-1.00 sec 481 KBytes 3.94 Mbits/sec 0 76.4 KBytes [5] 1.00-2.00 sec 223 KBytes 1.83 Mbits/sec 0 82.0 KBytes ... [ID] Interval Transfer Bitrate Retr [5] 0.00-14.00 sec 3.92 MBytes 2.35 Mbits/sec 32 sender [5] 0.00-14.00 sec 0.00 Bytes 0.00 bits/sec receiver iperf3: error - the server has terminated
Connecting to host 192.0.2.3, port 5201 [5] local 192.0.2.4 port 52130 connected to 192.0.2.3 port 5201 [ID] Interval Transfer Bitrate Retr Cwnd [5] 0.00-1.00 sec 481 KBytes 3.94 Mbits/sec 0 76.4 KBytes [5] 1.00-2.00 sec 223 KBytes 1.83 Mbits/sec 0 82.0 KBytes ... [ID] Interval Transfer Bitrate Retr [5] 0.00-14.00 sec 3.92 MBytes 2.35 Mbits/sec 32 sender [5] 0.00-14.00 sec 0.00 Bytes 0.00 bits/sec receiver iperf3: error - the server has terminated
验证
显示接口上
htb
和sfq
类的数据包计数的统计信息:Copy to Clipboard Copied! Toggle word wrap Toggle overflow tc -s qdisc show dev ifb4eth0
# tc -s qdisc show dev ifb4eth0 qdisc htb 1: root ... Sent 26611455 bytes 3054 pkt (dropped 76, overlimits 4887 requeues 0) ... qdisc sfq 8001: parent ... Sent 26535030 bytes 2296 pkt (dropped 76, overlimits 0 requeues 0) ...
显示
mirred
和ctinfo
操作的数据包计数的统计信息:Copy to Clipboard Copied! Toggle word wrap Toggle overflow tc -s filter show dev enp1s0 ingress
# tc -s filter show dev enp1s0 ingress filter parent ffff: protocol ip pref 49152 u32 chain 0 filter parent ffff: protocol ip pref 49152 u32 chain 0 fh 800: ht divisor 1 filter parent ffff: protocol ip pref 49152 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 terminal flowid not_in_hw (rule hit 8075 success 8075) match 00000000/00000000 at 0 (success 8075 ) action order 1: ctinfo zone 0 pipe index 1 ref 1 bind 1 cpmark 0x00000064 installed 3105 sec firstused 3105 sec DSCP set 0 error 0 CPMARK set 7712 Action statistics: Sent 25891504 bytes 3137 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 action order 2: mirred (Egress Redirect to device ifb4eth0) stolen index 1 ref 1 bind 1 installed 3105 sec firstused 3105 sec Action statistics: Sent 25891504 bytes 3137 pkt (dropped 0, overlimits 61 requeues 0) backlog 0b 0p requeues 0
显示
htb
速率限制器及其配置的统计信息:Copy to Clipboard Copied! Toggle word wrap Toggle overflow tc -s class show dev ifb4eth0
# tc -s class show dev ifb4eth0 class htb 1:100 root leaf 8001: prio 7 rate 1Mbit ceil 2Mbit burst 1600b cburst 1600b Sent 26541716 bytes 2373 pkt (dropped 61, overlimits 4887 requeues 0) backlog 0b 0p requeues 0 lended: 7248 borrowed: 0 giants: 0 tokens: 187250 ctokens: 93625
其他资源
-
您系统上的
tc (8)
和tc-ctinfo (8)
手册页 -
您系统上的
nft (8)
手册页