編者按:關於容器網絡的解決方案業界已經有較多的討論,筆者無心繼續贅述。K8S及其網絡模型體現了鮮明的解耦設計思想,採用SDN技術實現K8S容器網絡,並與相應的生態組件造成SDN監管控一體化解決方案,能夠更好地提升整個系統的運營水平,更有效地提高企業的核心競爭力。本文擬拋磚引玉,從K8S的網絡實現入手,重點闡述SDN在容器網絡中的應用價值。歡迎業界聯繫雲杉同仁交流討論。web
綜述:K8S的基本機制是以「對象-控制器」架構模式爲基礎設計與實現的。組件API server與etcd的主要功能是實現對各類資源對象REST風格的增刪改查CRUD、盯Watch操做。組件controller-manager包括了各類內置控制器,其功能是確保整個系統處於預期的狀態。這種數據存儲與應用邏輯分離的模式是各功能組件實現無狀態服務架構的關鍵。K8S集羣針對基本操做單元Pod對象的處理主要是經過scheduler和kubelet實現的。實際上咱們能夠把scheduler看做是集羣層面的Pod對象控制器,把kubelet理解爲是節點層面Pod對象的建立與維護的控制器。docker
K8S場景下實現Pod互聯等的容器網絡特別是其數據轉發面遵循並適用網絡技術的通常性原則與實現。當前主流的容器網絡基本解決方案主要包括以Calico爲表明的基於經典的三層路由/Netfilter模型的實現,和以OpenShift的SDN實現爲表明的二層SDN/OVS模型的實現。而容器網絡的特殊性則主要體如今管理控制面實現、以及基於K8S擴展機制的SDN控制器雲原生部署等方面。K8S及其網絡模型體現了鮮明的解耦設計思想,不管是在K8S與網絡組件之間,仍是在容器網絡與Pod接入容器網絡之間等各方面。api
狹義地講SDN的核心技術主要包括數據轉發面特別是流表流水線的設計和相應的基於SDN控制器平臺的應用的設計與實現等。SDN控制器與各節點上的SDN代理相配合完成系統容器網絡的項目租戶、網絡子網路由、安全策略與服務、SLA/QoS的管控,以及監控可視化等各項操做。而CNI-Plugin的主要功能則是在kubelet建立Pod時將之掛接到容器網絡上。在K8S場景下,SDN的價值一樣體如今與各類生態組件的集成,實現一體化監管控解決方案,能夠更好地提高整個系統的運營水平。緩存
K8S集羣提供了以Pod爲基本操做單元的容器化應用的部署、維護、擴展等功能。主要由主節點上的API server、etcd、controller-manager、scheduler等,以及工做節點上的kubelet、容器運行時等功能組件構成。命令行kubectl能夠在主節點上也能夠部署在遠程運行,並經過API server調用與K8S交互。etcd集羣能夠採用與主節點分離的方式進行部署。另外,即便是主節點不參與業務Pod的分配與建立,也須要運行有一個kubelet實例。安全
kube-apiserver:API server經過Web Service端點處理函數的註冊與相應的訪問請求相關聯,實現REST機制對資源對象的增刪改查CRUD盯Watch等的操做功能,是系統對外訪問的統一入口。而K8S集羣內部各功能組件之間的互動也主要是經過API server 的Watch機制實現的。API server自己實現了無狀態服務架構模式。Web Service端點以API Group來管理分組和版本適配,分組包括核心組、擴展組、其餘的auto scaling組、metrics組等。而Proxy類API server接口的做用是代理REST請求,並轉發給相應節點的kubelet進行實際的操做處理。此外API server還提供有各類web hook擴展機制。服務器
etcd集羣:etcd是Go語言編寫的基於raft分佈式協議的高可用key-value存儲系統,做爲API server的後臺用於K8S存儲各類資源對象包括外部擴展定製資源對象(CRD – Custom Resource Definition)等配置與狀態信息,支持典型的消息發佈與訂閱機制,即Watch機制。etcd是K8S組件API server等實現無狀態服務架構的基礎。K8S集羣內任何對資源對象的增刪改查CRUD盯Watch操做等都經過API server的storage接口統一與etcd交互,各組件不會直接操做etcd。網絡
控制器模式是K8S各組件功能實現的基本框架,其基礎主要是基於etcd特性在API server內部實現的List-Watch機制和相應的client-go客戶端平臺庫函數。架構
List-Watch機制:該機制是基於etcd自己的Watch特性的,屬於API server對資源對象CRUD操做的體系化擴展。API server內部向etcd發起的Watch只能訂閱某個對象的建立、刪除事件,沒法設置過濾條件的,不能針對對象的屬性進行過濾;而API server實現對外部各類K8S功能組件發起的Watch請求的處理,並可以針對對象屬性進行過濾。在集羣運行過程當中組件向API server發送REST請求進行Watch訂閱,告訴API server對什麼資源對象及發生什麼樣的變化事件感興趣。而每個Watch操做的生命週期對應相應的HTTP REST請求的生命週期。負載均衡
庫函數client-go包括了訪問API server的客戶端,以及支持控制器實現所需的相關平臺機制List-Watch的客戶端informer和事件隊列workqueue等。這樣控制器的設計與實現只需專一應用邏輯,只需提供對象的事件回調函數和相應的隊列處理功能便可。框架
控制器架構模式:一個典型的控制器實現經過API server的List-Watch機制的客戶端informer與API server保持交互,跟蹤特定的資源對象的狀態與變化。對象變化的事件由informer調用相應的callback完成一些基本的處理,而後把相關的變動及對象信息放到workqueue裏面。控制器的應用邏輯實如今worker協程裏面。控制器可啓動多個worker協程來處理workqueue裏的對象事件。根據對象的指望狀態和當前系統的實際狀況進行相應的處理,並經過clients向API server發送行動請求。實際上也是經過對其餘相關下游資源對象的設置,以實現整個集羣向指望的狀態演進。此外,爲緩解各組件模塊對API server的訪問壓力、提升處理性能,控制器的內部實現也都採用了緩存機制的支持。
kube-controller-manager:K8S內置了一系列的控制器,基本上都是嵌入在controller-manager進程裏的。其中,Replication Controller的功能是確保集羣中有且僅有指定個數的Pod實例在運行,能夠經過調整RC中的副本數量來實現系統擴容或縮容,經過改變RC中的Pod模板來實現系統的滾動升級;Endpoints Controller中的Endpoints表示某個Service對應的全部Pod副本的訪問地址。此控制器的功能是經過監聽Service和對應的Pod副本的變化,負責生成和維護全部Endpoints對象。而工做節點上的kube-proxy就是經過監聽Service和Endpoints來配置相應的數據面實現相應的轉發和負載均衡功能。咱們能夠理解Endpoints Controller是K8S除Pod之外最重要的資源對象服務Service的集羣層面的控制器,而kube-proxy則是相應節點層面的控制器;Namespace Controller的功能是在後臺實現優雅地刪除某Namespace下的Service Account、RC、Pod等資源對象及此Namespace自己;Service Accounts Controller的功能是爲每一個Namespace維護一個默認的Service Account,並與Token Controller配合實現K8S集羣內部Pod訪問API server的認證功能。
K8S除自己內置的這些控制器外,也支持各類用戶自定義擴展。控制器能夠運行在K8S主節點上,也能夠運行在工做節點上;能夠運行在K8S集羣內,甚至運行在集羣外。
基本上K8S的資源對象與控制器都是相互對應、配合起來完成相應的功能的。但若是注意到的話,在controller-manager中並無針對Pod對象操做的控制器。實際上K8S決定把Pod放到哪一個節點上是由組件scheduler按照相應的策略決策的,而Pod的實際建立與維護是由kubelet完成的。因此咱們能夠理解爲scheduler是Pod集羣層面的控制器,kubelet則是Pod節點層面的控制器。
具體的來講,就是scheduler經過API server提供的Watch等接口,監聽並獲取到未調度的Pod和節點等的相關信息,經過過濾和優先級算分對節點篩選,選擇出最合適的節點,將Pod與此節點綁定,並把結果經過API server存儲到etcd中。在相應工做節點上的kubelet會去實際建立Pod的SandBox,調用CNI-Plugin進行相應的網絡配置掛接SandBox網絡名字空間到容器網絡上,建立和運行Pod所屬的init容器,最終建立和運行Pod的常規業務容器。
業界所謂的「There is no such thing called container networking」的說法更多的是從鏈接容器或Pod的網絡的通常性而言的。或者說從二層交換、三層路由轉發面的角度認爲鏈接容器的網絡與鏈接VM或BM等的網絡沒有本質的區別,即容器網絡特別是其數據轉發面仍遵循和適用網絡技術的通常性原則與實現。在這個層面上「容器網絡」有點相似「業務網絡」的概念之與物理網絡、虛擬網絡。但另外一方面,特別是從服務發現與負載均衡、管理模式與部署實施等的角度看,K8S的「容器網絡」是有其特殊性的。這主要體如今Pod生命週期到服務Service映射的動態性、SDN控制器雲原生模式部署、Pod掛接網絡的Plugin機制、以及安全策略的實現等方面。
針對當前主流的典型的容器網絡解決方案的分析,特別從數據轉發面特徵的角度,能夠認爲主要包括以Calico爲表明的基於經典的三層路由、Netfilter模型的實現,和以OpenShift的SDN及Neutron等爲典型表明的二層SDN/OVS模型的實現等。
三層路由/Netfilter模型:這類實現的優勢是網絡拓撲直觀易懂,扁平化結構,可擴展性強;容器間三層網絡隔離,不須要解決arp風暴問題;基於經典的、成熟的Netfilter/IPtables與Linux路由技術,包轉發與細粒度策略控制效率高等。
二層SDN/OVS模型:這類模式的轉發面是指Overlay二層和流表流水線設計與實現採用OVS,支持與各類Underlay模式的對接,可擴展實現DVR、廣播抑制特性等。這是當前比較典型和成熟的轉發面SDN模式方案;三層採用網絡名字空間的Linux路由器;安全策略以及NAT功能採用Netfilter/IPtables實現。
基於這種參考架構實現的方案的優勢是兼容了傳統網絡二層交換、三層路由、策略控制,能夠經過VLAN實現多租戶隔離;能夠採用典型的SDN套路對容器網絡的訪問作到細粒度控制;Overlay與Underlay的解耦設計,具有良好的混合雲、公有云的互聯能力;邏輯結構清晰,可適應不一樣場景和規模的網絡方案;有成熟的開發部署運維實踐經驗,穩定性通過生產環境驗證。這種類型的典型有OpenShitf的SDN轉發面方案,從某種角度來看它與Neutron模型的轉發面實現有不少相似的地方。
SDN容器網絡轉發面設計與實現的關鍵因素,特別是對於虛擬網絡方案而言,是選擇以Linux路由、Netfilter爲基礎,疊加基於OVS的多租戶支持等的SDN擴展。通常而言以OVS爲主體的SDN容器網絡解決方案,也是須要有三層互聯的功能配合的。而對於簡單扁平的三層容器網絡方案是能夠沒有二層OVS特性支持的。
相應的管理控制面的設計與實現主要也分爲基於BGP的分佈式管理控制面和基於SDN控制器的集中式管理控制面等。
K8S實現了典型的平臺與應用解耦的架構設計,提供了種針不一樣場景的擴展手段。除了kubelet的CNI-Plugin網絡掛接擴展外,與SDN容器網絡相關的擴展機制還有Operator模式和Aggregated Server模式。
Operator擴展模式:這種模式基於CRD機制和定製控制器實現。CRD是經過apiextensions-apiserver實現的。K8S集羣能夠動態定義並註冊用戶資源對象的schema,能夠像操做其餘內置資源對象同樣經過kubectl建立和訪問這些自定義對象。定製化控制器是用戶能夠在集羣內部署的定製開發的控制器,與定製化資源CRD等結合起來解決特定的應用問題。這種模式比較適合做爲SDN控制器雲原生部署的實施方案。
Aggregated-server擴展模式:這種方式的設計思路是經過增長API的擴展性,使K8S的用戶能夠擴展本身的API服務器,而不須要更改核心代碼。這種方式的優勢還在於能夠將開發工做分階段進行,新的API先在單獨的API服務器中開發,在穩定以後再把它集成在一塊兒。這種模式比較適合K8S監控系統的實現與部署。apiextensions-apiserver和替代早期版本K8S監控Heapster的metrics-server都是採用這種模式實現的。
庫函數client-go包括了訪問API server的客戶端,以及支持控制器實現所需的相關平臺機制List-Watch的客戶端informer和事件隊列workqueue等。這樣控制器的設計與實現只需專一應用邏輯,只需提供對象的事件回調函數和相應的隊列處理功能便可。
SDN控制器部署:K8S的SDN控制器的部署首先是建立SDN控制器和節點代理及CNI-Plugin部署和運行所需的服務帳號、角色和角色綁定。定義角色的訪問對象涉及哪些資源以及相應許可的操做。定義訪問的主體,即服務帳號,在特定名字空間中對相應角色、對象的訪問受權;而後以Deployment的方式在主節點上部署SDN控制器,可採用ConfigMap實現SDN控制器的相關配置管理;在每一個集羣工做節點上以DaemonSet的方式部署SDN代理,其中的CNI-Plugin安裝腳本容器負責在部署時安裝CNI-Plugin插件和相應的網絡配置等;以及經過CRD機制擴展相關的資源對象管理,實現相應的定製控制器進行K8S與SDN間的封裝、對接、適配。
kubelet:kubelet運行在集羣的每一個節點上,負責節點層面的Pod管理,週期執行Pod狀態的探測和上報功能,並提供相應的http服務代理的各類Pod或容器操做等功能。
在系統運行過程當中,kubelet的配置協程經過監聽Watch apiserver獲取分配給該節點的Pod。Pod工做協程池經過事件隊列接收從配置協程發來的Pod建立請求,調用相應的Pod管理、容器管理、設備管理等Manager模塊,最終經過容器運行時(以及dockershim)與Docker和CNI-Plugin互動完成Pod的建立。PLEG(Pod Lifecycle Event Generator)協程會持續地經過容器運行時監視本節點Pod的狀態,與相應的指望值進行比較,當發現狀態變化時生成相應事件給Pod工做協程實現相應的同步處理以保證Pod正常工做。
除監聽apiserver外,kubelet還支持監聽本地靜態配置文件建立Pod的功能。K8S集羣主節點上的apiserver、controller-manager、scheduler以及etcd就是以這種靜態Pod的方式由kubelet啓動運行的。
CNI-Plugin:Docker在建立容器的過程當中支持四種網絡模式。bridge模式會爲每一個容器分配網絡名字空間、IP地址等,並鏈接到本地的bridge上;host模式會共用主機的網絡名字空間;none模式會分配給容器獨立的網絡名字空間,但不會對容器進行相關的網絡配置;container模式是將新建立的容器和已經存在的某個容器共享網絡名字空間。
kubelet在建立Pod過程當中,首先經過容器運行時調用Docker以none模式建立Pod的SandBox,即pause容器,也就是在這個時間點kubelet調用CNI-plugin來進行相應的接口、IP、路由等網絡相關配置任務的,即掛接Pod到容器網絡上;而後調用Docker以container模式建立並運行init容器,共享SandBox的網絡名字空間;最終調用Docker也是以container模式建立常規業務容器,一樣共享SandBox的網絡名字空間。
因此CNI-Plugin是在kubelet建立Pod時被直接或經過dockershim調用來爲Pod的SandBox作網絡配置的。原則上CNI-Plugin不包含「容器網絡」主體項目租戶、網絡子網等的建立和管理等功能。從這個意義上咱們能夠理解CNI-Plugin的做用主要是kubelet在建立Pod時將之掛接到「容器網絡」上。
廣義地講SDN的基本功能是把可形式化的、繁瑣的各類網絡的監管控操做自動化以支持運維人員直觀便捷地獲取各類信息、執行各類操做、解決各類問題。狹義地講SDN的核心技術主要包括OpenFlow模式等交換機的轉發面流表流水線設計和相應的基於SDN控制器平臺的應用開發等方面。
SDN轉發面OpenFlow流表實際上能夠理解爲是對二層交換mac表、三層路由表、防火牆ACL策略表等的一種抽象。因此從原理上講OpenFlow/OVS交換機能夠特定化承載傳統的二層交換、三層路由、以及各類ACL等功能。SDN這種轉發面從特例到通常再到特例的演進過程當中,其價值更體如今能夠支持更多種變幻無窮的應用上,這就是SDN轉發面流表流水線設計的核心。一般SDN網絡解決方案的套路就是針對特定問題設計相應的流水線,並基於SDN控制器平臺開發相應的應用配合起來造成總體的解決方案。OpenShift的SDN容器網絡以及Neutron架構中的DVR、SFC就是比較典型的案例。而現階段多數SDN解決方案的轉發面一般是在經典的二層交換、三層路由基礎之上擴展細粒度流表設計實現相應的Overlay/Underlay轉發、策略、服務鏈功能等的。
SDN控制器主要包括平臺和應用兩個層面。平臺一般採用基於分佈式內存存儲的某開源方案,控制器集羣遵循CAP理論約束,支持基於任務和功能的負載分割,實現相應的二層交換、三層路由、拓撲管理、規則下發、狀態統計等功能。而各類應用的開發是與相應的轉發面、流表流水線設計相配合實現相應的網絡互聯、安全隔離、服務鏈、網絡SLA/QoS、以及監控分析可視化與閉環控制等功能。
SDN控制器的南向接口對接各類網元設備,能夠是物理的、也能夠是虛擬的;北向接口提供各類網絡主體的管理操做,能夠經過各類封裝適應不一樣的應用場景與不一樣的雲管平臺對接;西向接口能夠是與K8S各類相關資源對象的動態互動適配;而東向接口能夠做爲CNI-Server提供給kubelet的CNI-Plugin完成將Pod掛接到容器網絡的相關操做。
SDN這種架構適用於物理Fabric網絡的管控和/或服務器Overlay虛擬網絡的管控;適用於OpenStack、vSphere、K8S的網絡管控;適用於DCN、WAN,也適用於混合雲;適用於網絡主幹的管控、資源池的管控,也適用於邊緣互聯的管控。
一個典型的生產環境K8S和SDN容器網絡部署除劃分有各個網絡平面外,服務器節點也能夠拆分爲不一樣的功能組。其中主節點組承擔K8S集羣的Master角色,主要運行apiserver、controller-manager、scheduler組件等;基礎節點組屬於K8S集羣的工做節點,經過設置節點標籤,只用於部署系統基礎服務,包括註冊倉庫、三層路由、監控可視化、SDN控制器等;業務節點組也屬於工做節點,用於運行業務系統的各類應用容器Pod。若是以OpenStack爲參照的話,主節點組對應OpenStack的控制器節點;基礎節點組部分功能對應OpenStack的網絡節點;業務節點組則對應OpenStack的計算節點。
SDN解決方案包括在K8S場景下的應用能夠支持業務應用彈性擴展、更新迭代;自動化可提升系統運行穩定、有效的運維排障;細粒度控制能夠提升訪問和數據的安全性。採用SDN技術實現K8S容器網絡,SDN控制器基於K8S平臺擴展機制的雲原生部署,並與相應的生態組件造成SDN監管控一體化解決方案,能夠更好地提升整個系統的運營水平,更有效地提高企業的核心競爭力。