如果通过tc来限制虚拟机网卡接收方向带宽呢,实际上使用tc对接收方向限制的不够好,使用tc ingress可以限制接收,但是功能不够多,而且会形成丢包问题。一般是采用将流量重定向到一个虚拟设备ifb上,再对虚拟设备ifb的发包方向来限制带宽,以此来达到限制接收方向带宽的目的。
对于虚拟机的网卡而言,同样也可以使用ifb设备,间接来限制接收方向的带宽,但是还有一种办法是通过限制虚拟机网卡的后端设备的发,来达到限制虚拟机网卡接收带宽的目的。
1、查找虚拟机某网卡对应的后端设备
我的方法比较笨,先是在主机上virsh dumpxml xxx可以查看生成虚拟机的xml文件,如下:
<interface type='bridge'> <mac address='99:13:3a:59:22:5c'/> <source bridge='br1'/> <target dev='vnet11'/> <model type='virtio'/> <alias name='net2'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/> </interface>
target dev 对应的就是后端设备,我们在主机上,ifconfig,就可以查到这个后端网卡设备。我们要限制虚拟机网卡的收,就可以限制这个后端网卡设备的发。
但很多情况下,由于路由问题,实际的业务流向并不一与后端设备。如,我的虚拟机环境中,ens3f0 端口的ip地址为 129.9.240.236,在物理主机上看,对应的后端设备是vnet11,我向129.9.240.236上发数据包时,通过sar命令查看,实际的数据流向却不是走的vnet11->ens3f0。如下所示:
在主机中查看:
sar -n DEV 1 Average: IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s Average: br1 25.49 0.00 1.36 0.00 0.00 0.00 0.00Average: eth0 57.46 1.29 3.86 0.26 0.00 0.00 24.45Average: vnet2 0.00 25.73 0.00 1.74 0.00 0.00 0.00 Average: eth1 71491.80 2447.85 105636.68 169.77 0.00 0.00 12.42Average: vnet11 0.00 25.73 0.00 1.74 0.00 0.00 0.00 Average: ovs-system 0.00 0.00 0.00 0.00 0.00 0.00 0.00Average: br0 57.42 1.25 3.07 0.26 0.00 0.00 0.00 Average: vnet12 2447.85 2763.77 169.77 101206.93 0.00 0.00 0.00 Average: vnet1 0.00 56.25 0.00 3.78 0.00 0.00 0.00
在虚拟机中查看:
sar -n DEV 1 08:22:26 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil 08:22:27 AM ens3f3 26.00 0.00 1.52 0.00 0.00 0.00 0.00 0.00 08:22:27 AM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 08:22:27 AM ens3f0 26.00 0.00 1.52 0.00 0.00 0.00 0.00 0.00 08:22:27 AM ens8 50.00 4.00 3.26 0.46 0.00 0.00 0.00 0.00 08:22:27 AM ens3f1 26.00 0.00 1.52 0.00 0.00 0.00 0.00 0.00 08:22:27 AM ens3f2 10305.00 8576.00 394693.92 598.61 0.00 0.00 0.00 0.00
可以看到实际的网络流量是eth1->vnet12->ens3f2。
那么在实际应用中,如果要是限制发向ip为129.9.240.236的业务流量带宽,就需要限制vnet12发出方向的带宽。
2、配置带宽限制策略
在主机上对vnet12后端设备进行限制,配置如下所以:
tc qdisc add dev vnet12 root handle 1: htb default 20 tc class add dev vnet12 parent 1: classid 1:1 htb rate 10000mbit tc class add dev vnet12 parent 1:1 classid 1:10 htb rate 2000mbit tc class add dev vnet12 parent 1:1 classid 1:20 htb rate 1000mbit tc class add dev vnet12 parent 1:1 classid 1:30 htb rate 500mbit tc filter add dev vnet12 protocol ip parent 1:0 prio 1 u32 match ip dport 10051 0xffff flowid 1:10
tc filter add dev vnet12 protocol ip parent 1:0 prio 1 u32 match ip dport 10052 0xffff flowid 1:20
tc filter add dev vnet12 protocol ip parent 1:0 prio 1 u32 match ip dport 10053 0xffff flowid 1:30
测试下,虚拟机接收端,开启三个接口,三个进程同时并发执行,如下:
root@ubuntu: python demo_server.py 3 3 process concurrent.... server 10051 server 10052 server 10053
发送端发送数据包,并统计时延时间,以及粗略计算下带宽值,结果如下:
root@ubuntu: python test.py 129.9.240.236 3 1 3 process concurrent.... bandwidth 155.74MB/s bandwidth 95.54MB/s bandwidth 52.78MB/s
实际结果,与我们期望的一致。