龙空技术网

KVM虚拟机网络资源限制

云技术 346

前言:

眼前看官们对“虚拟机带宽”都比较着重,大家都想要分析一些“虚拟机带宽”的相关资讯。那么小编也在网摘上收集了一些对于“虚拟机带宽””的相关资讯,希望看官们能喜欢,兄弟们快快来学习一下吧!

KVM虚拟机网络资源限制可以使用以下四种方案:

1 基于Open vSwitch做流量限制

2 通过TC限制虚拟机流量,TC是内核一套限制网络流量的机制;

3 通过Libvirt限制虚拟机流量;

4 通过iptables限制虚拟机流量。

为了对比网络流量限制效果,先介绍下不作流量限制的网络测试情况,测试环境中宿主机是千兆网卡,在不做限制的情况下,利用netperf测试虚拟机的结果如下:

# netperf -t TCP_STREAM -H 10.69.68.161 -p 12865 -l 60

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.69.68.156 (10.69.68.156) port 0 AF_INET

Recv Send Send

Socket Socket Message Elapsed

Size Size Size Time Throughput

bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 60.01 947.97

可以看到,基本可以达到线速。

使用TC(Traffic Control)限制虚拟机带宽

TC(Traffic Control)是Linux进行流量控制的工具,可以控制网络接口发送数据的速率。每个网络接口都有一个队列,用于管理和调度待发的数据。TC的工作原理就是通过设置不同类型的网络接口队列,从而改变数据包发送的速率和优先级,达到流量控制的目的。

Linux内核中支持的队列有:

1 TBF,Token Bucket Flow令牌桶过滤器,适用于流量整形。

2 Pfifo_fast,Third Band First In First Out Queue先进先出队列。

3 CBQ队列,分类的队列,用于实现精细的qos控制,配置复杂;

4 SFQ,Stochastic Fairness Queueing随机公平队列。

5 HTB,Hierarchy Token Bucket分层令牌桶,用于实现精细的qos控制,配置比CBQ简单些。

TC控制的主要是出口流量,入口流量不能通过TC控制。

通过TC限制网卡流量

1)通过TBF限制流出速度的例子:

#tc qdisc add dev eth0 root tbf rate 51200kbit latency 50ms minburst 200k burst 200k

限制网卡eth0流出速度为51200kbit,正确的设置方法,和minburst这个参数有很大的关系,不同的硬件环境和系统需要具体调试。

删除队列的命令:

tc qdisc del dev eth0 root tbf

修改队列的命令:

tc qdisc change dev eth0 root tbf rate 2200kbit latency 5000ms burst 1540

查看当前队列

tc -s -d qdisc ls

2)通过HTB队列,针对不同ip源限速

建立一个htb根队列:

tc qdisc add dev eth0 root handle 1: htb

建立一个父类1:1,速度为100mbit:

tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit

建立一个子类1:10,速度50mbit,这里的50mbit包含在1:1的100mbit中:

tc class add dev eth0 parent 1:1 classid 1:10 htb rate 50mbit ceil 50mbit

指定1:10是一个随机公平队列:

tc qdisc add dev eth0 parent 1:10 sfq perturb 10

通过过滤器,保证1.1.1.1这个ip通过1:1这个队列,优先级是2:

tc filter add dev eth0 protocol ip parent 1: prio 2 u32 match ip dst 1.1.1.1/32 flowid 1:1

通过过滤器,保证所有的其他ip通过1:10这个队列,优先级是50:

tc filter add dev eth0 protocol ip parent 1: prio 50 u32 match ip dst 0.0.0.0/0 flowid 1:10

通过TC限制虚拟机流量

通过TC的流量限制,限制虚拟机的流量,分为以下几个步骤:

1)建立队列;

2)建立分类;

3)建立过滤器,过滤虚拟机的ip;

4)绑定网卡。

下面是一个在宿主机上限制网卡流量的脚本:

#!/bin/bash

DEV=em1

tc qdisc del dev $DEV root

tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 1000mbit

tc class add dev $DEV parent 1: classid 1:1 cbq rate 100kbit allot 1500 prio 5 bounded isolated

tc filter add dev $DEV parent 1: protocol ip prio 16 u32 match ip src 10.0.0.161 flowid 1:1

tc qdisc add dev $DEV parent 1:1 sfq perturb 10

其中DEV是与虚拟机进行桥接的宿主机网卡名。测试结果如下:

# netperf -t TCP_STREAM -H 10.0.0.161 -p 12865 -l 60

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.0.0.161 (10.0.0.161) port 0 AF_INET

Recv Send Send

Socket Socket Message Elapsed

Size Size Size Time Throughput

bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 14.00 0.09

流量基本被限定到100k。

使用Libvirt限制虚拟机带宽

Libvirt的虚拟机流量限制,配置非常方便,在虚拟机配置文件中的网卡部分加入以下一段:

<bandwidth>

<inbound average='100' peak='50' burst='1024'/>

<outbound average='100' peak='50' burst='1024'/>

</bandwidth>

目标是限制进出带宽平均不超过100(kilobytes/second),最高不超过50(kilobytes/second),实际结果和预想的出入,测试结果如下:

流进几乎没有影响:

# netperf -H 10.0.0.161 -l 60

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.0.0.161 () port 0 AF_INET

Recv Send Send

Socket Socket Message Elapsed

Size Size Size Time Throughput

bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 60.01 820.58

流出是177.55M:

#netperf -H 10.0.0.167 -l 20

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.0.0.167 () port 0 AF_INET

Recv Send Send

Socket Socket Message Elapsed

Size Size Size Time Throughput

bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 20.02 177.55

Libvirt实际也是使用TC,虚拟机配置生效的时候,通过TC队列查看命令,可以看到TC队列:

tc -s -d qdisc ls

...

qdisc pfifo_fast 0: dev virbr0-nic root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

Sent 614 bytes 8 pkt (dropped 0, overlimits 0 requeues 0)

backlog 0b 0p requeues 0

qdisc htb 1: dev macvtap0 root refcnt 2 r2q 10 default 1 direct_packets_stat 0 ver 3.17

Sent 468 bytes 6 pkt (dropped 0, overlimits 0 requeues 0)

backlog 0b 0p requeues 0

qdisc sfq 2: dev macvtap0 parent 1:1 limit 127p quantum 1514b depth 127 flows 128/1024 divisor 1024 perturb 10sec

Sent 468 bytes 6 pkt (dropped 0, overlimits 0 requeues 0)

backlog 0b 0p requeues 0

qdisc ingress ffff: dev macvtap0 parent ffff:fff1 ----------------

Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)

backlog 0b 0p requeues 0

因为TC只能限制流出方向流量,不能限制流入方向,所以通过Libvirt限制流量,实际也只能限制流出方向。

使用iptables限制虚拟机的发包率

通过iptables限制虚拟机的流进方向发包率

在宿主机上用iptables来限制虚拟机的发包率,也是限制虚拟机流进流量的一个有效方案。

默认情况下,经过桥接的虚拟机网络流量不受宿主机的iptables控制,需要改动一个内核参数:

# echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables

然后添加两条iptables规则:

iptables -A FORWARD -d 10.0.0.161 -m limit --limit 100/sec --limit-burst 100 -j ACCEPT

#限定每秒100个数据包

iptables -A FORWARD -d 10.0.0.161 -j DROP

同时测试了下流进流出方向的流量,测试结果如下:

流进方向流量被限制的很明显,只有2.06M:

#netperf -H 10.20.102.161 -l 60

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.20.102.161 () port 0 AF_INET

Recv Send Send

Socket Socket Message Elapsed

Size Size Size Time Throughput

bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 60.01 2.06

流出方向流量被限制的也很明显,是213.50M

#netperf -H 10.0.0.167 -l 60

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.0.0.167 () port 0 AF_INET

Recv Send Send

Socket Socket Message Elapsed

Size Size Size Time Throughput

bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 60.23 213.50

通过iptables限制虚拟机的流进方向发包率

iptables -A FORWARD -s 10.0.0.161 -m limit --limit 100/sec --limit-burst 100 -j ACCEPT

#限定虚拟机源地址每秒100个数据包

iptables -A FORWARD -s 10.0.0.161 -j DROP

测试结果如下:

流进流量明显受到限制,是19.31M:

netperf -H 10.20.102.161 -l 60

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.20.102.161 () port 0 AF_INET

Recv Send Send

Socket Socket Message Elapsed

Size Size Size Time Throughput

bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 60.49 19.31

流出方向流量也受到限制是1.58M:

netperf -H 10.20.102.167 -l 60

MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.20.102.167 () port 0 AF_INET

Recv Send Send

Socket Socket Message Elapsed

Size Size Size Time Throughput

bytes bytes bytes secs. 10^6bits/sec

87380 16384 16384 60.63 1.58

iptables限制流量总结

1 通过iptables不能精确控制网速,只能控制包的个数,具体数对可以用mtu乘包的个数计算;

2 因为网络协议是双向的,因此iptables限制网络流量,即使配置的是单向的,实际对流出流进方向流量都有影响。

标签: #虚拟机带宽