黃玉奇:華為CCE在混合云、大規模集群場景下的技術探索
杭州是一座極有包容性的城市,古韻清雅的街道景點隨處可見,現代建筑群設計感十足,傳統底蘊與現代科技被這座古城兼容并蓄,***融合。HDG華為開發者匯,就將杭州作為第四站,5位講師***揭秘華為的CloudOpera、PaaS、融合視頻3個生態圈,技術干貨無私分享,聽眾疑問現場解答,思想的小火花一直在碰撞,參會的開發者大呼過癮。
“一談到容器,很多友誼的小船說翻就翻了。”華為PaaS開發部高級工程師黃玉奇幽默地開了場。他著重向開發者介紹了Kubernetes在混合云、大規模場景下的集群管理訴求。
現場實錄如下:
這么熱的天,大家能趕到華為的開發者會,特別感謝大家。同時也感謝活動各位組織的伙伴們。我是華為CCE的黃玉奇,現在主要做華為CCE的設計開發的工作,同時也是Kubernetes社區小小的貢獻。華為CCE的全稱就是云、容器、引擎,簡單給大家介紹一下。今天跟大家一起分享的題目是華為CCE在混合云大規模場景下的一個技術探索。
分享主要從四塊說起,首先跟大家溫習一下什么是容器,什么是容器服務。第二個我們看一下現在有一個開源容器的明星,Kubernetes一些經典的應用模型,包括它的架構。第三塊是我們CEE在華為IT系統里面的實踐,以及面臨的一些挑戰。***會跟大家分享一下我們在Kubernetes社區里面貢獻的集群聯邦的技術細節。
大家看這幅圖有點蒙了,現在在我們小圈子里有一句話說,一言不合就要講容器,講容器的時候就會擺上一些大大的集裝箱,我不知道為什么。在60年代的之前全球的運輸主要以散貨的運輸方式來進行的,大部分的時間都集中在裝載、卸載,再裝載、再卸載上面。有人就會問了,我們為什么不能把這些貨物都集中放到一些大箱子里面,我們只來做這些箱子的運輸。伴隨著這個問題,集裝箱技術就出現了,集裝箱技術出現之后,大約節省了六分之一的人力和三分之一的運輸時間。
這里我們就做了一個容器技術和集裝箱的對比,為什么我們總喜歡把容器和集裝箱放在一起比。***個它是一個內容無關性,集裝箱的東西都有這個特征,內容無關性。我不管你這個箱子里放的什么物品,或者對我們容器技術來說我不管你放的什么負載或者什么應用。第二個就是硬件無關性,我的集裝箱可以通過火車、卡車或者輪船來運輸,當然我們的容器也可以跑在物理機、虛擬機、筆記本或者服務器當中。
***一個我想提的是它的效率問題,集裝箱能解決我們運輸的效率,容器它能解決我們應用的開發部署,包括運維的效率。
說到容器,我們不得不說容器里面的一個明星了,Docker,在我理解Docker并不是在它的技術上有多么的先進,而是說它給我們帶來一個統一的認識,我們可以通過Docker鏡像來實現應用的開發、部署、運維,最終它的這種極大的便利性,形成一個穩定的Docker生態,其實它最有價值的地方就是Docker生態。我們有一個問題就要說了,任何一個復雜的應用并不是以獨立的Docker容器能夠解決問題的,通常是一組,或者是一堆的Docker容器相互協同,才能完成某一個特定的完整的應用站。這里我不得不說一個容器服務,一個可用的容器服務都需要哪些要素呢?***個就是基礎架構,我一個容器服務解決資源的編排,資源的管理,包括一些在外圍的負載均衡,服務的注冊發現,租戶方面的能力。第二個就是監控運維的能力,就是我的應用在容器服務商要能夠提供對容器應用,或者集群不同維度的狀態的監控。此外還有一些日志的分析,應用的升級。***一個就是外圍的支持,包括一些代碼庫,經銷商庫一些能力的支持。
當前不管在開源界,還是在國內外一些重大的IT廠商,都會有一些容器服務的產品,像開源的有Docker,在國內外有些大的IT廠商里面也有很多的容器的產品,華為CCE就是基于Kubernetes做的容器服務的產品。這里我重點想跟大家分享一下Kubernetes經典的模型和它的典型的架構。
Kubernetes其實是谷歌開源容器集群的環境系統,它構建在Docker的基礎之上,主要是為容器化的應用提供了應用的部署,服務的發現,擴容縮容一整套的功能。下面我們看一下Kubernetes里面基本的概念,從這個圖里面可以看到,節點上運行了Kubernetes大部分的控制面的主件,里面主要是KubernetesAPIserver、調度器,還有一些資源管理控制器。下面兩個是它的slive節點,slive節點就是應用真正運行的地方。它上面運行了Kubernetes控制面的兩個主件。在Kubernetes里面有一些應用的模型,這邊我有列。***個就是pod,pod它對應的Kubernetes里面一個最小的部署單元,它其實就是一組容器的集合。第二個想介紹一下的是副本控制器,主要就是包括我在KPI集群里面有固定數目的在運行。第三個就是service,service后端真實pod訪問的問題。還不得不提的是一個label的概念,因為在kps里面,各種資源之間的管理,或者它的觀點和查詢都是通過label來解決的。
我們來展開講一下Kubernetes里面的幾個基本概念,***個就是pod,大家聽的最多的就是pod的概念,pod在KPI里面是最小的部署調度的單元,它是一組容器的組合,不是一個單獨的容器。pod里面的容器它們共享這相同的網絡運營空間、IP地址,包括數據卷,所以在這個pod里面多個容器可以相互的訪問。這里就有一個問題了,pod需要手動上線嗎,或者在pod生命周期里面誰來維護pod的生命周期。這里面對應了Kubernetes的另外一個概念,叫做副本控制器,副本控制器通過label或者一組pod做一些關聯,它能維持在我的KPI集群里面一個固定數目的pod的運行。當我的pod的數量超過了我的副本控制器里面指定數量的時候,副本控制器就會揍掉一些,如果少的話,我就會重新再啟動一些。此外它能夠解決pod擴容和縮容的問題。這里面我要提到一下,創建一個IC的時候,我需要指定哪兩個東西,***個就是pod的模板,相當于是一個pod的描述文件。第二個就是label,label主要就是解決我的副本控制器跟pod之間的管理關系。在講副本控制器的時候我們也提到,pod會不斷的被副本控制器重新啟動,或者把它Q掉。也就是說我的pod在后端是不斷變化的,是一個動態的。那么我們怎么解決pod,或者我某一個應用對用戶訪問的問題,因為我在后臺是不斷變化的,Kubernetes有一個service的概念。
service的引用它就為了解決我的用戶對后端pod訪問的透明化,我只需要知道我的service在哪里,由service來將這個流量導向我后面支持的pod。我們可以簡單理解,它就是一個虛IP,做了一個LD。它可以把外部的流量進來之后,把這個流量按照一定的規則,對后臺支持的pod做了一個簡單的流量分發。當前KPI對service還是一個四層的LB。但是在Kubernetes在EDL版本,也引用了資源對象,主要是解決后端七層的LB的問題。在KPI集群里面我們這個服務,它的服務發現通過兩種方式。Kubernetes里面自帶了一個DNS的組建,解決了我們服務發現的問題。這是Kubernetes的三個很重要的概念,因為在我們后面講述集群聯邦的時候會用到這幾個概念。
下面主要想給大家一起看一下Kubernetes基礎的架構。前面我們說到了它是一個典型的(10:30)的結構,在節點上運行了很重要的一個組建,就是API的服務器,主要是對外提供服務,來供用戶對資源進行增查改查,包括words的操作。它后端對接的是一個CD,做私有化存儲。我還會有一些認證,授權的模塊,然后最終的用戶他的訪問流量是通過ACPI進入到我的APiservice里面。第二個主要組建就是調度器,調度器解決的問題主要就是,根據一些調度策略,來決定我的pod真正的被部署到哪個node上,它里面的調度策略是可插拔的調度策略。這里面主要有一些親和性,或者反親和的調度算法。第三個重要的控件的組建是控制器管理器,這里面主要是針對Kubernetes每種資源所做的控制器,它能夠相應Kubernetes里面的資源變化,因為每一個資源變化都對應了一個資源變化的事件,這個事件最終是由我的控制器管理器比別人的控制器去消費的,來做不同的動作。大概這里面的東西我給大家列舉一下,有node的控制器,副本的控制器,等等。控制面的組件,主要是解決了容器的生命周期管理的問題,包括我容器的啟動、創建、刪除、更新這些東西。Kubernetes本身也提供一個restAPI服務,會將這些運維服務通過自身的restAPI,供外面的用戶查詢。當前主要的應用場景是Kubernetes提供一個restAPI,***將所有的運維數據做一個不同維度的聚合。第二個slive節點上的控制件組件是pods組件,顧名思義這個pods主要是給pod做一些流量分發,主要是結合我們前面提到的service的概念,來運行的,來開展工作的。這里是Kubernetes的基礎架構,大家有點印象,因為我在后面講到Kubernetes聯邦集群的時候,可能會重復一下里面的一些概念。
我們可以看到Kubernetes會有很多線連到APIservice里面,這里面我要講一下Kubernetes里面有一個list-watch的機制,它主要是解決Kubernetes里面異步通信的問題。這個list-watch還是基于ECD的Kubernetes的能力,通過APIservice做了一層封裝,對外提供的。這里有一個簡單的例子,用戶創建一個應用之后,或者創建一個資源之后,會在APIservice里面有一個相應的資源,我就會有相應的資源,獲取到資源的變化,可以做一些相應的動作處理。這里就不展開了。
第三塊主要想講講CCE在基于Kubernetes這個開源的解決方案上,怎么來去實現在華為IT系統里面的技術挑戰。華為的CCE主要還是以Kubernetes,或者docker,以核心技術構建,主要想打通原有的在IaaS、PaaS或者CaaS這個端到端打通的融合方案。我們的愿景是能夠解決跨境應用的集中部署的管理,混合資源的編排,開發測試生產環境的一致性,再集成我們華為這么多年電信領域的中間件,或者把這個中間件做一些容器化的操作。
隨著業務的開展,現在我們華為CCE上了各種各樣的生產環境,我們也開始面臨越來越多來自生產環境上的挑戰。***個就是規模問題,這邊有一個統計,2015年的統計數據,我們中間件云里面,以DC為單位,我們業務量是快速增長的趨勢,這是一個規模的問題。第二個就是業務的頻繁發布,現在我們很多傳統業務的平臺不支持快速的迭代,就是說我們業務上線效率特別的低,希望能夠通過我們華為CCE,在基于容器基礎上,能夠解決他們業務頻繁發布的問題。第三個就是冗余部署,我們希望能夠解決一些同城雙活、混合云、異地容災這么一些問題。因為現在我們的應用是在VM下,希望通過容器來解決這個問題,提高我們資源利用率的問題。第三個就是容器化、微服務化的改造,這里是華為CCEKubernetes提供的基礎的能力,容器化管理部署的能力。
面臨的挑戰我們也做了很多的技術探索,我們在華為公司內部也做了一些Kubernetes的性能提升,包括調度啊,各方面的性能提升的技術探索。今天想跟大家分享的是探索的一個方面,就是Kubernetes聯邦集群的一個點。它主要能夠解決一些什么問題呢?***個高可用,我們知道Kubernetes本身是一個單機性部署的,如果我們想解決在集群這個維度的單點故障的問題,就是在AZ級別,或者云提供商級別的這么一些單點的問題。第二個就是我希望能夠安全集群的特性做一些應用調度,可能我希望我的應用被調度到一些云提供商上面,AWS上面。第三個就是集群間應用的自動遷移,就是當我某一個集群的容量溢出了,我希望能夠把上面一些應用自動的遷移到其他的界面上面,用戶不感知。第四個是混合云的部署,我們希望將能負載部署到不同的云服務提供商上面,能夠做到一些自動遷移,或者業務量的自動的增加減少。第五個是為了解決當前Kubernetes面臨的比較嚴峻的問題,Kubernetes的規模問題。我們也知道現在Kubernetes發布了1.3版本,對外宣稱能支持到2000節點,但是2000節點在我們生產環境上,這個能力還是略微顯得比較薄弱的。所以我們想通過聯邦這么一個技術點,去解決Kubernetes本身的規模問題。
下面我們把Kubernetes聯邦打開,給大家分享一下。這個是集群聯邦的一個架構,大家看這個圖可能覺得跟我們前面講的Kubernetes本身的架構有些相似。我們這里也是附用了Kubernetes(18:45)的機制,實現了組建結藕的架構。其實這個架構我們發現它的控制面也包括一個聯邦級別的APIservice,還是附用了ECD作它的私有化存儲,能夠對接第三方一些認證健全的功能。在功能面上我們還是有一個聯邦級別的調度器,它來解決應用在不同集群之間的一個調度問題。當然它也支持親和性、反親和性這些基礎的調度能力。第三個重要的組件是聯邦級別的資源控制器、管理器,里面也包括了聯邦級別的資源的控制器。現在聯邦我們引入了三種資源。下面就是聯邦管轄的Kubernetes的集群,原生的Kubernetes集群。對應到聯邦的資源剛才也提到過,本身Kubernetes原生的集群在聯邦維度對應的是Cluster的這么一種資源。這里大家先有一個印象,后面我們在聯邦不同的應用場景下面會把這個圖再給大家做一個展開。
***個就是聯邦上的應用創建,這里可能會跟Kubernetes原生有一點點的區別,Kubernetes我們知道它最小的應用部署單元是pod,或者一組容器。它對我們聯邦來講,它的最小的部署單元是RS,或者一個RC,叫做一個副本控制器。應用部署之主要解決的是我這個RS在聯邦層級調度的問題,它調度主要解決了一個RS拆分的問題,要根據我下面集群的負載能力,或者根據一些親和結合策略,把這個RS做一些拆分。所以***步我的聯邦使用者還是通過聯邦暴露出來的API,它來提供一個創建應用的請求。首先我會把這個應用劃到聯邦的ECD里面。我有一個聯邦的集群的控制器,會周期性的采集我聯邦負載的數據,或者它的健康狀態,然后供聯邦的調度器做一些調度的決策。對應到調度器的行為,它會把RS的副本數按照集群的維度做一些拆分。我們這里的假定場景,我ClusterB的容量可能比A要大,我就會把應用的副本數拆成2A3,對應關系是2到ClusterA上面,3到ClusterB上面。最終還是由聯邦的資源控制器調下面集群的應用創建的接口,把這個應用在各個集群里面創建出來。當然它還會負責應用狀態周期性的查詢,最終會通過APIservice向用戶提供我這個應用狀態的查詢。
這里面就把調度器打開了一下,這個聯邦調度器會感知下面各個子集群的變化,包括我各個子集群的容量、負載,供它自己生成一些調度策略。第二它要能夠看到我當前應用里面,或者我的聯邦維度有哪些應用沒有被調度,通過過濾出字段檢查我這些應用有哪些沒有被調度,放到本地的調度的隊列里面再調度。第三個就是根據***步獲取到的每個集群的容量啊,負載的信息,生成它的調度策略,其實也就是對我這個應用的副本做一些拆分。***它會把這個調度結果寫回到我的集群聯邦的APIservice里面,供我的應用控制器去調下面子集群的接口,去創建它的應用。
在我的聯邦調度器里面也有一些親和性和反親和的考慮,我希望我的應用能夠部署到某些屬性的集群里面,或者我的同一個應用不同實例,我希望在不同的集群里面做一些不同的部署,去解決我的一個高可靠的問題。
前面說的比較慢,后面說的快一些。這個主要是應用跟集群之間親和和反親和的調度,我通過跟不同集群打一些標簽,決定我某些應用會部署到某個特定的集群上面。我這里面應用A的應用,包括了集群1和集群2標簽的選擇性,我應用A就會被拆分到集群1和集群2上面。應用B類似的會拆分到我的集群2到集群3上面。這是應用跟應用之間的親和的調度,如果我的應用B和應用A之間有些依賴關系,我為了解決在不同集群間的網絡消耗,會盡量鋪到一個集群里面。這里面可以支持一些硬親和和軟性的親和。
這個就是前面提到過的,主要是集群的控制器和副本的控制器,前面功能剛才也講到過。***一個很關鍵的點,就是集群聯邦下的服務發現,剛才我在前面講到過Kubernetes服務主要是解決后端應用的訪問問題,里面主要是解決聯邦場景下的應用的訪問問題,包括跨集群的訪問。首先用戶會創建一個服務,主要目的還是為了通過這個服務訪問分布在不同的集群上的應用的訪問問題。我的聯邦的服務控制器會感知到這個服務的創建,會在下面各個子集群里面都會創建這么一個服務實例。這里會有一個默認的選項,包括我的每個集群里面會有一個負載均衡器跟大家做一下關聯。這個服務控制器會在我各個子集群里面創建一種服務,我的應用流量會從一個全球的分布式路由這邊過來,首先會做一層Kubernetes集群維度的流量分發,然后這個集群里面的LB會把這個流量再進一步的分發到我應用后端對應的真實的POD上面。
這個是現在Kubernetes社區1.3版本的集群聯邦的功能展示,我稍微給大家介紹一下它的背景。我現在在GKE的四個區,我分別有四個集群,我希望通過集群聯邦把這四個集群管理起來,并且能夠在我這四個集群里面分別創建我聯邦級別的服務,通過訪問這個服務可以把我的流量按照一些流量分發的策略,分發到我不同的集群里面。***步就是創建集群。第二件事就是把我這個聯邦的控制面部署在其中某個集群里。第四步就是把我的個集群放到集群聯邦里面。這里可以查一下我當前各個集群的狀態,第二步就是創建一個聯邦的服務,當你在集群聯邦這里創建一個服務之后,我下面各個子集群都會有一個被創建。這個時候我的效果是什么呢,我通過分布在不同的集群的服務的訪問,可以按照就近的原則,把這個流量導到某個指定的集群上面。
集群聯邦大概就分享到這里,后面說的比較快,有什么問題大家可以討論。我打個廣告,現在華為CCE在Kubernetes集群的貢獻,大概有四百家的提交次數,全球能夠達到第四,國內基本穩坐***把交椅。包括docker的貢獻,也差不多是這么一個位置。我今天的演講大概到這里結束。