最大并發(fā)和每秒新增會(huì)話數(shù)測(cè)試_網(wǎng)絡(luò)安全云安全
在企業(yè)內(nèi)使用Kubernetes,對(duì)部署在Kubernetes上的應(yīng)用做訪問控制是比較基本的安全需求,不但要控制外部流量,而且各服務(wù)之間的流量也要兼顧。對(duì)此Kubernetes也給出了官方的解法——NetworkPolicy。然而,這還要仰仗各網(wǎng)絡(luò)驅(qū)動(dòng)的支持程度。而對(duì)于不同類型的網(wǎng)絡(luò)驅(qū)動(dòng)(如基于路由技術(shù)或隧道技術(shù))又各有各的解法和困難。文章中,我們將剖析主流Kubernetes網(wǎng)絡(luò)驅(qū)動(dòng)是如何支持NetworkPolicy的,同時(shí),分享面對(duì)公有云復(fù)雜需求摸索的經(jīng)驗(yàn)和企業(yè)落地Kubernetes私有云的解決思路。
在企業(yè)內(nèi)使用Kubernetes,其上部署的應(yīng)用是否需要嚴(yán)格的訪問控制,這個(gè)答案并不總是肯定的,至少支持訪問控制并不是方案選型時(shí)的優(yōu)先考慮要素。但對(duì)于我們行云創(chuàng)新來講,這種控制必不可少。因?yàn)?,我們提?duì)供的公有云業(yè)務(wù)允許任何個(gè)人和團(tuán)自由地開發(fā)和部署應(yīng)用到任意云端,那么為每位用戶的應(yīng)用提供安全可靠的訪問控制是一個(gè)十分基本的要求。相信我們對(duì)公有云復(fù)雜需求的摸索經(jīng)驗(yàn)和一些解決思路也將對(duì)眾多企業(yè)落地Kubernetes私有云非常有借鑒意義。
NetworkPolicy
Kubernetes提供了一種叫NetworkPolicy的對(duì)象,專門用來解決L3/L4訪問控制的問題。然而,它只定義了如何制定這些策略,而它們?nèi)绾蝸戆l(fā)揮作用卻還要仰仗各Kubernetes網(wǎng)絡(luò)插件的支持程度。而對(duì)于不同類型的網(wǎng)絡(luò)插件在支持NetworkPolicy方面又有各自的解法和面臨的挑戰(zhàn)。
在本次分享中,我們將在簡(jiǎn)單分析主流Kubernetes網(wǎng)絡(luò)插件如何支持NetworkPolicy之余,講述行云創(chuàng)新在實(shí)現(xiàn)訪問控制的過程中遇過到的那些挑戰(zhàn),以及它們又是如何被解決的。
首先我們來聊聊Kubernetes NeworkPolicy 對(duì)象 。
簡(jiǎn)單的說,NetworkPolicy是通過定義策略對(duì)選定Pod進(jìn)行網(wǎng)絡(luò)通訊控制的,這樣可以讓運(yùn)行在POD里的業(yè)務(wù)受到安全保護(hù)。Kubernetes早在1.6版本中就支持了NetworkPolicy對(duì)象,但只能通過Selector對(duì)Pod間通訊進(jìn)行控制,直至1.8版本在NetworkPolicyPeer對(duì)象支持IPBlock之后,才具備了通過指定IP段(CIDR)的方式對(duì)集群內(nèi)外訪問進(jìn)行全面控制。
下面我們分析一下NetworkPolicy是如何工作的。
上圖是NetworkPolicy對(duì)象的結(jié)構(gòu)平鋪圖。NetworkPolicy的作用域在Namespace內(nèi),它通過podSelector來確定哪些Pod將受這個(gè)policy約束。在一個(gè)NetworkPolicy對(duì)象中,可以設(shè)置多條NetworkPolicyEgressRule和NetworkPolicyIngressRule,分別用來做出口和入口的訪問控制。每條Rule由一組NetworkPolicyPeer和一組NetworkPolicyPort組成,意思比較明確,這組Peers的這些Ports被授予了訪問權(quán)限。
NetworkPolicyPeer則可以是兩類資源,其一是通過namespace selector和pod selector來篩選出Pod,另一則是前文提到過的IPBlock,它通過CIDR來指定。具體的配置方式可以參考官方文檔:https://kubernetes.io/docs/concepts/services-networking/network-policies。
從上圖我們可以看出,無論Ingress還是Egress,NetworkPolicy定義的是Pod之間或者Pod和某些CIDR之間的關(guān)系。從Kubernetes的設(shè)計(jì)理念和訪問實(shí)際發(fā)生的位置來看,這樣的設(shè)計(jì)實(shí)在再合理不過。然而,卻給實(shí)現(xiàn)層面增加了不少復(fù)雜度,甚至可能會(huì)影響到是否能夠讓方案落地實(shí)現(xiàn)。問題主要出在以下幾方面。
Pod網(wǎng)絡(luò)由各網(wǎng)絡(luò)插件提供的網(wǎng)絡(luò)驅(qū)動(dòng)支持,NetworkPolicy幾乎全部依賴這些網(wǎng)絡(luò)驅(qū)動(dòng)來實(shí)現(xiàn),而不同原理的網(wǎng)絡(luò)驅(qū)動(dòng)并不一定能實(shí)現(xiàn)NetworkPolicy的全部功能,而且難易程度也有所不同,即便到了今天,Kubernetes已經(jīng)發(fā)布了1.10,NetworkPolicy仍然沒有被所有主流網(wǎng)絡(luò)插件完整支持。
雖然Pod網(wǎng)絡(luò)由網(wǎng)絡(luò)驅(qū)動(dòng)實(shí)現(xiàn),但Service網(wǎng)絡(luò)卻是Kubernetes管理的,而Kubernetes應(yīng)用都是通過Service向外提供服務(wù)的,這中間的轉(zhuǎn)換也會(huì)對(duì)NetworkPolicy的實(shí)現(xiàn)有嚴(yán)重的影響。
在遵循NetworkPolicy的前提下,同時(shí)還要考慮以下各種情況如何應(yīng)對(duì):
Pod訪問API server的情形
基于網(wǎng)絡(luò)訪問的Probes(LivenessProbe和ReadinessProbe)
kube-proxy的--masquerade-all選項(xiàng)的開啟和關(guān)閉
NodePort類型的Service是否會(huì)受到影響
集群擴(kuò)容時(shí)NetworkPolicy的考慮等
接下來我們簡(jiǎn)單分析一下主流的網(wǎng)絡(luò)插件對(duì)NetworkPolicy的支持程度。
Kubernetes網(wǎng)絡(luò)插件
Calico
Calico提供的是一個(gè)基于路由的解決方案,也就是說Pod之間的交互將通過在Node上生效的各種路由規(guī)則來實(shí)現(xiàn)。如下圖所示。
Calico部署完成后,每臺(tái)Node上的Calico組件Felix會(huì)負(fù)責(zé)根據(jù)etcd中的配置來修改路由和iptables規(guī)則。Calico的組件BIRD則負(fù)責(zé)將這些路由策略分發(fā)到其他Node。Calico不但支持NetworkPolicy的特性,還支持了更多的安全策略,用戶可以通過calicoctl客戶端來配置,而這些特性也皆是通過iptables來實(shí)現(xiàn)的。
Flannel
Flannel的目標(biāo)在于解決Node之間的網(wǎng)絡(luò)互聯(lián)問題,它支持眾多實(shí)現(xiàn)方式,不僅包括VxLAN,IPIP等普遍的實(shí)現(xiàn)方式,還可以和不少公有云的網(wǎng)絡(luò)設(shè)施直接集成,對(duì)于在公有云上部署Kubernetes集群十分友好。然而它旨在解決網(wǎng)絡(luò)通訊的問題,因此并不支持NetworkPolicy。官方的建議是配合在這方面擅長(zhǎng)的Calico來使用,或者使用Canal。
Cilium
Cilium是一個(gè)十分有趣的項(xiàng)目,在組網(wǎng)方面它同時(shí)提供了基于路由的組網(wǎng)方式和基于VxLAN的Overlay網(wǎng)絡(luò)。而在訪問控制方面,它使用了BPF而非Netfilter。如下圖所示。
比起其他的網(wǎng)絡(luò)驅(qū)動(dòng),Cilium還比較年輕,尚未完全支持NetworkPolicy,但是它提供了CiliumNetworkPolicy對(duì)象用來提供更多的訪問控制特性,不只包括L3/L4的訪問控制,甚至涵蓋了L7的訪問控制,十分了得。
WeaveNet
WeaveNet提供了一種十分便利的方式在Kubernetes主機(jī)之間構(gòu)建一個(gè)Overlay網(wǎng)絡(luò),工作原理如下圖所示。
WeaveNet在Kubernetes上以DaemonSet的形式部署,每個(gè)Pod中包含兩個(gè)容器,分別是weave-kube和weave-npc。前者負(fù)責(zé)構(gòu)建網(wǎng)絡(luò),后者則是[n]etwork-[p]olicy-[c]ontroller。WeaveNet需要在每臺(tái)主機(jī)上創(chuàng)建一個(gè)bridge,作為主機(jī)上所有接入weave網(wǎng)絡(luò)的Pod的網(wǎng)關(guān),不同主機(jī)的bridge之間的數(shù)據(jù)流則會(huì)通過VxLAN協(xié)議轉(zhuǎn)發(fā),其他的數(shù)據(jù)流都會(huì)在主機(jī)上經(jīng)過SNAT從而進(jìn)入主機(jī)網(wǎng)絡(luò)。
對(duì)于NetworkPolicy,WeaveNet僅僅支持NetworkPolicyIngressRule和基于Selector的NetworkPolicyPeer,并不支持IPBlock類型的Peer。WeaveNet的實(shí)現(xiàn)方式和其他插件類似,通過從API Server監(jiān)聽NetworkPolicy的狀態(tài),修改主機(jī)上iptables策略和ipset來實(shí)現(xiàn)控制。
行云創(chuàng)新的選擇
我們行云創(chuàng)新是如何進(jìn)行選擇呢?
行云創(chuàng)新的公有云服務(wù)必須要具備跨多個(gè)云供應(yīng)商的能力來幫助用戶解除對(duì)單一云依賴,并構(gòu)筑成本優(yōu)勢(shì)。不同的云廠商,如阿里、華為、Azure、Ucloud、AWS等提供的網(wǎng)絡(luò)架構(gòu)和網(wǎng)絡(luò)能力是差異很大的, 這就決定了我們必然會(huì)面對(duì)十分復(fù)雜并且多樣的網(wǎng)絡(luò)環(huán)境,也應(yīng)該選擇一種與各公云的網(wǎng)絡(luò)架構(gòu)兼容最好的Kubernetes網(wǎng)絡(luò)方案。 先看看我們?cè)?jīng)在阿里上遇到的一個(gè)問題:
阿里云在網(wǎng)絡(luò)底層采用了ARP劫持技術(shù),所有網(wǎng)絡(luò)通訊(包括L2)都要到網(wǎng)關(guān)中轉(zhuǎn),自定義的“非法網(wǎng)絡(luò)” 將被丟棄,此時(shí)需要在阿里云平臺(tái)上的路由表中增加策略,才有可能成功。而其它家云在這些方面的行為又會(huì)大不相同,包括可能會(huì)存在路由表?xiàng)l目數(shù)量的限制。因此,基于路由技術(shù)的網(wǎng)絡(luò)插件,如Calico就不是最合適的選擇。
那么看看基于“隧道”技術(shù)的實(shí)現(xiàn)方案。同樣使用VxLAN技術(shù)的Flannel和WeaveNet要如何選擇呢?WeaveNet除了配置簡(jiǎn)單,它還有一個(gè)獨(dú)特的功能,那就是它并不要求所有主機(jī)必須處于full mesh network中,對(duì)于如下這種網(wǎng)絡(luò)拓?fù)渌材軌蛑С帧?
所以行云創(chuàng)新在公有云的實(shí)現(xiàn)上選擇了WeaveNet,但如同其它網(wǎng)絡(luò)插件一樣,在NetworkPolicy的支持上,它也無法完全滿足我們應(yīng)對(duì)的公有云環(huán)境下應(yīng)用控問控制需求。
對(duì)于我們來說,對(duì)NetworkPolicy最迫切的需求當(dāng)是支持IPBlock類型的NetworkPolicyPeer,這也是多集群管理的需要。試想多個(gè)微服務(wù)分別部署在不同地理位置、不同云商的集群中時(shí),IPBlock是Kubernetes給我們的唯一選擇。為什么WeaveNet只支持了通過Selector來定義NetworkPolicyPeer,IPBlock不能用類似的方法來實(shí)現(xiàn)嗎?那我們必須來分析一下。
weave-npc通過API Server監(jiān)聽NetworkPolicy的變化,并隨之改變配置。它在得到NetworkPolicyPeer對(duì)象后,根據(jù)其中的Selector篩選出符合條件的Pod,在得到Pod的IP地址后便可以在Pod所在主機(jī)iptables的Filter表中設(shè)置規(guī)則,接受來自這些地址的請(qǐng)求。當(dāng)然,實(shí)際的實(shí)現(xiàn)方式要更高效和復(fù)雜一點(diǎn)。那么基于IPBlock的NetworkPolicyPeer是否也能如此簡(jiǎn)單?答案當(dāng)然是否定的,至于原因還要從如何從集群外訪問到集群內(nèi)應(yīng)用說起,我們稱之為L(zhǎng)3接入方式。
Kubernetes以Service的方式管理L3接入,那么便可以通過LoadBalancer和NodePort直接從集群外訪問Service,這是比較常見的方式。但技術(shù)上來講,我們還可以打通集群外到ClusterIP的路由,來直接訪問Service的ClusterIP。照此原理,若大家希望從集群外直接訪問Pod網(wǎng)絡(luò)本身,通過直接路由的方式也是可以達(dá)成的,只不過要把Pod的IP暴露到全網(wǎng)中。
我們來看看自集群外訪問集群內(nèi)服務(wù)的簡(jiǎn)圖。
如上圖所示,無論是通過NodePort還是直接訪問Service ClusterIP的方式來接入,所有請(qǐng)求都會(huì)在進(jìn)入主機(jī)網(wǎng)絡(luò)時(shí)經(jīng)過DNAT,將目標(biāo)地址和端口轉(zhuǎn)換成Service對(duì)應(yīng)的Pod及其端口。而在經(jīng)由Weave bridge將請(qǐng)求轉(zhuǎn)發(fā)到Pod或者另一臺(tái)Node的Weave Bridge前(此時(shí)會(huì)通過隧道方式以VxLAN協(xié)議傳輸)會(huì)再做一次SNAT,將源地址修改為Weave Bridge的地址,這是Kubernetes確定的規(guī)則。
若我們?nèi)绶ㄅ谥茖?shí)現(xiàn)IPBlock,必然會(huì)面對(duì)這樣的難題。如上圖示例,Node2在接收到對(duì)PodB的請(qǐng)求時(shí),該請(qǐng)求已然在Node1上經(jīng)過了SNAT,其源地址已經(jīng)變成了Node1上Weave Bridge的地址,而非原始的源地址,此時(shí)再在Node2上執(zhí)行NetworkPolicy怕是會(huì)發(fā)生錯(cuò)誤,因?yàn)槲覀兿胍鲈L問控制的是原始的源地址。那么Kubernetes為何要在這個(gè)關(guān)鍵位置做SNAT?這是必須的嗎?
面對(duì)這個(gè)問題,我們的解決思路是,只要將針對(duì)每個(gè)Pod的NetworkPolicy應(yīng)用到所有的Node上而非僅僅在Pod所在的Node上即可,如同kube-proxy一樣。這樣,WeaveNet就可以全面支持單Kubernetes集群的NetworkPolicy了。此外,還有一個(gè)有趣的問題值得思考,Pod和Node之間的交互是否要受NetworkPolicy的約束[?這個(gè)問題我將在稍后和各位朋友加以分析。
接下來,我們來講述一個(gè)更加復(fù)雜的場(chǎng)景,也是行云創(chuàng)新要面對(duì)的場(chǎng)景,即將不同的微服務(wù)部署到不同地理位置、不同云商的Kubernetes集群,它們要如何相互訪問,又如何來做訪問控制呢?為了延續(xù)用戶在Kubernetes集群中的使用習(xí)慣和代碼習(xí)慣,在跨集群部署服務(wù)時(shí)維持Service和Kubernetes的服務(wù)發(fā)現(xiàn)機(jī)制是必須的(跨地理位置、跨云商的服務(wù)發(fā)現(xiàn)我們會(huì)在未來分享中詳細(xì)加以交流)。請(qǐng)看下圖。
從路由的角度來看,跨集群訪問并沒有什么特別之處,打通雙向路由即可。然而WeaveNet提供的是Overlay的解決方案,主機(jī)網(wǎng)絡(luò)上并不存在到Pod網(wǎng)絡(luò)的路由策略,所有的Pod到集群外的訪問均在從主機(jī)網(wǎng)卡發(fā)出時(shí)做了SNAT,故在Cluster2的Node上看到的請(qǐng)求源地址是Cluster1的Node地址,而非Pod A的地址,因此不能在Cluster2上簡(jiǎn)單地使用Pod A的地址通過IPBlock配置NetworkPolicy。
那么WeaveNet在此時(shí)做SNAT是必要的嗎?答案是肯定的。Pod網(wǎng)絡(luò)和主機(jī)網(wǎng)絡(luò)是相互隔離的,若他們要互相訪問,則必須要建立起路由(Calico的做法),或者在這種特殊架構(gòu)的前提下使用SNAT,使得Pod網(wǎng)絡(luò)保持獨(dú)立且不污染外部網(wǎng)絡(luò)環(huán)境。那么為了實(shí)現(xiàn)跨集群的訪問控制,我們必須對(duì)從Pod發(fā)出的請(qǐng)求區(qū)別對(duì)待,若是訪問其他集群的Service則不需要SNAT,否則依然要做SNAT。
至此,WeaveNet在行云創(chuàng)新跨地理位置、跨云商的場(chǎng)景下的連通和訪問控制就完全實(shí)現(xiàn)了,而且它最大限度地繼承了用戶對(duì)Kubernetes的使用習(xí)慣。至于如何使用和開發(fā)網(wǎng)絡(luò)插件,關(guān)鍵還是在于充分理解Kubernetes對(duì)Service和Pod網(wǎng)絡(luò)的定義。
最后,對(duì)于前文中提出的問題“Pod和Node之間的交互是否要受NetworkPolicy的約束?”來分享一下我們的思考。
從完整性的角度來講,一旦開啟了NetworkPolicy,那么所有的交互都應(yīng)當(dāng)受其控制,這其中自然包括Pod和Node之間的通訊。此時(shí)就需要考慮,當(dāng)Pod需要訪問API Server或者設(shè)置Probe策略時(shí),為它們開通訪問控制的責(zé)任是否要交給用戶?用戶是否有足夠的信息來完成這些設(shè)置?但從運(yùn)營(yíng)的角度來講,集群中所有的Node都在運(yùn)營(yíng)商的控制中,是安全的,也就可以認(rèn)為Pod和這些Node之間的通訊也是安全的。
當(dāng)然,在跨地址位置、跨云商的復(fù)雜公有云環(huán)境中部署業(yè)務(wù)其所面臨的挑戰(zhàn)和技術(shù)陷阱并非今天的分享就能夠介紹全面的。
Q&A
Q:根據(jù)https://cmgs.me/life/docker-network-cloud的測(cè)試,Weave網(wǎng)絡(luò)方案在性能上比其他方案差很多,這是真的嗎?
A:該文章測(cè)試的時(shí)候并未開啟fast-data-path,經(jīng)過我們的測(cè)試,在fast-data-path開啟的情況下,還是很可觀的。況且這個(gè)測(cè)試到今天已經(jīng)過去了2年時(shí)間,Weave社區(qū)一直以來還是很活躍的,相信未來只會(huì)更好。
Q:請(qǐng)問針對(duì)Azure和AWS在網(wǎng)絡(luò)方面有沒有遇到什么坑?好像前面只看到Aliyun的。
A:AWS有個(gè)“源/目標(biāo)地址檢查”,華為云也有類似功能,如果在你的網(wǎng)絡(luò)設(shè)計(jì)中云主機(jī)出來或進(jìn)去的IP與注冊(cè)的云主機(jī)IP不符,則需要把它關(guān)掉,另外如果不關(guān)“源/目標(biāo)”地檢查,也無法把目標(biāo)主機(jī)設(shè)置成路由的next-hop;Azure主要就是默認(rèn)動(dòng)態(tài)公網(wǎng)IP,需要調(diào)整成固定IP。另外要特別注意主機(jī)間copy數(shù)據(jù)的流量費(fèi)。
AWS上設(shè)置Kubernetes for Windows確實(shí)大費(fèi)周折,我們當(dāng)時(shí)和Kubernetes社區(qū)的Windows AIG的人一起搞了個(gè)方案,比較復(fù)雜。
Q:有沒有什么辦法為每個(gè)命名空間設(shè)置一個(gè)全局的NetworkPolicy,還是說必須要先創(chuàng)建命名空間才能定義NetworkPolicy(希望是就像ClusterRoleBinding一樣)?
A:至少現(xiàn)在還不可以,一般來說這不應(yīng)該是普遍的需求,因?yàn)槊總€(gè)應(yīng)用在一個(gè)Namespace下,而每個(gè)應(yīng)用的的訪問控制策略不大可能是相同的。從另一個(gè)方面看,以Kubernetes社區(qū)的風(fēng)格,任何普遍的需求最終都是會(huì)被實(shí)現(xiàn)的,而且速度很快。
轉(zhuǎn)載請(qǐng)注明來自夕逆IT,本文標(biāo)題:《最大并發(fā)和每秒新增會(huì)話數(shù)測(cè)試_網(wǎng)絡(luò)安全云安全》

還沒有評(píng)論,來說兩句吧...