首页 > 科技 > IT > 正文

OpenStack实现虚拟机IPv4/IPv6双栈带宽控制的方法
2018-10-23 09:37:14   来源:第一新闻网   评论:0 点击:

陈云炜 李伟波 陈蔡涛
  
睿哲科技股份有限公司 广州 510630
  
  摘要:本文介绍了在OpenStack云平台中利用Linux TC技术改进Neutron QoS功能,实现对虚拟机的IPv4/IPv6双栈公网带宽进行限而不影响其内网带宽的实现方案。
  
  关键词:云平台、OpenStack、Neutron、QoS、IPv4、IPv6、IPv4/IPv6、双栈、带宽、TC
  
  一、需求背景
  
  在OpenStack云平台中,网络带宽一般作为一种共享的基础资源而存在;然而在业务场景中往往需求对这种共享的基础资源按照一定的规则进行划分和控制,以满足不同业务的正常运作。尤其在公有云平台中,当共享的网络带宽作为一种基础资源进行销售时,对于带宽的按量划分和控制更是一种刚需。OpenStack的Neutron网络组件中原生提供了QoS(Quality of Service)带宽控制功能,但原生的Neutron QoS组件实现的是基于端口的全流量带宽控制,而在业务场景中往往需要的是基于IP的分类流量带宽控制功能,甚至是对于IPv4/IPv6的带宽分别进行控制。下文将介绍端口带宽限制和IP带宽限制这两种方式的区别,以及不同模式的实现原理。
  
  二、Neutron QoS架构实现
  
  1.Neutron QoS功能由来
  
  OpenStack在Liberty版的Neutron中加入了网络QoS功能,在这以前的版本中,对于虚机网络带宽的控制是通过Nova flavor来设置Hypervisor中的虚拟机端口带宽(需要Hypervisor支持带宽限制功能),这需要去维护很多个Flavor来保证不同的QoS带宽需求,可见Flavor QoS非常不灵活。在Neutron中,QoS属于Core plugin,根据所使用的ML2 mechanism driver的不同,其实现QoS功能的agent driver也不相同,每个mechanism driver下都按照自身网络实现方式提供对于的QoS agent driver。在Linux系统上,无论使用怎样的工具,本质上都是使用Linux TC(Traffic Control)来做流量控制。TC利用队列规定建立处理数据包的队列,并定义队列中的数据包被发送的方式, 从而实现对流量的控制。
  
  2.Linux TC
  
  Linux操作系统中的流量控制器TC(Traffic Control)用于Linux内核的流量控制,主要是通过在输出端口处建立一个队列来实现流量控制。接收包从输入接口进来后,经过流量限制丢弃不符合规定的数据包。Linux TC主要是在网卡设备输出接口排列时进行处理和实现的,一般只能限制网卡发送的数据包,不能限制网卡接收的数据包,即“控发不控收”。这里的“发送”可以从二层网络的数据包地址内容直观地体现:数据包的源MAC地址为当前设备MAC地址的数据包为发送的数据包。
  
  TC规则涉及到队列(queue),分类器(class)和过滤器(filter)三个概念:
  
  队列(queue):用来实现控制网络的收发速度。通过队列,Linux可以将网络数据包缓存起来,然后根据用户的设置,在尽量不中断连接(如TCP)的前提下来平滑网络流量。常用的队列有:TBF(令牌桶队列)、CBQ(分类的队列)、HTB(分层的令牌桶队列)等。
  
  分类器(class):用来表示控制策略。很多时候,我们很可能要对不同的流量实行不同的流量控制策略,这时候我们就可以用不同的class来表示不同的控制策略了。
  
  过滤器(filter):用来将流量划入到具体的控制策略中(即不同的class中)。在对不同的流量实行不同的控制策略时,利用filter对流量进行规则匹配,然后将匹配的流量划入到对应的控制策略中。filter对流量的匹配可用U32过滤规则或iptables的set-mark功能来实现对IPv4或IPv6的流量进行分别匹配。
  
  对于Linux TC的技术原理不在此处展开描述。
  
  3.Neutron QoS架构与原理
  
  在中小型OpenStack云平台中,一般多采用Open vSwitch(简称OVS)作为二层虚拟交换机,本文也只讨论使用Open vSwitch作为Neutron二层虚拟交换机并且Neutron的ML2 mechanism driver采用openvswitch的情况。
  
  在OpenStack计算节点中,虚拟机实例的网络连接简图如下图1:

\
图 1
  
  Neutron的QoS agent driver调用了Open vSwitch中的QoS功能,Open vSwitch中的QoS bandwidth limit功能是通过对 图1 OVS br-int上的端口qvoXXX配置TC策略来实现,由于Linux TC控发不控收的特性,因此在OVS的br-int网桥中只是限制了qvoXXX端口的发送包速率,即原生的QoS带宽限制功能只是实现了对于虚拟机上行带宽的限制。就截止到OpenStack Ocata版本来说,Neutron QoS agent driver(OVS)均是通过配置Open vSwitch中对应端口的ingress_policing_rate和ingress_policing_burst两个参数来达到带宽限制(实际是配置OVS bridge中的interface。对于OVS内部创建的Internal类型虚拟网卡接口,会同时创建同名Interface和Port);而OVS中的ingress_policing_rate和ingress_policing_burst参数的实现实际上是通过在端口上配置Linux TC的HTB队列来实现带宽限制,但由于OVS中配置的HTB的filter规则是all,因此OVS中的bandwidth limit是对于端口通过的所有IPv4/IPv6双栈流量实现同样的带宽限制,所以说原生的Neutron QoS是基于端口的全部流量带宽限制。
  
  三、改进Neutron QoS实现双向公网带宽限制
  
  上文讲到了Neutron通过Open vSwitch实现带宽管理的基本原理,但这种基于端口的全流量带宽限制,并且还是单向的带宽限制,未能满足大部分业务使用需求。因此需要分类流量带宽控制功能,例如:对同一局域网内虚拟机之间的IPv4/IPv6双栈通信带宽均不作限制或限制在一个比较大的值,而对于公网出口的IPv4/IPv6双栈带宽分别限制至一个较低的值。因此本文阐述一种基于Linux TC的HTB队列改进Neutron QoS带宽限制的方案,在此之前先简单描述Linux TC的HTB队列。
  
  1.分层的令牌桶队列HTB
  
  HTB(Hierarchical Token Bucket)分层令牌桶队列其实是TBF(令牌桶过滤器)的一个增强版。TBF的队列规则是:只允许以不超过设定的速率到来的数据包通过,但可以允许短暂的突发流量超过设定值。TBF 的实现在于一个缓冲器(桶),不断地被一些叫做“令牌”的虚拟数据以特定速率填充着。“桶”最重要的参数就是它的大小,也就是它能够存储令牌的数量,每个到来的令牌从数据队列中收集一个数据包,然后从桶中被删除。若数据流以等于令牌流的速率到达TBF,这种情况下每个到来的数据包都能对应一个令牌,然后可以无延迟地通过队列。若数据流以小于令牌流的速度到达TBF,通过队列的数据包只消耗了一部分令牌,剩下的令牌会在桶里积累下来直到桶被装满,剩下的令牌可以在需要以高于令牌流速率发送数据流的时候消耗掉,这种情况下会发生突发传输。若数据流以大于令牌流的速率到达TBF,这意味着桶里的令牌很快就会被耗尽,导致TBF中断一段时间,称为“越限”;如果数据包持续到来,将会发生丢包;因此TBF可以用来对数据通过过滤器的速率进行整形,令牌的积累可以导致越限的数据进行短时间的突发传输而不必丢包,但是持续越限的话会导致传输延迟直至丢包。TBF很精确,对于网络和处理器的影响都很小,实现是针对数据的字节数进行的,而不是针对数据包进行,常用于网关限速。因为TBF是一种流量控制的无类算法,所以没有对数据包进行分类传输的功能。
  
  HTB分层令牌桶,其工作原理和相关配置类似于TBF,并且拥有TBF的各项性能。HTB是一个分类的令牌桶过滤器,即可以对到达的流量进行分类,并且将分类的流量放到不同的令牌桶中进行流量整形。顾名思义,分层令牌桶具有层级关系,结合一张简图概略这种分层结构:

\
图 2
  
  如图2所示,在HTB队列中可以细分为多个class,并且子class还可以继续细分class;而在父级class中添加filter(过滤器)并设定一些过滤规则,即可将流量进行分类并发送到子级class中继续处理。过滤器(filter)是对数据包进行分类工具,用于把数据包分类并放入相应的子队列,这些过滤器在分类的队列规定内部被调用。为了决定用哪个类(class)处理数据包,必须调用所谓的“分类器链”进行选择,这个链中包含了这个分类队列规定所需的所有过滤器。过滤器只能将数据包向“下”送入队列操作,而不能用过滤器把数据包向“上”送;并且在使用HTB的时候,把所有的过滤器规则同时放在root class处会得到更好的效率。
  
  2.Neutron QoS改进方案
  
  在了解HTB队列的特性后,我们即可使用原生Linux TC的HTB队列对Neutron QoS功能进行改进,实现对虚拟机IPv4/IPv6双栈公网带宽的单独限制。
  
  首先,我们可以设计HTB的队列模型如下图3:

\
图 3
  
  图3中的sfq是一个公平队列,为了防止一个会话占用全部带宽。在此方案中,我们设计了两个HTB class,其中root class是一个带宽很大的class,设计用来传输局域网内的IPv4/IPv6流量;root class中指明的带宽同时也是此网卡端口所允许的最大带宽,其下的所有子class共享root class的带宽。在root class下设置两个带宽比较小的class,用这两个class队列来分别限制公网IPv4/IPv6的流量带宽。那么可以在创建HTB root qdisc的时候,指明默认的class队列为公网带宽的队列,然后filter只需匹配内网IPv4/IPv6的流量并交由root class处理即可,未匹配的流量均作为公网IPv4/IPv6流量进行带宽限制。简单的示例如下(假设不限制带宽的内网IPv4地址段为:10.0.0.0/8和192.168.0.0/16,以及内网IPv6地址段为:2001::/32):
  
  tc qdisc add dev qvoXXX root handle 1: htb default 100
  
  tc class add dev qvoXXX parent 1: classid 1:100 htb rate 10mbit
  
  tc qdisc add dev qvoXXX parent 1:100 sfq perturb 10
  
  tc class add dev qvoXXX parent 1: classid 1:101 htb rate 20mbit
  
  tc qdisc add dev qvoXXX parent 1:101 sfq perturb 10
  
  tc class add dev qvoXXX parent 1: classid 1:1 htb rate 10gbit
  
  tc qdisc add dev qvoXXX parent 1:1 sfq perturb 10
  
  tc filter add dev qvoXXX protocol ip parent 1: prio 1 u32 match ip dst 10.0.0.0/8 flowid 1:1
  
  tc filter add dev qvoXXX protocol ip parent 1: prio 2 u32 match ip dst 192.168.0.0/16 flowid 1:1
  
  tc filter add dev qvoXXX protocol ipv6 parent 1: prio 3 u32 match ip6 dst 2001::/32 flowid 1:1
  
  tc filter add dev qvoXXX protocol ipv6 parent 1: prio 3 u32 match ip6 dst ::/0 flowid 1:101
  
  通过HTB队列,我们可以对流量进行了分类,上述的简单示例即可将标记为内网之外的IPv4流量带宽限制至10Mbps,以及将标记为内网之外的IPv6流量带宽限制至20Mbps。
  
  接下来需要实现双向的带宽限制,上文中依然是对qvoXXX虚拟网卡设备配置Linux TC规则,因此依然是实现了对虚拟机上行流量的带宽控制。由Linux TC“控发不控收”的特性,在需要对虚拟机的下行带宽进行限制时,我们还需要对另外一个虚拟网卡设备配置Linux TC规则。在计算节点中,从属于每台虚拟机的虚拟网络设备还有tapXXX、qbrXXX、qvbXXX,在此方案中选取在qvbXXX虚拟网卡上配置Linux TC规则,因为qvoXXX与qvbXXX是一对veth pair,具有相同的MAC地址,因此对于qvoXXX的发送则是qvbXXX的接收,而对于qvoXXX的接收则是qvbXXX的发送,恰好组成一组收发关系。而对qvbXXX配置的Linux TC的规则和对qvoXXX配置的规则类似。则有如下图4的结构:

\
 
  3.Neutron QoS的二次开发
  
  上文中仅仅是从技术原理层面阐述了Neutron利用Linux TC实现对于虚拟机IPv4/IPv6双栈双向公网带宽限制的可行方案,而方案的真正实施依然需要进行代码上的一些工作。在Neutron的二次开发中,一般有两种方式:一是直接基于源代码进行修改开发,这种方式对于后续的升级不够友好;二是将功能作为一个新插件的形式进行开发,这种方式会有较多的工作量。而在这次QoS功能的二次开发中,混合了两种方式:一是直接修改Neutron Server的QoS Plugin,这里主要修改QoS Plugin的API数据处理与入库部分的代码,增加几个相关的参数域;二是对于QoS agent,重写一个QoS agent driver,使用新的QoS agent driver对qvbXXX和qvoXXX配置Linux TC规则。此方案直接使用了Neutron原生QoS功能的API处理流程以及消息队列等方面的内容,并且使用了原生QoS的虚拟机迁移重配置策略,降低了二次开发的工作量。
  
  四、结语
  
  以上对Neutron QoS功能的改进方案不仅可实现对虚拟机IPv4/IPv6双栈的双向带宽区别私网与公网的流量进行分别带宽限制,而且还可以基于Neutron的API灵活地进行修改和删除。并且将带宽限制的功能放到每个虚拟机所在的计算节点中,降低了传统方式的在出口物理路由上配置acl规则带来的繁琐和降低了物理路由器的处理压力。同时这种通过RESTFul API调用即可方便配置虚拟机带宽的方式,可以很方便地与业务系统结合,灵活地提供不同的业务套餐。

相关热词搜索:带宽 方法

上一篇:广播电视系统的IPv6升级和演进浅谈
下一篇:寓教于乐 新星贝机器人打造高品质教育

分享到: 收藏