陳云煒 李偉波 陳蔡濤 睿哲科技股份有限公司 廣州 510630 摘要:本文介紹了在OpenStack云平臺中利用Linux TC技術(shù)改進Neutron QoS功能,實現(xiàn)對虛擬機的IPv4/IPv6雙棧公網(wǎng)帶寬進行限而不影響其內(nèi)網(wǎng)帶寬的實現(xiàn)方案。 關鍵詞:云平臺、OpenStack、Neutron、QoS、IPv4、IPv6、IPv4/IPv6、雙棧、帶寬、TC 一、需求背景 在OpenStack云平臺中,網(wǎng)絡帶寬一般作為一種共享的基礎資源而存在;然而在業(yè)務場景中往往需求對這種共享的基礎資源按照一定的規(guī)則進行劃分和控制,以滿足不同業(yè)務的正常運作。尤其在公有云平臺中,當共享的網(wǎng)絡帶寬作為一種基礎資源進行銷售時,對于帶寬的按量劃分和控制更是一種剛需。OpenStack的Neutron網(wǎng)絡組件中原生提供了QoS(Quality of Service)帶寬控制功能,但原生的Neutron QoS組件實現(xiàn)的是基于端口的全流量帶寬控制,而在業(yè)務場景中往往需要的是基于IP的分類流量帶寬控制功能,甚至是對于IPv4/IPv6的帶寬分別進行控制。下文將介紹端口帶寬限制和IP帶寬限制這兩種方式的區(qū)別,以及不同模式的實現(xiàn)原理。 二、Neutron QoS架構(gòu)實現(xiàn) 1.Neutron QoS功能由來 OpenStack在Liberty版的Neutron中加入了網(wǎng)絡QoS功能,在這以前的版本中,對于虛機網(wǎng)絡帶寬的控制是通過Nova flavor來設置Hypervisor中的虛擬機端口帶寬(需要Hypervisor支持帶寬限制功能),這需要去維護很多個Flavor來保證不同的QoS帶寬需求,可見Flavor QoS非常不靈活。在Neutron中,QoS屬于Core plugin,根據(jù)所使用的ML2 mechanism driver的不同,其實現(xiàn)QoS功能的agent driver也不相同,每個mechanism driver下都按照自身網(wǎng)絡實現(xiàn)方式提供對于的QoS agent driver。在Linux系統(tǒng)上,無論使用怎樣的工具,本質(zhì)上都是使用Linux TC(Traffic Control)來做流量控制。TC利用隊列規(guī)定建立處理數(shù)據(jù)包的隊列,并定義隊列中的數(shù)據(jù)包被發(fā)送的方式, 從而實現(xiàn)對流量的控制。 2.Linux TC Linux操作系統(tǒng)中的流量控制器TC(Traffic Control)用于Linux內(nèi)核的流量控制,主要是通過在輸出端口處建立一個隊列來實現(xiàn)流量控制。接收包從輸入接口進來后,經(jīng)過流量限制丟棄不符合規(guī)定的數(shù)據(jù)包。Linux TC主要是在網(wǎng)卡設備輸出接口排列時進行處理和實現(xiàn)的,一般只能限制網(wǎng)卡發(fā)送的數(shù)據(jù)包,不能限制網(wǎng)卡接收的數(shù)據(jù)包,即“控發(fā)不控收”。這里的“發(fā)送”可以從二層網(wǎng)絡的數(shù)據(jù)包地址內(nèi)容直觀地體現(xiàn):數(shù)據(jù)包的源MAC地址為當前設備MAC地址的數(shù)據(jù)包為發(fā)送的數(shù)據(jù)包。 TC規(guī)則涉及到隊列(queue),分類器(class)和過濾器(filter)三個概念: 隊列(queue):用來實現(xiàn)控制網(wǎng)絡的收發(fā)速度。通過隊列,Linux可以將網(wǎng)絡數(shù)據(jù)包緩存起來,然后根據(jù)用戶的設置,在盡量不中斷連接(如TCP)的前提下來平滑網(wǎng)絡流量。常用的隊列有:TBF(令牌桶隊列)、CBQ(分類的隊列)、HTB(分層的令牌桶隊列)等。 分類器(class):用來表示控制策略。很多時候,我們很可能要對不同的流量實行不同的流量控制策略,這時候我們就可以用不同的class來表示不同的控制策略了。 過濾器(filter):用來將流量劃入到具體的控制策略中(即不同的class中)。在對不同的流量實行不同的控制策略時,利用filter對流量進行規(guī)則匹配,然后將匹配的流量劃入到對應的控制策略中。filter對流量的匹配可用U32過濾規(guī)則或iptables的set-mark功能來實現(xiàn)對IPv4或IPv6的流量進行分別匹配。 對于Linux TC的技術(shù)原理不在此處展開描述。 3.Neutron QoS架構(gòu)與原理 在中小型OpenStack云平臺中,一般多采用Open vSwitch(簡稱OVS)作為二層虛擬交換機,本文也只討論使用Open vSwitch作為Neutron二層虛擬交換機并且Neutron的ML2 mechanism driver采用openvswitch的情況。 在OpenStack計算節(jié)點中,虛擬機實例的網(wǎng)絡連接簡圖如下圖1:
圖 1 Neutron的QoS agent driver調(diào)用了Open vSwitch中的QoS功能,Open vSwitch中的QoS bandwidth limit功能是通過對 圖1 OVS br-int上的端口qvoXXX配置TC策略來實現(xiàn),由于Linux TC控發(fā)不控收的特性,因此在OVS的br-int網(wǎng)橋中只是限制了qvoXXX端口的發(fā)送包速率,即原生的QoS帶寬限制功能只是實現(xiàn)了對于虛擬機上行帶寬的限制。就截止到OpenStack Ocata版本來說,Neutron QoS agent driver(OVS)均是通過配置Open vSwitch中對應端口的ingress_policing_rate和ingress_policing_burst兩個參數(shù)來達到帶寬限制(實際是配置OVS bridge中的interface。對于OVS內(nèi)部創(chuàng)建的Internal類型虛擬網(wǎng)卡接口,會同時創(chuàng)建同名Interface和Port);而OVS中的ingress_policing_rate和ingress_policing_burst參數(shù)的實現(xiàn)實際上是通過在端口上配置Linux TC的HTB隊列來實現(xiàn)帶寬限制,但由于OVS中配置的HTB的filter規(guī)則是all,因此OVS中的bandwidth limit是對于端口通過的所有IPv4/IPv6雙棧流量實現(xiàn)同樣的帶寬限制,所以說原生的Neutron QoS是基于端口的全部流量帶寬限制。 三、改進Neutron QoS實現(xiàn)雙向公網(wǎng)帶寬限制 上文講到了Neutron通過Open vSwitch實現(xiàn)帶寬管理的基本原理,但這種基于端口的全流量帶寬限制,并且還是單向的帶寬限制,未能滿足大部分業(yè)務使用需求。因此需要分類流量帶寬控制功能,例如:對同一局域網(wǎng)內(nèi)虛擬機之間的IPv4/IPv6雙棧通信帶寬均不作限制或限制在一個比較大的值,而對于公網(wǎng)出口的IPv4/IPv6雙棧帶寬分別限制至一個較低的值。因此本文闡述一種基于Linux TC的HTB隊列改進Neutron QoS帶寬限制的方案,在此之前先簡單描述Linux TC的HTB隊列。 1.分層的令牌桶隊列HTB HTB(Hierarchical Token Bucket)分層令牌桶隊列其實是TBF(令牌桶過濾器)的一個增強版。TBF的隊列規(guī)則是:只允許以不超過設定的速率到來的數(shù)據(jù)包通過,但可以允許短暫的突發(fā)流量超過設定值。TBF 的實現(xiàn)在于一個緩沖器(桶),不斷地被一些叫做“令牌”的虛擬數(shù)據(jù)以特定速率填充著?!巴啊弊钪匾膮?shù)就是它的大小,也就是它能夠存儲令牌的數(shù)量,每個到來的令牌從數(shù)據(jù)隊列中收集一個數(shù)據(jù)包,然后從桶中被刪除。若數(shù)據(jù)流以等于令牌流的速率到達TBF,這種情況下每個到來的數(shù)據(jù)包都能對應一個令牌,然后可以無延遲地通過隊列。若數(shù)據(jù)流以小于令牌流的速度到達TBF,通過隊列的數(shù)據(jù)包只消耗了一部分令牌,剩下的令牌會在桶里積累下來直到桶被裝滿,剩下的令牌可以在需要以高于令牌流速率發(fā)送數(shù)據(jù)流的時候消耗掉,這種情況下會發(fā)生突發(fā)傳輸。若數(shù)據(jù)流以大于令牌流的速率到達TBF,這意味著桶里的令牌很快就會被耗盡,導致TBF中斷一段時間,稱為“越限”;如果數(shù)據(jù)包持續(xù)到來,將會發(fā)生丟包;因此TBF可以用來對數(shù)據(jù)通過過濾器的速率進行整形,令牌的積累可以導致越限的數(shù)據(jù)進行短時間的突發(fā)傳輸而不必丟包,但是持續(xù)越限的話會導致傳輸延遲直至丟包。TBF很精確,對于網(wǎng)絡和處理器的影響都很小,實現(xiàn)是針對數(shù)據(jù)的字節(jié)數(shù)進行的,而不是針對數(shù)據(jù)包進行,常用于網(wǎng)關限速。因為TBF是一種流量控制的無類算法,所以沒有對數(shù)據(jù)包進行分類傳輸?shù)墓δ堋?/p> HTB分層令牌桶,其工作原理和相關配置類似于TBF,并且擁有TBF的各項性能。HTB是一個分類的令牌桶過濾器,即可以對到達的流量進行分類,并且將分類的流量放到不同的令牌桶中進行流量整形。顧名思義,分層令牌桶具有層級關系,結(jié)合一張簡圖概略這種分層結(jié)構(gòu):
圖 2 如圖2所示,在HTB隊列中可以細分為多個class,并且子class還可以繼續(xù)細分class;而在父級class中添加filter(過濾器)并設定一些過濾規(guī)則,即可將流量進行分類并發(fā)送到子級class中繼續(xù)處理。過濾器(filter)是對數(shù)據(jù)包進行分類工具,用于把數(shù)據(jù)包分類并放入相應的子隊列,這些過濾器在分類的隊列規(guī)定內(nèi)部被調(diào)用。為了決定用哪個類(class)處理數(shù)據(jù)包,必須調(diào)用所謂的“分類器鏈”進行選擇,這個鏈中包含了這個分類隊列規(guī)定所需的所有過濾器。過濾器只能將數(shù)據(jù)包向“下”送入隊列操作,而不能用過濾器把數(shù)據(jù)包向“上”送;并且在使用HTB的時候,把所有的過濾器規(guī)則同時放在root class處會得到更好的效率。 2.Neutron QoS改進方案 在了解HTB隊列的特性后,我們即可使用原生Linux TC的HTB隊列對Neutron QoS功能進行改進,實現(xiàn)對虛擬機IPv4/IPv6雙棧公網(wǎng)帶寬的單獨限制。 首先,我們可以設計HTB的隊列模型如下圖3:
圖 3 圖3中的sfq是一個公平隊列,為了防止一個會話占用全部帶寬。在此方案中,我們設計了兩個HTB class,其中root class是一個帶寬很大的class,設計用來傳輸局域網(wǎng)內(nèi)的IPv4/IPv6流量;root class中指明的帶寬同時也是此網(wǎng)卡端口所允許的最大帶寬,其下的所有子class共享root class的帶寬。在root class下設置兩個帶寬比較小的class,用這兩個class隊列來分別限制公網(wǎng)IPv4/IPv6的流量帶寬。那么可以在創(chuàng)建HTB root qdisc的時候,指明默認的class隊列為公網(wǎng)帶寬的隊列,然后filter只需匹配內(nèi)網(wǎng)IPv4/IPv6的流量并交由root class處理即可,未匹配的流量均作為公網(wǎng)IPv4/IPv6流量進行帶寬限制。簡單的示例如下(假設不限制帶寬的內(nèi)網(wǎng)IPv4地址段為:10.0.0.0/8和192.168.0.0/16,以及內(nèi)網(wǎng)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隊列,我們可以對流量進行了分類,上述的簡單示例即可將標記為內(nèi)網(wǎng)之外的IPv4流量帶寬限制至10Mbps,以及將標記為內(nèi)網(wǎng)之外的IPv6流量帶寬限制至20Mbps。 接下來需要實現(xiàn)雙向的帶寬限制,上文中依然是對qvoXXX虛擬網(wǎng)卡設備配置Linux TC規(guī)則,因此依然是實現(xiàn)了對虛擬機上行流量的帶寬控制。由Linux TC“控發(fā)不控收”的特性,在需要對虛擬機的下行帶寬進行限制時,我們還需要對另外一個虛擬網(wǎng)卡設備配置Linux TC規(guī)則。在計算節(jié)點中,從屬于每臺虛擬機的虛擬網(wǎng)絡設備還有tapXXX、qbrXXX、qvbXXX,在此方案中選取在qvbXXX虛擬網(wǎng)卡上配置Linux TC規(guī)則,因為qvoXXX與qvbXXX是一對veth pair,具有相同的MAC地址,因此對于qvoXXX的發(fā)送則是qvbXXX的接收,而對于qvoXXX的接收則是qvbXXX的發(fā)送,恰好組成一組收發(fā)關系。而對qvbXXX配置的Linux TC的規(guī)則和對qvoXXX配置的規(guī)則類似。則有如下圖4的結(jié)構(gòu):
3.Neutron QoS的二次開發(fā) 上文中僅僅是從技術(shù)原理層面闡述了Neutron利用Linux TC實現(xiàn)對于虛擬機IPv4/IPv6雙棧雙向公網(wǎng)帶寬限制的可行方案,而方案的真正實施依然需要進行代碼上的一些工作。在Neutron的二次開發(fā)中,一般有兩種方式:一是直接基于源代碼進行修改開發(fā),這種方式對于后續(xù)的升級不夠友好;二是將功能作為一個新插件的形式進行開發(fā),這種方式會有較多的工作量。而在這次QoS功能的二次開發(fā)中,混合了兩種方式:一是直接修改Neutron Server的QoS Plugin,這里主要修改QoS Plugin的API數(shù)據(jù)處理與入庫部分的代碼,增加幾個相關的參數(shù)域;二是對于QoS agent,重寫一個QoS agent driver,使用新的QoS agent driver對qvbXXX和qvoXXX配置Linux TC規(guī)則。此方案直接使用了Neutron原生QoS功能的API處理流程以及消息隊列等方面的內(nèi)容,并且使用了原生QoS的虛擬機遷移重配置策略,降低了二次開發(fā)的工作量。 四、結(jié)語 以上對Neutron QoS功能的改進方案不僅可實現(xiàn)對虛擬機IPv4/IPv6雙棧的雙向帶寬區(qū)別私網(wǎng)與公網(wǎng)的流量進行分別帶寬限制,而且還可以基于Neutron的API靈活地進行修改和刪除。并且將帶寬限制的功能放到每個虛擬機所在的計算節(jié)點中,降低了傳統(tǒng)方式的在出口物理路由上配置acl規(guī)則帶來的繁瑣和降低了物理路由器的處理壓力。同時這種通過RESTFul API調(diào)用即可方便配置虛擬機帶寬的方式,可以很方便地與業(yè)務系統(tǒng)結(jié)合,靈活地提供不同的業(yè)務套餐。 轉(zhuǎn)載請注明出處。 |
|