基本信息
版本支持
已实测版本:
- DPVS-1.8.2-with-DPDK-17.11.2
- DPVS-1.9.0-with-DPDK-20.11.1
- DPVS-1.9.2-with-DPDK-20.11.1
上述三个版本对 tc 的配置命令并无差异,文中的配置命令均可受用。
能力支持
- 网卡级别流量限速: Example 1. Device traffic shaping (Egress)
- 细分流量控制: Example 2. Traffic classification and flow control (Egress)
- 访问控制: Example 3. Access control with TC (Ingress)
- 流量控制及访问控制: Example 4. Traffic policing for services (Ingress)
- 动态访问控制: Example 5. Dynamic allow/deny access list using TC ipset classifier
以上策略不局限于仅在 Ingress 或 Egress 单向流量配置,也可在同一个流量策略中实现双向组合控制。
基本概念
实现方式
DPVS的限速是通过 TC(Traffic Control) 的机制实现的,Traffic Control是一组在网络接口上排队传输/接收数据包的机制和操作。其中包括排队(enqueuing)、流控策略(policing)、分类(classifying)、调度(scheduling)、塑形(shaping)和丢包(dropping)等操作。
主要用途介绍:
- Policing:流量控制机制,常用于网络边界,以确保对等方不会消耗超过其分配带宽的流量。
- Classifying:分组机制,将数据包分离到不同的处理方式,可能是不同的输出队列中。
- Scheduling:排程机制,将数据包在特定队列的输入和输出之间排列(或重新排列)。
- Shaping:塑形机制,将数据包在输出队列中延迟传输,以满足所需的输出速率。
- Dropping:丢弃机制,将数据包完全丢弃。
在DPVS上的实现机制
DPVS通过两种TC对象(QSch 和 Cls)实现上述流量控制机制。DPVS 的 TC 框架是基于每个逻辑核(lcore)实现的,以避免多线程竞争条件造成的性能损失。每个 Qsch 必须是根 Qsch 或现有 Qsch 的一个子 Qsch ,并且根 Qsch 必须连接到 DPVS 设备。DPVS TC支持以下设备类型:
- 物理设备
- 绑定(bonding)设备
- VLAN设备
目前不支持隧道设备。支持出站(egress)和入站(ingress)流量,但需要注意的是,入站流量很难受限,因为它主要由网络通信的对等端决定。
扩展说明:
此处的出站和入站都是相对于 DPVS 而言的,而在实际场景中,如果站在 RS 的视角来看这里的出站和入站,那么应该是:
- 出站: 即 RS 的流入/下载
- 入站: 即 RS 的流出/上传
基本上,Qsch由一个或多个队列、一组用于队列的操作以及一些流量统计成员组成。Qsch可以作为 根Qsch 安装到 DPVS 接口设备中,也可以作为 子Qsch 集成到现有的 Qsch 中。根Qsch接收其连接设备的所有传入/传出流量,而 非根Qsch 只能从其 父Qsch 接收流量。Qsch可以分为两种不同的类型——出站Qsch和入站Qsch,以执行传输到或从 DPVS 设备接收的数据包的流量控制策略。
Cls是一种分类器,由一组用于将流量分类到不同 Qsch (队列调度器/规则)的操作组成。Cls必须附加到现有的 Qsch 规则上,并在 Cls 匹配到的数据包后,会由 Qsch 规则来决定后续操作。DPVS支持两种分类的目标操作:丢弃(drop)或加入 子Qsch (queue)。不允许将流量分类到非子Qsch(例如孙子Qsch)中。基于性能考虑,数据包仅会排入最后匹配的 Qsch 中,而不是对前序 Qsch 规则逐个匹配。这意味着,如果 Qsch 被层次化配置,并且网络数据包从 根Qsch 到 叶Qsch 匹配所有 Cls,那么数据包将直接被加入到 叶Qsch 中,而不必一个接一个地经过。
每个 Cls 只能处理一种指定的数据包类型。DPVS Cls支持三种数据包类型–IPv4、IPv6和Vlan。Cls支持优先级。如果有两个或多个 Cls 附加到一个 Qsch 上,并且它们都匹配 Qsch 中的数据包,则采用具有最高优先级的 Cls 的分类结果。
Qsch 对象
DPVS TC 实现了四个 Qsch 对象 – pfifo
、bfifo
、pfifo_fast
和 tbf
。原则上,它们与 Linux TC 的对应项几乎相同。
pfifo,bfifo
FIFO
意味着“先进先出” ( First-In, First-Out ) ,它只是在收到数据包后尽快传输数据包,并按照数据包接收的顺序排队。
然而,一个真正的 FIFO Qsch 必须有一个大小限制(缓冲区大小),以防止队列溢出。DPVS实现了两个基本的 FIFO Qsch : 一个基于字节(bytes),另一个基于数据包(packets)。无论使用哪种类型的 FIFO,其队列大小都由参数 limit
来定义。
对于 pfifo
,单位被理解为数据包(packets),对于 bfifo
,单位被理解为字节(bytes)。
pfifo_fast
基于传统的 FIFO Qsch,pfifo_fast Qsch 也提供了一些优先级设置。它提供了三个不同的频段(单独的FIFO)来分离流量。
最高优先级的流量(交互式流量)被放置在频段0 (FIFO 0) 中,并优先得到服务。同样地,如有频段2 (FIFO 2) 的数据包需要出队(流出),则需要等待频段1 (FIFO 1) 处理完其所有排队中的现有数据包。
因此,通常建议将 pfifo_fast
作为根 Qsch。(支持优先级和分离流量的设计,有助于提高网络性能和用户体验,对于多数应用场景已经足够。)
而对于 pfifo_fast
队列,用户没有任何可配置项。关于 priomap
和使用 ToS 比特位的详细信息,请参见文档中的 pfifo-fast 部分。
tbf
TBF
是“令牌桶过滤器”(Token Bucket Filter)的缩写,因为它是建立在 token 和 buckets 之上。它简单地塑造了一个接口上传输的流量。为了限制数据包从一个特定接口的脱队速度,TBF Qsch是一个完美的解决方案。它只是将传输的流量减慢到指定的速率。只有当有足够的令牌可用时,数据包才会被传输。否则,数据包将被推迟。以这种方式延迟数据包将在数据包的往返时间中引入一个人工延迟。
TBF QSch可以有以下参数:
- rate: 速率参数,单位是 bps,可能会加上 k、m、g 等的 SI 单位后缀(1000进制),最大值为 4 Gbps。
- burst: 桶大小参数,单位是 bytes。这是可用令牌的最大字节数,通常需要根据速率设置较大的 burst 值。
- limit/latency: limit 表示可以等待令牌变得可用的队列中的最大字节数,latency 表示在 TBF 中一个数据包最大可以等待的时间,单位分别为 bytes 和 ms 。
- peakrate: 可选参数,表示桶的最大耗尽速率,单位是 bps,可能会加上 k、m、g 等的 SI 单位后缀。
- mtu: 可选参数,表示 peakrate 桶的大小,单位是 bytes 。
Cls对象
match
Cls match
规则由两部分组成:模式(pattern)和目标(target)。生产环境中,每个来自 Qsch 的数据包都会与模式进行比较,如果匹配,它们的处理方式将由目标的策略决定。
在配置 模式(pattern)
中,需要考虑一个数据流中的以下五个属性:
- Protocol: 协议,包括: TCP, UDP, ICMP.
- Source ip-port range: 源IP的端口范围,数据包的源IP地址和端口的可接受范围。
- Dest ip-port range: 目的IP的端口范围,数据包的目标IP地址和端口的可接受范围。
- Ingress device: 入站设备,接收数据包的设备,仅用于入口流量。
- Egress device: 出站设备,数据包被发送的设备,仅适用于出口流量。
在实际配置中,可以省略上述 pattern 中的一个或多个属性,省略的属性在匹配时会被忽略。
例如: pattern 'tcp,from-192.168.0.1:1-1024,oif-dpdk0'
表示匹配源IP地址为 192.168.0.1
,源端口在1到1024之间,从 DPVS dpdk0
接口发出的 TCP
数据包。
而对于 Cls target
配置有两种策略:Qsch或Drop,具体如下:
- 前者(Qsch): 将匹配的数据包分类到指定 Qsch 的队列中,且目标 Qsch 必须是 Cls 所附加到的 Qsch 的子级。
- 后者(Drop): 仅丢弃匹配的数据包。
功能介绍
基本命令
export PATH=/usr/local/dpvs-1.9.2/bin:$PATH
# 开启 egress 限速
dpip link set dpdk0 tc-egress on
# 添加 200Mbps 带宽限制,突发可达240Mpbs的限速规则
dpip qsch add dev dpdk0 root tbf rate 200m burst 2400000 latency 1ms
# 查看 dpdk0 流量调度器(qdisc)信息
dpip qsch show dev dpdk0
# 查看 dpdk0 根流量调度器下的分类器(cls)信息
dpip cls show dev dpdk0 qsch root
# 查看 dpdk0 分类器 ID 为 1 的分类器信息
dpip cls show dev dpdk0 qsch 1:
# 修改限速20Mbps,突发30Mbps
dpip qsch change dev dpdk0 root tbf rate 20m burst 240000 latency 1ms
# 删除限速规则
## 注意: 如有多层规则,那么需要对每层规则手动删除
dpip qsch del dev dpdk0 root tbf
dpip qsch del dev dpdk0 root pfifo_fast
dpip qsch del dev dpdk0 handle 1:0 parent root
dpip qsch del dev dpdk0 handle 10:0 parent 1:0
关键语法说明:
rate
: 带宽限制,单位(bits/s), 支持 SI 制式(1000进)单位 (k, m, g),例如: 10k, 20m, 1gburst
: 突发速率,单位(Bps|Bytes/s),例如可以理解为最大突发可达: xxMB/s- 上述两者相互制约:
- 最大
burst
决定最大带宽,假设rate
设置为200m
,burst
设置为2000000
(约1.9MB),此时最大带宽约为67Mbps
. - 最大
rate
制约burst
,假设rate
设置为100m
,burst
设置为20000000
(约19MB),此时最大带宽约为200Mbps
.
- 最大
qsch
: 表示网口的排队调度器设置,包括 根排队调度器 和 子排队调度器 。- 根排队调度器是整个调度器层次结构的最上层,它控制整个端口的调度和限速。
- 子排队调度器是根排队调度器的下一级,它控制端口接收到的特定流量的调度和限速。
- 例如,如果要为特定 IP 地址或端口号配置不同的服务质量(QoS),可以为其创建子排队调度器。
qsch root
: 表示网口根排队调度器的分类规则,即指定哪些流量将被发送到子排队调度器进行进一步处理。qsch 1:
: 表示网口qsch 1
的子排队调度器的分类规则,即指定哪些流量将被发送到qsch 1
进行进一步处理。需要注意的是,这里的qsch 1:
中的冒号(:)表示所有qsch 1
的子排队调度器,而不是qsch 1
本身。
限速配置中,可能实际速率会低于限速值,此时可适时调整。
以下,将基于打流实验进行简单的限速配置介绍。
基准速度
基于iperf3打流进行带宽测试。
Keepalived配置
仅展示关键配置。
local_address_group laddr_g1 {
192.168.7.185 dpdk0
}
local_address_group laddr_g2 {
192.168.7.186 dpdk0
}
virtual_server 192.168.7.182 12334 {
delay_loop 3 # 执行RS健康检测间隔,单位: 秒
lb_algo rr
lb_kind FNAT
protocol TCP
syn_proxy
laddr_group_name laddr_g1 # 从这个转发组ID与RS建连
# 如果所有RS检测失败,则运行脚本
quorum_down /etc/keepalived/check_rs.sh
real_server 192.168.7.27 12334 {
weight 100
TCP_CHECK {
connect_timeout 3
nb_sock_retry 2
delay_before_retry 3
connect_port 80
}
}
}
virtual_server 192.168.7.182 12335 {
delay_loop 3
lb_algo rr
lb_kind FNAT
protocol TCP
syn_proxy
laddr_group_name laddr_g1
quorum_down /etc/keepalived/check_rs.sh
real_server 192.168.7.27 12335 {
weight 100
TCP_CHECK {
connect_timeout 3
nb_sock_retry 2
delay_before_retry 3
connect_port 80
}
}
}
virtual_server 192.168.7.183 12335 {
delay_loop 3
lb_algo rr
lb_kind FNAT
protocol TCP
syn_proxy
laddr_group_name laddr_g2
quorum_down /etc/keepalived/check_rs.sh
real_server 192.168.7.95 12335 {
weight 100
TCP_CHECK {
connect_timeout 3
nb_sock_retry 2
delay_before_retry 3
connect_port 80
}
}
}
IPVS关系
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.7.182:12334 rr
-> 192.168.7.27:12334 FullNat 100 0 0
TCP 192.168.7.182:12335 rr
-> 192.168.7.27:12335 FullNat 100 0 0
TCP 192.168.7.183:12335 rr
-> 192.168.7.95:12335 FullNat 100 0 0
iPerf3命令
服务端
iperf3 -s -p 12334 -i 1
客户端
# 测试客户端上传,DPVS端下载,RS端下载
iperf3 -c 192.168.7.182 -p 12334 -t 10
结果输出
# 客户端上传
# iperf3 -c 192.168.7.182 -p 12334 -t 10
Connecting to host 192.168.7.182, port 12334
[ 4] local 192.168.7.53 port 59896 connected to 192.168.7.182 port 12334
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 93.6 MBytes 785 Mbits/sec
[ 4] 1.00-2.00 sec 98.2 MBytes 824 Mbits/sec
[ 4] 2.00-3.00 sec 92.6 MBytes 777 Mbits/sec
[ 4] 3.00-4.00 sec 95.5 MBytes 801 Mbits/sec
[ 4] 4.00-5.00 sec 96.3 MBytes 808 Mbits/sec
[ 4] 5.00-6.00 sec 97.5 MBytes 818 Mbits/sec
[ 4] 6.00-7.00 sec 97.9 MBytes 821 Mbits/sec
[ 4] 7.00-8.00 sec 96.1 MBytes 807 Mbits/sec
[ 4] 8.00-9.00 sec 94.6 MBytes 793 Mbits/sec
[ 4] 9.00-10.00 sec 91.7 MBytes 769 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 954 MBytes 800 Mbits/sec sender
[ 4] 0.00-10.00 sec 954 MBytes 800 Mbits/sec receiver
# ---
# 客户端下载
# iperf3 -c 192.168.7.182 -p 12334 -t 10 -R
Connecting to host 192.168.7.182, port 12334
Reverse mode, remote host 192.168.7.182 is sending
[ 4] local 192.168.7.53 port 59944 connected to 192.168.7.182 port 12334
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 89.6 MBytes 751 Mbits/sec
[ 4] 1.00-2.00 sec 90.4 MBytes 758 Mbits/sec
[ 4] 2.00-3.00 sec 87.8 MBytes 736 Mbits/sec
[ 4] 3.00-4.00 sec 88.2 MBytes 739 Mbits/sec
[ 4] 4.00-5.00 sec 90.8 MBytes 761 Mbits/sec
[ 4] 5.00-6.00 sec 87.1 MBytes 731 Mbits/sec
[ 4] 6.00-7.00 sec 90.9 MBytes 763 Mbits/sec
[ 4] 7.00-8.00 sec 87.6 MBytes 735 Mbits/sec
[ 4] 8.00-9.00 sec 92.5 MBytes 776 Mbits/sec
[ 4] 9.00-10.00 sec 90.5 MBytes 759 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 896 MBytes 751 Mbits/sec 0 sender
[ 4] 0.00-10.00 sec 896 MBytes 751 Mbits/sec receiver
iperf Done.
可得 RS 的基准带宽:
- 下行约为
800Mbps
。 - 上行约为
751Mbps
。
出站限速-Egress
整体限速
该限速方法是针对整个 dpdk 网卡进行限速,如果有需要针对多个 VIP、RS 限速需求,应该采取”分类限速”。
设置限速
双向限速
开启限速
- 将限速设置为
200Mbps
.
针对 dpdk0
网卡开启限速
cd /usr/local/dpvs-1.9.2/bin
./dpip link set dpdk0 tc-egress on
./dpip qsch add dev dpdk0 root tbf rate 200m burst 20000000 latency 1ms
查看当前限速策略
./dpip qsch show dev dpdk0
# >>>
qsch tbf root dev dpdk0 parent 0: flags 0x0 cls 0 rate 200.00Mbps burst 20000000B limit 25000B
结果输出
# 客户端上传速率
iperf3 -c 192.168.7.182 -p 12334 -t 10
# >>>
Connecting to host 192.168.7.182, port 12334
[ 4] local 192.168.7.53 port 53672 connected to 192.168.7.182 port 12334
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 37.4 MBytes 314 Mbits/sec
[ 4] 1.00-2.00 sec 19.6 MBytes 164 Mbits/sec
[ 4] 2.00-3.00 sec 28.1 MBytes 236 Mbits/sec
[ 4] 3.00-4.00 sec 18.9 MBytes 158 Mbits/sec
[ 4] 4.00-5.00 sec 22.5 MBytes 189 Mbits/sec
[ 4] 5.00-6.00 sec 27.0 MBytes 227 Mbits/sec
[ 4] 6.00-7.00 sec 20.3 MBytes 170 Mbits/sec
[ 4] 7.00-8.00 sec 20.6 MBytes 173 Mbits/sec
[ 4] 8.00-9.00 sec 26.3 MBytes 220 Mbits/sec
[ 4] 9.00-10.00 sec 19.1 MBytes 160 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 240 MBytes 201 Mbits/sec sender
[ 4] 0.00-10.00 sec 240 MBytes 201 Mbits/sec receiver
iperf Done.
# ---
# 客户端下载速率
iperf3 -c 192.168.7.182 -p 12335 -t 10 -R
# >>>
Connecting to host 192.168.7.182, port 12335
Reverse mode, remote host 192.168.7.182 is sending
[ 4] local 192.168.7.53 port 56984 connected to 192.168.7.182 port 12335
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.01 sec 37.5 MBytes 313 Mbits/sec
[ 4] 1.01-2.00 sec 26.1 MBytes 220 Mbits/sec
[ 4] 2.00-3.00 sec 19.5 MBytes 163 Mbits/sec
[ 4] 3.00-4.00 sec 26.0 MBytes 219 Mbits/sec
[ 4] 4.00-5.00 sec 22.7 MBytes 190 Mbits/sec
[ 4] 5.00-6.00 sec 21.5 MBytes 180 Mbits/sec
[ 4] 6.00-7.00 sec 23.9 MBytes 201 Mbits/sec
[ 4] 7.00-8.00 sec 20.3 MBytes 170 Mbits/sec
[ 4] 8.00-9.00 sec 25.2 MBytes 212 Mbits/sec
[ 4] 9.00-10.00 sec 19.0 MBytes 159 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 242 MBytes 203 Mbits/sec 708 sender
[ 4] 0.00-10.00 sec 242 MBytes 203 Mbits/sec receiver
iperf Done.
平均带宽均在 200Mbps
左右,验证生效。
调整限速
- 将限速设置为
30Mbps
../dpip qsch change dev dpdk0 root tbf rate 30m burst 3000000 latency 1ms ./dpip qsch show dev dpdk0 # >>> qsch tbf root dev dpdk0 parent 0: flags 0x0 cls 0 rate 30.00Mbps burst 3000000B limit 3750B
结果输出
客户端发起打流,验证限速结果
# 客户端上传速率
iperf3 -c 192.168.7.182 -p 12334 -t 10
# >>>
Connecting to host 192.168.7.182, port 12334
[ 4] local 192.168.7.53 port 53837 connected to 192.168.7.182 port 12334
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 5.24 MBytes 43.8 Mbits/sec
[ 4] 1.00-2.00 sec 4.37 MBytes 36.8 Mbits/sec
[ 4] 2.00-3.00 sec 3.35 MBytes 28.1 Mbits/sec
[ 4] 3.00-4.00 sec 3.36 MBytes 28.2 Mbits/sec
[ 4] 4.00-5.00 sec 3.39 MBytes 28.4 Mbits/sec
[ 4] 5.00-6.00 sec 3.43 MBytes 28.7 Mbits/sec
[ 4] 6.00-7.00 sec 3.41 MBytes 28.7 Mbits/sec
[ 4] 7.00-8.00 sec 3.42 MBytes 28.5 Mbits/sec
[ 4] 8.00-9.00 sec 3.38 MBytes 28.4 Mbits/sec
[ 4] 9.00-10.00 sec 3.41 MBytes 28.6 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 36.8 MBytes 30.8 Mbits/sec sender
[ 4] 0.00-10.00 sec 36.6 MBytes 30.7 Mbits/sec receiver
iperf Done.
# ---
# 客户端下载速率
iperf3 -c 192.168.7.182 -p 12335 -t 10 -R
# >>>
Connecting to host 192.168.7.182, port 12335
Reverse mode, remote host 192.168.7.182 is sending
[ 4] local 192.168.7.53 port 57333 connected to 192.168.7.182 port 12335
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 5.90 MBytes 49.3 Mbits/sec
[ 4] 1.00-2.00 sec 2.98 MBytes 25.0 Mbits/sec
[ 4] 2.00-3.00 sec 3.79 MBytes 31.8 Mbits/sec
[ 4] 3.00-4.00 sec 3.05 MBytes 25.6 Mbits/sec
[ 4] 4.00-5.01 sec 3.76 MBytes 31.6 Mbits/sec
[ 4] 5.01-6.00 sec 3.02 MBytes 25.4 Mbits/sec
[ 4] 6.00-7.00 sec 3.80 MBytes 32.0 Mbits/sec
[ 4] 7.00-8.00 sec 3.02 MBytes 25.3 Mbits/sec
[ 4] 8.00-9.00 sec 3.13 MBytes 26.4 Mbits/sec
[ 4] 9.00-10.00 sec 3.69 MBytes 30.9 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 36.6 MBytes 30.7 Mbits/sec 1940 sender
[ 4] 0.00-10.00 sec 36.2 MBytes 30.3 Mbits/sec receiver
iperf Done.
持续流量过程中调整限速
- 在持续的流量中,将限速从
200Mbps
调整为50Mbps
再调整回200Mbps
,验证过程是否有影响。
结果输出
iperf3 -c 192.168.7.182 -p 12334 -t 15
# >>>
Connecting to host 192.168.7.182, port 12334
[ 4] local 192.168.7.53 port 54238 connected to 192.168.7.182 port 12334
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 35.0 MBytes 294 Mbits/sec
[ 4] 1.00-2.00 sec 28.6 MBytes 240 Mbits/sec
[ 4] 2.00-3.00 sec 18.6 MBytes 156 Mbits/sec
[ 4] 3.00-4.00 sec 20.2 MBytes 170 Mbits/sec
[ 4] 4.00-5.00 sec 28.1 MBytes 235 Mbits/sec
[ 4] 5.00-6.00 sec 8.72 MBytes 73.3 Mbits/sec
[ 4] 6.00-7.00 sec 5.73 MBytes 48.1 Mbits/sec
[ 4] 7.00-8.00 sec 5.83 MBytes 48.9 Mbits/sec
[ 4] 8.00-9.00 sec 3.97 MBytes 33.2 Mbits/sec
[ 4] 9.00-10.00 sec 5.83 MBytes 49.0 Mbits/sec
[ 4] 10.00-11.00 sec 5.77 MBytes 48.3 Mbits/sec
[ 4] 11.00-12.00 sec 37.3 MBytes 313 Mbits/sec
[ 4] 12.00-13.00 sec 19.3 MBytes 162 Mbits/sec
[ 4] 13.00-14.00 sec 28.6 MBytes 241 Mbits/sec
[ 4] 14.00-15.00 sec 19.0 MBytes 159 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-15.00 sec 271 MBytes 151 Mbits/sec sender
[ 4] 0.00-15.00 sec 271 MBytes 151 Mbits/sec receiver
验证有效。
删除限速
./dpip qsch del dev dpdk0 root tbf
分类限速
该限速方法可以根据应用场景进行分类限速,支持对多个 RS 配置不同限速规则。
场景说明
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.7.182:12334 rr synproxy
-> 192.168.7.27:12334 FullNat 100 0 0
TCP 192.168.7.182:12335 rr synproxy
-> 192.168.7.27:12335 FullNat 100 0 0
TCP 192.168.7.183:12335 rr synproxy
-> 192.168.7.95:12335 FullNat 100 0 0
接下来,将针对上述的 RS 设置不同的限速策略:
- 双向不限速
- 所有 RS 的 12334 端口: 双向不限速
- 针对RS限制出站
- 192.168.7.27:12335: 限制出站
200Mbps
(即 RS 下载带宽) - 192.168.7.95:12335: 限制出站
250Mbps
(即 RS 下载带宽)
- 192.168.7.27:12335: 限制出站
配置方式
# 开启egress限速
./dpip link set dpdk0 tc-egress on
# 编写分级限速策略
./dpip qsch add dev dpdk0 root pfifo_fast
./dpip qsch add dev dpdk0 handle 1:0 parent root bfifo limit 10000000
./dpip qsch add dev dpdk0 handle 10:0 parent 1:0 pfifo limit 100000
./dpip qsch add dev dpdk0 handle 20:0 parent 1:0 tbf rate 80m burst 8000000 latency 2ms
./dpip qsch add dev dpdk0 handle 30:0 parent 1:0 tbf rate 150m burst 15000000 latency 2ms
# 分级策略
./dpip cls add dev dpdk0 qsch root handle 0:1 match pattern 'tcp,oif=dpdk0' target 1:
# 针对RS地址分类
./dpip cls add dev dpdk0 qsch 1: handle 1:1 match pattern 'tcp,to=:12334,oif=dpdk0' target 10:
./dpip cls add dev dpdk0 qsch 1: handle 1:2 match pattern 'tcp,to=192.168.7.27:12335,oif=dpdk0' target 20:
./dpip cls add dev dpdk0 qsch 1: handle 1:3 match pattern 'tcp,to=192.168.7.95:12335,oif=dpdk0' target 30:
查看限速策略
# 整体限速
./dpip qsch show dev dpdk0
# >>>
qsch pfifo_fast root dev dpdk0 parent 0: flags 0x0 cls 1 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qsch tbf 30: dev dpdk0 parent 1: flags 0x0 cls 0 rate 150.00Mbps burst 15000000B limit 37500B
qsch tbf 20: dev dpdk0 parent 1: flags 0x0 cls 0 rate 80.00Mbps burst 8000000B limit 20000B
qsch pfifo 10: dev dpdk0 parent 1: flags 0x0 cls 0 limit 100000
qsch bfifo 1: dev dpdk0 parent root flags 0x0 cls 3 limit 10000000
# ---
# 分级策略
./dpip cls show dev dpdk0 qsch 1:
# >>>
cls match 1:1 dev dpdk0 qsch 1: pkttype 0x0800 prio 0 TCP,to=0.0.0.0-0.0.0.0:12334-12334,oif=dpdk0 target 10:
cls match 1:2 dev dpdk0 qsch 1: pkttype 0x0800 prio 0 TCP,to=192.168.7.27-192.168.7.27:12335-12335,oif=dpdk0 target 20:
cls match 1:3 dev dpdk0 qsch 1: pkttype 0x0800 prio 0 TCP,to=192.168.7.95-192.168.7.95:12335-12335,oif=dpdk0 target 30:
结果输出
# 192.168.7.182:12334不限速
iperf3 -c 192.168.7.182 -p 12334 -t 10
# >>>
Connecting to host 192.168.7.182, port 12334
[ 4] local 192.168.7.53 port 65415 connected to 192.168.7.182 port 12334
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.01 sec 87.9 MBytes 727 Mbits/sec
[ 4] 1.01-2.00 sec 84.8 MBytes 722 Mbits/sec
[ 4] 2.00-3.00 sec 92.4 MBytes 775 Mbits/sec
[ 4] 3.00-4.00 sec 84.7 MBytes 710 Mbits/sec
[ 4] 4.00-5.00 sec 96.8 MBytes 812 Mbits/sec
[ 4] 5.00-6.00 sec 90.5 MBytes 759 Mbits/sec
[ 4] 6.00-7.00 sec 95.5 MBytes 801 Mbits/sec
[ 4] 7.00-8.00 sec 90.2 MBytes 756 Mbits/sec
[ 4] 8.00-9.00 sec 88.1 MBytes 739 Mbits/sec
[ 4] 9.00-10.00 sec 96.7 MBytes 811 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 908 MBytes 761 Mbits/sec sender
[ 4] 0.00-10.00 sec 908 MBytes 761 Mbits/sec receiver
iperf Done.
# ---
# 192.168.7.182:12335限速80Mbps
iperf3 -c 192.168.7.182 -p 12335 -t 10
# >>>
Connecting to host 192.168.7.182, port 12335
[ 4] local 192.168.7.53 port 65441 connected to 192.168.7.182 port 12335
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 14.7 MBytes 123 Mbits/sec
[ 4] 1.00-2.00 sec 9.42 MBytes 78.9 Mbits/sec
[ 4] 2.00-3.00 sec 9.37 MBytes 78.5 Mbits/sec
[ 4] 3.00-4.00 sec 9.80 MBytes 82.3 Mbits/sec
[ 4] 4.00-5.00 sec 7.62 MBytes 64.1 Mbits/sec
[ 4] 5.00-6.00 sec 9.23 MBytes 77.1 Mbits/sec
[ 4] 6.00-7.00 sec 10.1 MBytes 85.3 Mbits/sec
[ 4] 7.00-8.00 sec 9.39 MBytes 78.9 Mbits/sec
[ 4] 8.00-9.00 sec 9.40 MBytes 78.6 Mbits/sec
[ 4] 9.00-10.00 sec 9.31 MBytes 78.4 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 98.4 MBytes 82.5 Mbits/sec sender
[ 4] 0.00-10.00 sec 98.3 MBytes 82.4 Mbits/sec receiver
iperf Done.
# ---
# 192.168.7.183:12335限速150Mbps
iperf3 -c 192.168.7.183 -p 12335 -t 10
# >>>
Connecting to host 192.168.7.183, port 12335
[ 4] local 192.168.7.53 port 65473 connected to 192.168.7.183 port 12335
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 30.8 MBytes 258 Mbits/sec
[ 4] 1.00-2.00 sec 17.3 MBytes 145 Mbits/sec
[ 4] 2.00-3.00 sec 17.1 MBytes 144 Mbits/sec
[ 4] 3.00-4.00 sec 17.1 MBytes 144 Mbits/sec
[ 4] 4.00-5.00 sec 17.0 MBytes 142 Mbits/sec
[ 4] 5.00-6.00 sec 17.3 MBytes 145 Mbits/sec
[ 4] 6.00-7.00 sec 17.2 MBytes 144 Mbits/sec
[ 4] 7.00-8.00 sec 17.1 MBytes 144 Mbits/sec
[ 4] 8.00-9.00 sec 17.2 MBytes 145 Mbits/sec
[ 4] 9.00-10.00 sec 17.2 MBytes 144 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 185 MBytes 155 Mbits/sec sender
[ 4] 0.00-10.00 sec 185 MBytes 155 Mbits/sec receiver
策略生效。
删除限速策略
./dpip qsch del dev dpdk0 root pfifo_fast
./dpip qsch del dev dpdk0 handle 1:0 parent root bfifo limit 10000000
./dpip qsch del dev dpdk0 handle 10:0 parent 1:0 pfifo limit 100000
./dpip qsch del dev dpdk0 handle 20:0 parent 1:0 tbf rate 80m burst 8000000 latency 2ms
./dpip qsch del dev dpdk0 handle 30:0 parent 1:0 tbf rate 150m burst 15000000 latency 2ms
除了限速,还可以实现 Ingress 方向控制、针对源IP或目标IP的访问控制与 UDP 协议分流转发相关配置等,详见: DPVS Traffic Control (TC)
最佳实践
基于Egress实现出入站分类限速
分类限速
场景说明
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.7.182:12334 rr synproxy
-> 192.168.7.27:12334 FullNat 100 0 0
TCP 192.168.7.182:12335 rr synproxy
-> 192.168.7.27:12335 FullNat 100 0 0
TCP 192.168.7.183:12335 rr synproxy
-> 192.168.7.95:12335 FullNat 100 0 0
针对上述的 VIP 和 RS 设置不同的限速策略:
- 双向不限速
- 192.168.7.27:12334: 双向不限速
- 针对VIP限制
- 192.168.7.182:12335: 出站/上传
150Mbps
(即 VIP 上传带宽) - 192.168.7.183:12335: 出站/上传
80Mbps
(即 VIP 上传带宽)
- 192.168.7.182:12335: 出站/上传
- 针对RS限制
- 192.168.7.27:12335: 限制入站
200Mbps
(即 RS 下载带宽) - 192.168.7.95:12335: 限制入站
250Mbps
(即 RS 下载带宽)
- 192.168.7.27:12335: 限制入站
配置方式
添加限速
export PATH=/usr/local/dpvs-1.9.2/bin:$PATH
dpip link set dpdk0 tc-egress on
dpip qsch add dev dpdk0 root pfifo_fast
dpip qsch add dev dpdk0 handle 1:0 parent root bfifo limit 10000000
dpip qsch add dev dpdk0 handle 10:0 parent 1:0 pfifo limit 100000
dpip qsch add dev dpdk0 handle 20:0 parent 1:0 tbf rate 200m burst 21000000 latency 2ms
dpip qsch add dev dpdk0 handle 30:0 parent 1:0 tbf rate 250m burst 26000000 latency 2ms
dpip qsch add dev dpdk0 handle 40:0 parent 1:0 tbf rate 150m burst 16000000 latency 2ms limit 30000000
dpip qsch add dev dpdk0 handle 50:0 parent 1:0 tbf rate 80m burst 9000000 latency 2ms limit 8000
dpip cls add dev dpdk0 qsch root handle 0:1 match pattern 'tcp,oif=dpdk0' target 1:
dpip cls add dev dpdk0 qsch 1: handle 1:1 match pattern 'tcp,to=:12334,oif=dpdk0' target 10:
dpip cls add dev dpdk0 qsch 1: handle 1:2 match pattern 'tcp,to=192.168.7.27:12335,oif=dpdk0' target 20:
dpip cls add dev dpdk0 qsch 1: handle 1:3 match pattern 'tcp,to=192.168.7.95:12335,oif=dpdk0' target 30:
dpip cls add dev dpdk0 qsch 1: handle 1:4 match pattern 'tcp,from=192.168.7.182:12335,oif=dpdk0' target 40:
dpip cls add dev dpdk0 qsch 1: handle 1:5 match pattern 'tcp,from=192.168.7.183:12335,oif=dpdk0' target 50:
查看策略
dpip qsch show dev dpdk0
dpip cls show dev dpdk0 qsch root
dpip cls show dev dpdk0 qsch 1:
删除策略
dpip qsch del dev dpdk0 root pfifo_fast
dpip qsch del dev dpdk0 handle 1:0 parent root
dpip qsch del dev dpdk0 handle 10:0 parent 1:0
dpip qsch del dev dpdk0 handle 20:0 parent 1:0
dpip qsch del dev dpdk0 handle 30:0 parent 1:0
dpip qsch del dev dpdk0 handle 40:0 parent 1:0
dpip qsch del dev dpdk0 handle 50:0 parent 1:0
验证测试
Uploading to 192.168.7.182:12334 ...
# iperf3 -c 192.168.7.182 -p 12334 -t 10
Connecting to host 192.168.7.182, port 12334
[ 4] local 192.168.7.53 port 61150 connected to 192.168.7.182 port 12334
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 91.0 MBytes 763 Mbits/sec
[ 4] 1.00-2.00 sec 95.6 MBytes 802 Mbits/sec
[ 4] 2.00-3.00 sec 93.3 MBytes 782 Mbits/sec
[ 4] 3.00-4.00 sec 82.7 MBytes 693 Mbits/sec
[ 4] 4.00-5.00 sec 84.5 MBytes 709 Mbits/sec
[ 4] 5.00-6.00 sec 84.5 MBytes 709 Mbits/sec
[ 4] 6.00-7.00 sec 96.8 MBytes 812 Mbits/sec
[ 4] 7.00-8.00 sec 86.0 MBytes 722 Mbits/sec
[ 4] 8.00-9.00 sec 96.5 MBytes 810 Mbits/sec
[ 4] 9.00-10.00 sec 100 MBytes 839 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 911 MBytes 764 Mbits/sec sender
[ 4] 0.00-10.00 sec 911 MBytes 764 Mbits/sec receiver
iperf Done.
# ---
Downloading from 192.168.7.182:12334 ...
# iperf3 -c 192.168.7.182 -p 12334 -t 10 -R
Connecting to host 192.168.7.182, port 12334
Reverse mode, remote host 192.168.7.182 is sending
[ 4] local 192.168.7.53 port 61161 connected to 192.168.7.182 port 12334
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 94.3 MBytes 791 Mbits/sec
[ 4] 1.00-2.00 sec 90.2 MBytes 756 Mbits/sec
[ 4] 2.00-3.00 sec 92.5 MBytes 776 Mbits/sec
[ 4] 3.00-4.00 sec 94.3 MBytes 791 Mbits/sec
[ 4] 4.00-5.00 sec 95.6 MBytes 802 Mbits/sec
[ 4] 5.00-6.00 sec 92.8 MBytes 778 Mbits/sec
[ 4] 6.00-7.00 sec 92.2 MBytes 774 Mbits/sec
[ 4] 7.00-8.00 sec 95.7 MBytes 802 Mbits/sec
[ 4] 8.00-9.00 sec 94.5 MBytes 793 Mbits/sec
[ 4] 9.00-10.00 sec 95.4 MBytes 801 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 938 MBytes 787 Mbits/sec 0 sender
[ 4] 0.00-10.00 sec 938 MBytes 787 Mbits/sec receiver
iperf Done.
# ---
Uploading to 192.168.7.182:12335 ...
# iperf3 -c 192.168.7.182 -p 12335 -t 10
Connecting to host 192.168.7.182, port 12335
[ 4] local 192.168.7.53 port 61179 connected to 192.168.7.182 port 12335
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 38.6 MBytes 324 Mbits/sec
[ 4] 1.00-2.01 sec 22.8 MBytes 191 Mbits/sec
[ 4] 2.01-3.01 sec 20.1 MBytes 168 Mbits/sec
[ 4] 3.01-4.01 sec 27.3 MBytes 229 Mbits/sec
[ 4] 4.01-5.01 sec 18.7 MBytes 157 Mbits/sec
[ 4] 5.01-6.00 sec 27.3 MBytes 230 Mbits/sec
[ 4] 6.00-7.00 sec 20.1 MBytes 169 Mbits/sec
[ 4] 7.00-8.00 sec 23.4 MBytes 197 Mbits/sec
[ 4] 8.00-9.00 sec 22.2 MBytes 186 Mbits/sec
[ 4] 9.00-10.00 sec 20.2 MBytes 170 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 241 MBytes 202 Mbits/sec sender
[ 4] 0.00-10.00 sec 241 MBytes 202 Mbits/sec receiver
iperf Done.
# ---
Downloading from 192.168.7.182:12335 ...
# iperf3 -c 192.168.7.182 -p 12335 -t 10 -R
Connecting to host 192.168.7.182, port 12335
Reverse mode, remote host 192.168.7.182 is sending
[ 4] local 192.168.7.53 port 61188 connected to 192.168.7.182 port 12335
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 31.1 MBytes 260 Mbits/sec
[ 4] 1.00-2.00 sec 17.5 MBytes 146 Mbits/sec
[ 4] 2.00-3.00 sec 17.3 MBytes 145 Mbits/sec
[ 4] 3.00-4.00 sec 17.5 MBytes 148 Mbits/sec
[ 4] 4.00-5.00 sec 13.3 MBytes 111 Mbits/sec
[ 4] 5.00-6.00 sec 19.7 MBytes 166 Mbits/sec
[ 4] 6.00-7.00 sec 17.4 MBytes 146 Mbits/sec
[ 4] 7.00-8.00 sec 17.4 MBytes 146 Mbits/sec
[ 4] 8.00-9.00 sec 17.3 MBytes 145 Mbits/sec
[ 4] 9.00-10.00 sec 17.4 MBytes 145 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 186 MBytes 156 Mbits/sec 38 sender
[ 4] 0.00-10.00 sec 186 MBytes 156 Mbits/sec receiver
iperf Done.
# ---
Uploading to 192.168.7.183:12335 ...
# iperf3 -c 192.168.7.183 -p 12335 -t 10
Connecting to host 192.168.7.183, port 12335
[ 4] local 192.168.7.53 port 61197 connected to 192.168.7.183 port 12335
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 45.8 MBytes 383 Mbits/sec
[ 4] 1.00-2.00 sec 27.2 MBytes 228 Mbits/sec
[ 4] 2.00-3.00 sec 30.1 MBytes 253 Mbits/sec
[ 4] 3.00-4.00 sec 32.3 MBytes 271 Mbits/sec
[ 4] 4.00-5.00 sec 11.6 MBytes 97.6 Mbits/sec
[ 4] 5.00-6.00 sec 28.1 MBytes 236 Mbits/sec
[ 4] 6.00-7.00 sec 32.4 MBytes 272 Mbits/sec
[ 4] 7.00-8.00 sec 33.2 MBytes 277 Mbits/sec
[ 4] 8.00-9.00 sec 36.7 MBytes 309 Mbits/sec
[ 4] 9.00-10.00 sec 29.3 MBytes 246 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-10.00 sec 307 MBytes 257 Mbits/sec sender
[ 4] 0.00-10.00 sec 306 MBytes 257 Mbits/sec receiver
iperf Done.
# ---
Downloading from 192.168.7.183:12335 ...
# iperf3 -c 192.168.7.183 -p 12335 -t 10 -R
Connecting to host 192.168.7.183, port 12335
Reverse mode, remote host 192.168.7.183 is sending
[ 4] local 192.168.7.53 port 61205 connected to 192.168.7.183 port 12335
[ ID] Interval Transfer Bandwidth
[ 4] 0.00-1.00 sec 15.2 MBytes 128 Mbits/sec
[ 4] 1.00-2.00 sec 6.29 MBytes 52.8 Mbits/sec
[ 4] 2.00-3.00 sec 12.4 MBytes 103 Mbits/sec
[ 4] 3.00-4.00 sec 10.5 MBytes 88.5 Mbits/sec
[ 4] 4.00-5.00 sec 6.21 MBytes 52.3 Mbits/sec
[ 4] 5.00-6.00 sec 12.5 MBytes 105 Mbits/sec
[ 4] 6.00-7.00 sec 8.83 MBytes 73.8 Mbits/sec
[ 4] 7.00-8.00 sec 6.21 MBytes 52.1 Mbits/sec
[ 4] 8.00-9.00 sec 12.4 MBytes 104 Mbits/sec
[ 4] 9.00-10.00 sec 8.86 MBytes 74.0 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 103 MBytes 86.1 Mbits/sec 4590 sender
[ 4] 0.00-10.00 sec 99.5 MBytes 83.4 Mbits/sec receiver
iperf Done.
策略生效。
小结
本次操作的限速规则可以理解成下面的一种树状结构:
root qdisc
└─ pfifo_fast qdisc (dev dpdk0 parent 0:1)
├─ tbf qdisc (dev dpdk0 parent 1:2)
│ └─ cls match (dev dpdk0 parent 1:2 qdisc 10:) (pkttype 0x0800 prio 0 TCP,to=0.0.0.0-0.0.0.0:12334-12334,oif=dpdk0) (target 10:)
├─ tbf qdisc (dev dpdk0 parent 1:2)
│ └─ cls match (dev dpdk0 parent 1:2 qdisc 20:) (pkttype 0x0800 prio 0 TCP,to=192.168.7.27-192.168.7.27:12335-12335,oif=dpdk0) (target 20:)
├─ tbf qdisc (dev dpdk0 parent 1:3)
│ └─ cls match (dev dpdk0 parent 1:3 qdisc 30:) (pkttype 0x0800 prio 0 TCP,to=192.168.7.95-192.168.7.95:12335-12335,oif=dpdk0) (target 30:)
├─ tbf qdisc (dev dpdk0 parent 1:4)
│ └─ cls match (dev dpdk0 parent 1:4 qdisc 40:) (pkttype 0x0800 prio 0 TCP,from=192.168.7.182-192.168.7.182:12335-12335,oif=dpdk0) (target 40:)
├─ tbf qdisc (dev dpdk0 parent 1:5)
│ └─ cls match (dev dpdk0 parent 1:5 qdisc 50:) (pkttype 0x0800 prio 0 TCP,from=192.168.7.183-192.168.7.183:12335-12335,oif=dpdk0) (target 50:)
├─ pfifo qdisc (dev dpdk0 parent 1:6) (limit 100000)
└─ bfifo qdisc (dev dpdk0 parent 0:5) (cls 5 limit 10000000)
从上面的结构可以看出,即便流量方向都是 egress
,但你仍可以根据 from
或 to
的方式实现出入站的限速策略。
写在最后
生产环境中,应该将 ingress
和 egress
分开配置,但本篇主要仅做功能介绍,仅提供一个配置思路。
Reference
Traditional Elements of Traffic Control