趣谈网络协议---云中的网络QoS:邻居疯狂下电影,我该怎么办?
流量控制技术,可实现 QoS(Quality of Service),从而保障大多数用户的服务质量。
对于控制一台机器的网络的 QoS,只能控制出方向,通过 Shaping 控制出的流量。进入的方向无法控制,只能通过 Policy 将包丢弃。
控制网络的 QoS 有哪些方式?
在 Linux 下,可通过 TC(Traffic Control,流量控制器)控制网络的 QoS,主要通过队列的方式。
1、无类别排队规则(Classless Queuing Disciplines)
(1)pfifo_fast
pfifo_fast 分为三个先入先出的队列,称为三个 Band,优先级从高到底依次为 Band 0,Band 1,Band 2。根据网络包里的 TOS 确定该包进哪个队列。TOS 共4位,每位代表不同含义,16种类型。
通过命令行 tc qdisc show dev eth0,可输出结果 priomap,16个数字,对应 TOS 的 16 种类型,每个数字在 0 到 2 之间,对应不同的 Band。
(2)随机公平队列(Stochcastic Fair Queuing)
建立很多 FIFO 队列,TCP Session 计算 hash 值,根据 hash 值分配队列。队列的另一端,网络包会通过轮询策略从各个队列种取出发送。
两个 Session 的 hash 一样时,会共享一个队列,可能相互影响。hash 函数会经常变,从而 session 不会总相互影响。
(3)令牌桶规则(TBF,Token Bucket Filte)
所有的网络包排成队列发送,到了队头后,需要拿到令牌才能发送。令牌根据设定的速度生成。
当队列中没有包时,令牌还是以既定的速度生成,直到放满桶。设置桶的大小,可避免:长时间没有网络包发送时,积累了大量令牌,突然来了大量包,每个都能得到令牌,造成流量瞬增。
2、基于类别的队列规则(Classful Queuing Disciplines)
(1)分层令牌桶规则(HTB,Hierarchical Token Bucket)。HTB 往往是一棵树,可通过 TC 构建。
a、使用 TC 为某个网卡 eht0 创建一个 HTB 的队列规则,赋予句柄(1:),作为树的根节点。
对于网卡,需规定发送的速度。一般有两个速度可以配置:
- rate,一般情况下的速度。
- ceil,最高情况下的速度。
对于根节点 root class,这两个速度一样,rate = ceil = 100 kbps。
tc class add dev eth0 parent 1: classid 1:1 htb rate 100 kbps ceil 100 kbps
b、建立分支,即几个子 class,如图中的 3 个分支,句柄分别为(: 10)、(: 11)、(: 12)。
tc adisc add dev eth0 root handle 1: htb default 12
参数 default 12,表示默认发送给 1: 12。
三个分支的网卡速度分别为(rate = 30 kbps,ceil = 100 kbps),(rate = 10 kbps,ceil = 100 kbps),(rate = 60 kbps,ceil = 100 kbps)。
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 30 kbps ceil 100 kbps
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 10 kbps ceil 100 kbps
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 60 kbps ceil 100 kbps
三个 rate 叠加起来,是整个网卡允许的最大速度。
同一个 root class 下的子类可相互借流量,当前不使用这个分支时,可借给另一个分支。但是,如果在队列下创建一个 root class,而是直接创建三个 class,则它们之间不能相互借流量。
c、创建叶子队列规则,分别为 fifo 和 sfq(随机公平队列)。
tc qdisc add dev eth0 parent 1:10 handle 20: pfifo limit 5
tc qdisc add dev eth0 parent 1:11 handle 30: pfifo limit 5
tc qdisc add dev eth0 parent 1:12 handle 40: pfifo limit 10
基于队列规则,可通过 TC 设定发送规则:从 1.2.3.4 来,发送给 port 80 的包,从第一个分支 1:10 走;其他从 1.2.3.4 发送来的包从第二个分支 1:11 走;其他走默认分支。
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src 1.2.3.4 match ip dport 80 0xffff flowid 1:10
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src 1.2.3.4 flowid 1:11
如何控制 QoS ?
OpenvSwitch 支持两种:
1、对于流入的流量,可设置策略 Ingress policy。
ovs-vsctl set Interface tap0 ingress_policing_rate=100000
ovs-vsctl set Interface tap0 ingress_poliicing_burst=10000
2、对于发出的流量,设置 QoS 规则 Egress shaping,支持 HTB。
OpenvSwitch 的 QoS 如何工作?
拓扑图:
1、在 port 上可创建 QoS 规则。
一个 QoS 规则可有多个队列 Queue。
ovs-vsctl set port first_br [email protected] -- [email protected] create qos type=linux-htb other-config:max-rate=10000000 [email protected],[email protected],[email protected] -- [email protected] create queue other-config:min-rate=3000000 other-config:max-rate=10000000 -- [email protected] create queue other-config:min-rate=1000000 other-config:max-rate=10000000 -- [email protected] create queue other-config:min-rate=6000000 other-config:max-rate=10000000
创建一个 QoS 规则,对应 3 个 Queue。min-rate 就是 rate,max-rate 就是 ceil。通过交换机的网络包,需匹配流表规则后进入不同的队列。添加流表规则 Flow(first_br 是 br0 上的 port 5)。
ovs-ofctl add-flow br0 "in_port=6 nw_src=192.168.100.100 actions=enqueue:5:0"
ovs-ofctl add-flow br0 "in_port=7 nw_src=192.168.100.101 actions=enqueue:5:1"
ovs-ofctl add-flow br0 "in_port=8 nw_src=192.168.100.102 actions=enqueue:5:2"
2、测试。
单独测试。从 192.168.100.100,192.168.100.101,192.168.100.102 到 192.168.100.103 都能打满带宽。
三个一起测试,一起狂发网络包,按照 3: 1: 6 进行,正是根据配置的队列的带宽比例分配。
192.168.100.100,192.168.100.101 一起测试,带宽占用比例为 3:1,借用了 192.168.100.102 的带宽。