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

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

nn

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

nn

核心功能:

find_router_ip = "ip netns exec qrouter-{router_id} ifconfig |grep -A1 qg- | grep inet | awk {{print $2}}".format(router_id=router_id)nn(status, output) = commands.getstatusoutput(find_router_ip)nnrun_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)nn(status, output) = commands.getstatusoutput(run_router_dnat)n

nn

Git repo地址

nnopencloudshare/Op_portforwardnn

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

nnnn

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

nn

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

nn

1. n一致性

nn

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

nn

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

nn

2. n恢復

nn

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

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

nnnn

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

nn

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

如同:

ovs-vsctl set interface nic-id ingress_policing_rate=xxxnovs-vsctl set interface nic-id ingress_policing_burst=xxxn

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

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

nnnn

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

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

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

nnnn

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

nn

1. n雲主機模式

nn

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

nn

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

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

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

nn

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

下行流量控制:

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

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

上面即是對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 處更容易出現瓶頸。

nnnn

2. nVPC模式

nn

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

nn

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

在 L3_agent上也可以看出來:

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

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

nn

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

nn

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

nn

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

nn

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

nn

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

nn

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

nnnn

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

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

系列上一篇 :深入淺出新一代雲網路--VPC中的那些功能與基於OpenStack Neutron的實現(一) - 知乎專欄

微信:

這兒分享雲計算相關的原創技術實踐和項目經驗,還有各種在雲、雲安全方面搞出的大新聞、趣事兒。


推薦閱讀:

雲諾(Yunio)與 Dropbox 有什麼差別?
有了解移動邊緣計算(MEC)的大神么,在網上搜到的不詳細?
數字化革命來襲,公司應該如何應對?
有哪些值得推薦的雲辦公平台?
雲主機商 會不會偷我的代碼?

TAG:OpenStack | 云计算 | 云平台 |