深入淺出新一代雲網絡——VPC中的那些功能與基於OpenStack Neutron的實現(二)-帶寬控制


在VPC功能實現第一篇中,簡單介紹了一下VPC網絡對租戶間隔離能力的提升以及基於路由提供的一系列網絡功能。在這一篇中,將繼續介紹VPC網絡中十分重要的一個內容:網絡帶寬的控制,共享以及分離。

首先是對第一篇中,端口轉發功能的樣例代碼,all-in-one http service 風格的實現。

核心功能:

find_router_ip = "ip netns exec qrouter-{router_id} ifconfig |grep -A1 qg- | grep inet | awk '{{print $2}}'".format(router_id=router_id)

(status, output) = commands.getstatusoutput(find_router_ip)

run_router_dnat = "ip netns exec qrouter-{router_id} iptables -t nat -D PREROUTING -d {router_gwip} -p {protocol} --dport {router_port} -j DNAT --to-destination {vm_ip}:{vm_port}".format(router_id=router_id,router_gwip=router_gwip,protocol=protocol,router_port=router_port,vm_ip=vm_ip,vm_port=vm_port)

(status, output) = commands.getstatusoutput(run_router_dnat)

Git repo地址

opencloudshare/Op_portforward

在readme中有簡單的介紹,通過最基本的rest請求即可實現功能。

Demo級的代碼,邏輯十分好理解,根據輸入的router_uuid ,找到 L3 節點上的命名空間,修改iptables實現轉發功能即可。

如果要在環境中正式使用,建議引入數據庫作為轉發記錄的存儲。引入了數據存儲后推薦加入額外的兩個流程:

1. 一致性

在通過commands或popen等執行系統命令的時候,通過不同的return status 及回顯作邏輯分支或try-exception。保證調用功能時的數據庫里的存儲規則和nat表上規則一致性。

如果nat規則的寫入和代碼里不同——不是直接在preforward主鏈而是在neutron-l3的子鏈里寫入,會發現執行某些網絡操作之后,nat規則會丟失,這是因為Neutron-l3-agent在router所控制的floating_ip發生變動時,自身會重寫nat表中自身子鏈的規則,這是neutron自己對l3數據一致性的保證。

2. 恢復

在l3節點所有配置清零重置后,能夠恢復之前各命名空間內的nat規則。這個功能簡單說就是一個讀取數據庫規則並解析執行的批量過程,也和Neutron的sync過程相似。

另外,從安全角度考慮,結合 keystone 加一層認證是更好的。

接下來進入帶寬控制的主題。

Neutron在以OVS組網時提供的 qos_policy功能實際上調用的是 ovs已有的對掛接在ovs-br上port的bandwidth limit,但只能控制 port 的出流量,是單向的。

如同:

ovs-vsctl set interface nic-id ingress_policing_rate=xxx
ovs-vsctl set interface nic-id ingress_policing_burst=xxx

底層都繞不開linux TC: Tc (Linux) - Wikipedia

TC規則涉及到隊列(queue),分類器(class)和過濾器(filter)三個概念.
隊列用來實現控制網絡的收發速度.通過隊列,linux可以將網絡數據包緩存起來,然后根據用戶的設置,在盡量不中斷連接(如TCP)的前提下來平滑網絡流量.需要注意的是,linux對接收隊列的控制不夠好,所以我們一般只用發送隊列,即“控發不控收”,。
class用來表示控制策略.很顯然,很多時候,我們很可能要對不同的IP實行不同的流量控制策略,這時候我們就得用不同的class來表示不同的控制策略了.
filter用來將用戶划入到具體的控制策略中(即不同的class中).正如前述,我們要對A,B兩個IP實行不同的控制策略(C,D),這時,我們可 用filter將A划入到控制策略C,將B划入到控制策略D,filter划分的標志位可用u32打標功能或IPtables的set-mark功能來實 現。

Tc控發不控收,注意發送指的是發出/上傳/出網/上行 的意思,因此原生ovs bandwidth limit在單純的對外提供數據的服務場景下是足夠適用的。但是在提供用戶上傳功能、雲主機軟件更新等需要下行流量的場景則無法約束,更別提當雲主機被入侵,攻擊者植入程序產生或作為肉雞發起對其它被攻擊對象的爆發性大規模下行流量了。在做了雙向的流量控制后,也更能分擔監控、抗D等系統的壓力。因此無論是用戶業務需求還是平台層考量,雙向QoS都是有意義的。

tc中的htb(令牌桶)算法簡單描述:

假如用戶配置的平均發送速率為r,則每隔1/r秒一個令牌被加入到桶中;
假設桶最多可以存發b個令牌。如果令牌到達時令牌桶已經滿了,那么這個令牌會被丟棄;
當一個n個字節的數據包到達時,就從令牌桶中刪除n個令牌,並且數據包被發送到網絡;
如果令牌桶中少於n個令牌,那么不會刪除令牌,並且認為這個數據包在流量限制之外;
算法允許最長b個字節的突發,但從長期運行結果看,數據包的速率被限制成常量r。對於在流量限制外的數據包可以以不同的方式處理:
它們可以被丟棄;
它們可以排放在隊列中以便當令牌桶中累積了足夠多的令牌時再傳輸;
它們可以繼續發送,但需要做特殊標記,網絡過載的時候將這些特殊標記的包丟棄。
注意:令牌桶算法不能與另外一種常見算法“漏桶算法(Leaky Bucket)”相混淆。這兩種算法的主要區別在於“漏桶算法”能夠強行限制數據的傳輸速率,而“令牌桶算法”在能夠限制數據的平均傳輸速率外,還允許某種程度的突發傳輸。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允許突發地傳輸數據直到達到用戶配置的門限,因此它適合於具有突發特性的流量。

在用原生tc代替neutron qos policy時,可以使用兩種模式:

1. 雲主機模式

即只對雲主機做流量控制,這里要提一下計算節點上雲主機連接網卡的原理。

在計算節點ip a的話,我們可以看到大量的虛擬網卡,在libvirt的虛機xml文檔中,可以明確看到雲主機與連接網卡的信息。

但除了tap設備外,計算節點上還有qvo,qvb,qbr。這些分別是什么呢。

openstack neutron 解釋的很詳細,可以直接參考。

不難歸納出 上行流量控制:

下行流量控制:

由前文,tc控制網卡設備的發出流量,所以當我們對上行或下行想做限制的時候,實際tc生效的設備只能是方向路徑上的設備。故雲主機模式的qos控制,可以分別對 qvo和 qvb設備進行規則寫入,即可實現上下行雙向控制。

tc qdisc del dev qvo233 root  //刪除原有規則
tc qdisc add dev qvo233 root handle 1: htb default 100 //創建htb隊列 
tc class add dev qvo233 parent 1: classid 1:1 htb rate 1gbit  //
tc qdisc add dev qvo233 parent 1:1 sfq perturb 10  //sfq隊列,避免單會話永占  
tc class add dev qvo233 parent 1: classid 1:100 htb rate 10mbit ceil 10mbit //子類100 帶寬10mb
tc qdisc add dev qvo233 parent 1:100 sfq perturb 10
tc class add dev qvo233 parent 1: classid 1:101 htb rate 100mbit ceil 100mbit
//子類101 帶寬100mb
tc qdisc add dev qvo233 parent 1:101 sfq perturb 10
tc filter add dev qvo233 protocol ip parent 1: prio 1 u32 match ip src 10.0.0.0/8 flowid 1:101
tc filter add dev qvo233 protocol ip parent 1: prio 1 u32 match ip src 172.16.0.0/12 flowid 1:101
tc filter add dev qvo233 protocol ip parent 1: prio 1 u32 match ip src 192.168.0.0/16 flowid 1:101

上面即是對qvo233這個設備的帶寬控制,實際為下行規則。默認子類為100 (10mb),但是當源地址為 10.0.0.0/8 和 172.16.0.0/12、192.168.0.0/16 時,使用子類101 (100mb),這樣保證私有地址間帶寬為百兆,而公網流量的帶寬為十兆。

為什么私有地址間的流量也要做限制?是因為即使是用戶VPC內雲資產產生的東西向流量,仍要占用計算節點物理網卡的實際帶寬,以及用於構建 VXLAN 網絡的交換機處理能力,考慮到雲資產較多的情景,因此是不得不注意的。

順帶一提,公網流量既包含 L3 節點的南北向流量,也包含L3節點上網關路由到實際雲資產所在宿主機的東西向流量。 帶寬在 L3 處更容易出現瓶頸。

2. VPC模式

對VPC與外網間的流量控制可以更靈活,在系列第一篇里介紹了VPC的路由,而這個路由實際上通過至少兩張網卡連接了租戶內網與外部網絡,

上圖左上角的路由,有兩張網卡,內連VPC的router_interface 與外連外部網絡的 router_gateway。

在 L3_agent上也可以看出來:

qg為外部網絡的網卡,qr為VPC內某一網絡的網關。

在限制vpc總體的上行流量時,實際將 tc 規則寫在 qg 即可,在限制VPC總體下行流量時,將tc 規則寫在 qr 即可。

這是VPC共享帶寬的一種思路。

如此實現了VPC內所有雲資產的公網流量共享,無需再限制雲主機單台的公網帶寬,其實這種在公有雲場景更滿足用戶預期,因為這樣用戶就不必為每一台VPC內的雲資產帶寬買單,只用支付總體帶寬費即可。

在實現了VPC內雲資源和外網流量的共享后,就有了新的問題,當發生資源搶占時該怎么辦。

如果任由搶占,那么我們使用的隨機序列算法就會生效,每隔10秒重新分配隊列。

但這對有良好業務規划的用戶來說並不合理,用戶可能需要某些業務能保持一定的獨占性。

所以我們通過對 不同子類帶寬的划分 以及 filter 規則的細化,即可實現源或目的不同轉發路徑的帶寬控制,對floating IP 以及 上一篇中的 NAT 功能同樣適用 。

上圖的樣例設計即可滿足 部分雲資產的帶寬獨占性,同時在總共享帶寬未滿的情況下,可以進行借用的場景功能。

系列下一篇 《深入淺出新一代雲網絡——VPC中的那些功能與基於OpenStack Neutron的實現(三)》中將給出實現QOS帶寬控制的類似開頭DNAT功能 rest api 的demo代碼,並展開下一塊內容——VPC網絡中實現互聯互通的路由技術與隧道技術,和場景案例。

 

系列上一篇 :http://www.cnblogs.com/opsec/p/6823437.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM