為什麼 k8s 在阿里能成功?| 問底中國 IT 技術演進

csdn 發佈 2020-01-16T01:12:50+00:00

作者| 曾凡松 阿里云云原生應用平台高級技術專家張振 阿里云云原生應用平台高級技術專家責編 | 屠敏從 2015 年 Google 牽頭成立 CNCF 以來,雲原生技術開始進入公眾的視線並取得快速的發展,到 2018 年包括 Google、AWS、Azure、Alibaba Cl

本文描述了阿里巴巴在容器管理領域的技術演進歷程,解讀了為什麼 k8s 最終能夠大獲成功的原因,以及到今年雙11阿里巴巴內部的 k8s 應用情況。內容著重描述了阿里巴巴基於 k8s 的雲原生改造實踐過程的三大能力升級,在對應能力升級過程中沉澱的技術解決方案,以及通過這些能力升級所取得的業務價值。

作者 | 曾凡松 阿里云云原生應用平台高級技術專家

張振 阿里云云原生應用平台高級技術專家

責編 | 屠敏

從 2015 年 Google 牽頭成立 CNCF 以來,雲原生技術開始進入公眾的視線並取得快速的發展,到 2018 年包括 Google、AWS、Azure、Alibaba Cloud 等大型雲計算供應商都加入了 CNCF,雲原生技術也從原來的應用容器化發展出包括容器、Service Mesh、微服務、不可變基礎設施、Serverless、FaaS 等眾多技術方向,CFCF 旗下也囊括了越來多的開源項目。

Kubernetes 作為 CNCF 的第一個項目從誕生之初就就令人矚目,Kubernetes 由 Google 工程師基於 Google 內部多年集群管理系統 Borg 的設計經驗,結合雲計算時代的基礎設施特點重新設計而得,旨在幫助企業解決大規模 IT 基礎設施的應用容器編排難題。Google 在 2014 年 6 月開源Kubernetes以後,在 Redhat、Microsoft、Alibaba 等廠商和眾多開源愛好者共同的努力下,成長為如今容器編排領域的事實標準,極大的推動了雲原生領域的發展。

今天為大家分享來自阿里雲的 Kubernetes 大規模實踐經驗,展現阿里雲如何基於 Kubernetes 推動阿里巴巴應用運維技術棧走向雲原生,如何推動 Kubernetes自身的技術進步,充分挖掘雲原生時代的紅利助力阿里巴巴大幅降低雙11的 IT 成本。

容器在阿里巴巴的發展歷程

在 2011 年之前,阿里巴巴使用 VM 虛擬化技術將一個物理機切分為 3 個虛擬機,用於部署淘寶服務,而隨著淘寶業務的飛速發展,基於 VM 的技術方案在靈活性上跟不上業務的步伐。因此,阿里巴巴在 2011 年就開始探索基於 Linux lxc 的容器技術,用於替代傳統基於 VM 的應用部署方案,到 2013 年,研發了基於 Linux lxc 的 T4 容器和AI 容器編排系統。這在當時已是非常領先的技術方案,但自己研發的容器技術與基於 VM 時代的運維繫統始終存在一些兼容性問題。

在 2013 年隨著 Docker 容器鏡像方案的出現,阿里巴巴技術人員立即看到了基於容器 + Docker 鏡像技術的未來,開始大力投入到這一領域的研究當中,到 2015 年 Aliswarm、Zeus、Hippo等容器編排系統蓬勃發展,各自開疆擴土服務了阿里巴巴經濟體的一部分業務。諸多的系統在解決了業務運維成本的同時,也帶來了一定的重複建設成本,同時也導致了阿里巴巴內部的資源分布比較分散,無法統一調度多樣的業務類型發揮出不同業務錯峰使用資源的優勢。正是在這樣的背景下,Sigma 系統應運而出並在 2017 年統一了阿里巴巴的資源池,統一調度阿里巴巴所有的核心業務,並第一次支持將在線服務與離線作業運行在同一個物理機上,大幅提高數據中心的資源利用效率並降低了阿里巴巴的 IT 成本。

隨著雲原生技術的高速發展,阿里巴巴也看到了雲原生技術的潛力,以及未來企業 IT 全面上雲的必然趨勢,從 2018 年開始轉型到 Kubernetes 技術,通過 Kubernetes 擴展能力將 Sigma 積累多年的調度能力通過 Kubernetes 的方式提供出來。在 2019 年阿里巴巴宣布全面上雲,阿里巴巴開始全面的擁抱Kubernetes,並將 Sigma 調度系統全面的遷移到基於Kubernetes 的調度系統,該系統也正是支持了今年最大規模雙11電商交易系統的底層基礎設施,穩定的支持了大促前後數百次的應用變更並提供極速的應用發布與擴容體驗,為雙11的順暢的購物體驗立下悍馬功勞。

為什麼 k8s 在阿里能成功

Kubernetes 在眾多的技術中脫穎而出,概括起來可以歸納為以下三個方面。

首先是其在誕生之初就為雲時代而生,擁有超前的眼光和先進的設計理念,加之最初由天才的 Google 工程師基於其內部 Borg 多年的經驗設計而來,誕生之後就飛速發展。後來隨著 RedHat、IBM、微軟、Vmware、阿里雲等來自全球的優秀工程師大力投入,打造了繁榮的社區和生態系統,成為企業容器編排系統的首選。阿里巴巴經濟體擁有眾多的子公司,這些子公司在加入阿里巴巴大家庭時或多或少都會有一套自有的容器編排系統,在融入阿里巴巴的基礎設施過程中,Kubernetes 是最標準也最容易被經濟體內外的客戶所接受的一個方案。

其次,Kubernetes 倡導的申明式 API 的設計理念,也貼合了阿里巴巴在應用運維領域的經驗與教訓。傳統的運維繫統通常是基於過程式的設計,而過程式的運維繫統在較長的系統調用鏈路下,通常會出現因異常處理複雜而導致的系統效率低下。在大規模應用運維繫統中複雜又繁多的狀態處理也是一個大難題,基於過程式的系統設計很難確保系統的一致性,針對這些邊界異常的處理通常又導致運維繫統變得非常複雜,最終為異常兜底的只能依賴運維人員的人工操作。基本上可以認為基於過程式的運維繫統難以應對超大規模的應用管理,而Kubernetes 提供的申明式 API 卻是解決應用運維狀態輪轉的一劑良藥,是提高運維技術棧整體鏈路效率的最佳實踐原則。

第三,Kubernetes 模塊化、可擴展的架構設計,滿足阿里巴巴的定製化改造以支持眾多業務運維場景的需求。在阿里巴巴內部,即有大量的無狀態核心電商系統,也有大量的緩存、消息隊列等中間件有狀態系統,也包括大量帶有倒排索引數據的檢索系統,還有大量的 AI 計算任務,不用的應用類型對底層容器管理平台的要求也有所不同。因此,一個模塊化方便遷入自定義應用管理策略、易於擴展調度模型的設計顯得至關重要,是能夠服務阿里內部眾多應用形態、提供統一容器管理基礎設施的關鍵,Kubernetes 基本上提供了這些關鍵基礎能力,雖然在實際應用過程中仍然會遇到非常多的實際問題。

阿里巴巴的 k8s 應用情況

在 2019 年雙11,阿里巴巴內部核心業務主要運行在神龍、ECS、ECI 三種資源類型的基礎設施之上,而這些不同類型的基礎設施資源均通過Kubernetes 統一管理,以容器的形態提供給上層應用使用,完成了核心業務的支撐。

有別於以往的雙11,今年核心電商業務應用大規模部署在神龍裸金屬伺服器上。如果有關注過阿里雲技術的發展,應該不會對神龍伺服器感到陌生,它是阿里雲自主研發的新一代雲伺服器,通過「軟硬一體」的技術開創性的將雲計算的虛擬化開銷分攤到低價硬體板卡上,徹底的釋放 CPU 的計算能力,第一次真正的做到了雲計算虛擬化的「零」開銷。容器也是一種輕量級的虛擬化方案,神龍+容器+Kubernetes 的結合正是雲原生時代的最佳拍檔,支撐了今年最大規模的雙11,也將是未來的主流技術形態。

阿里巴巴也在繼續使用 ECS 作為 Kubernetes 的底層資源供給,ECS 作為傳統的雲計算虛擬化方式支撐了部門集團內部業務,同時結合靈活性更好的彈性容器實例 ECI 用於應對業務突發的流量峰值,為業務帶來了雲計算的彈性價值,真正實現了按需申請、釋放資源的極致彈性能力,降低了業務需要提前規劃資源所帶來的成本。

這些分布在海內外的數十萬個節點的資源,被數十個 Kubernetes 集群託管,運行著阿里巴巴上萬個應用,共計超過百萬的容器,其規模之大前所未有。在今年的雙11中,阿里巴巴內部最大的 Kubernetes 集群規模達到萬級;當然這並不是Kubernetes 的技術極限,而是我們考慮數據中心資源效率與基礎設施容災能力之間所取的平衡,在將來如果有需要這個數字也可能變得更大。

基於 k8s 的雲原生改造實踐

Kubernetes 作為雲原生技術的代表,已經成為了容器編排領域的事實標準,阿里巴巴自 2017 年開始探索,到 2018 年確認技術轉型到使用 Kubernetes 來管理生產的容器。在落地 k8s 的過程中,我們主要面臨著兩大難題:

其一,上層多樣的業務運維平台。為了支撐阿里巴巴內部多樣的業務形態,在內部發展出來了多個典型的業務運維平台,每一個運維平台的基礎設施、流程控制、應用發布策或多或少都會存在一些差別,缺少一個統一的應用運維標準。在調度與集群管理的技術演進過程中,如何牽引整個運維體系升級的同時並保持多個業務的平台及其上業務的穩定性,這是一個巨大的工程。其二,隨著阿里經濟體的全面上雲戰略的實施,整個底層基礎設施包括存儲、網絡、基礎運維軟體的技術演進也非常迅速。調度與集群管理需要在支持好基礎設施快速演進的同時,疊代自身的技術架構,並同時保證業務的穩定性。

基於 k8s 的雲原生技術改造正是在這樣的背景下誕生,發展到2019 年 Kubernetes 在內部已大規模部署,所有的核心業務也都已經運行在 k8s 集群管理中。但在這幾年的實踐過程中,有一個問題始終縈繞在工程師頭腦中,在阿里巴巴這麼大體量、這麼複雜的業務下,遺留了大量傳統的運維習慣以及支撐這些習慣的運維體系,在這樣的背景下落地Kubernetes (內部一個形象的比喻叫做給高速飛行的飛機更換髮動機)到底是在堅持什麼,哪些地方可以妥協,哪些地方必須改變?

這一章節, 將為大家分享我們這幾年對這個問題的一些思考,特別是經過了今年的雙11考驗後,這個問題的答案基本上得到了工程師群里的集體認可,負責頂層設計的架構師終於可以喘一口氣:擁抱Kubernetes 本身並不是目的,而通過擁抱 Kubernetes 翹動業務的雲原生改造,通過Kubernetes 的能力治理傳統運維體系下的沉疴頑疾,真正釋放雲的彈性能力,為業務的應用交付解綁提速,才是這次技術變革的最大價值所在。

面向終態升級

在傳統的運維體系下,應用的變更都是運維通過創建操作工單發起工作流,繼而對容器平台發起一個個的變更來完成的。比如升級一個服務下的 3000 個實例,工單會被提前計算並生成出多個批次的子任務,並逐個的調用容器平台的接口完成變更應用的變更。為了確保應用發布工單的順利執行,在每一個子工單內部,每一個容器的發布也是一個工作流,包括監控開管、鏡像拉取、容器啟停、服務註冊、配置推送等等,如果一切正常該流程會按預期有序的進行。

在大規模應用發布的場景中,諸如宿主機宕機、磁碟異常、IO 異常、網絡異常、內核異常等幾乎是必然存在的,如果發布流程中的某一個步驟出現了錯誤,通常情況下需要運維平台按照一定的策略來重試,直到超過該批次的超時閾值,這將會帶來三個問題,下面逐一展開。

其一是重試帶來的效率問題。每一個子任務的執行時間將被任務內的長尾發布所拖累,假設將 3000 個容器分為 30 批次每批 100 個(僅為示意並非最佳實踐),每一批次內出現一個容器發布異常時,該批次的發布時間將被重試拉長。其二是失敗帶來的一致性問題。對於發布異常的容器,在工單結束之後通常只能通過外圍鏈路巡檢的方式來治理,而事實上通常的巡檢是依賴運維人員手工操作的,帶來了極大的人工成本和不確定性。第三是應用並發變更衝突問題。如果在應用發布的過程中,同時提交了應用擴容的請求,由 3000 擴容到 3200 個實例,擴容的 200 個實例應該採用舊版本還是新版本,採用舊版本擴容將面臨的問題是誰最終負責這200 箇舊版本實例的升級,採用新版本擴容將面臨的是穩定性問題,如果新版本存在問題新擴容的實例將產生較大的影響。正是因為這些複雜的問題導致多數運維繫統拒絕了並發的應用變更,導致並發操作效率非常底下。

k8s 為應用管理所提供的申明式 API 的設計理念同時解決了解決了這三個問題,用戶只需要描述期望的最終狀態以及達成期望狀態的過程中需要遵守的限制條件,達成終態所需要執行的複雜操作全部交由 k8s 的來完成。在應用發布過程中,通常情況下 k8s 通過控制並發度及最大不可用實例數來約束應用發布對服務的影響,對於發布過程中失敗的實例通過最終一致的方式在系統內部解決。正式基於這一設計,用戶發起服務變更時只是更新了應用的預期狀態,並不需要等待任何任務的結束,一併解決了應用發布效率、線上配置的一致性和並發變更衝突效率的問題。

基於面向終態的理念管理應用,我們開發 Advanced StatefulSet 的應用管理工作模型,顧名思義它基於Kubernetes 官方的 StatefulSet 擴展而來。

在官方的工作模型中,應用通過滾動的方式完成版本升級,也就是創建新的 Pod 同時刪除舊版本的 Pod,直到整個應用切換為新的版本。這種方式簡單直接,但存在效率的問題,比如所有應用的Pod 需要重新的調度,這在大規模應用發布場景將給調度器帶來很大的壓力;同時,因為新版本 Pod 為全新創建,需要重新分配 IP 並掛載遠程卷,這對雲計算網絡、存儲基礎設施也將是很大的挑戰;再者,因為容器是被全新調度出來的,在機器上需要重新下載新的應用鏡像,這將大幅降低應用發布的效率。

為了提高應用發布的效率和資源的確定性,開發了這一工作負載模型,它支持原地發布應用,應用發布前後應用所在的位置保持不變,同時支持了並發更新、容錯暫停等豐富的發布策略,高效的滿足了阿里巴巴內部電商應用的發布需求。因為應用發布前後位置不變,因此我們可以在灰度發布的過程中預先下載並解壓即將要發布的容器鏡像,從而大幅提高應用發布的效率。

在面向終態的應用管理中,複雜的運維過程被 k8s 內部所實現,k8s根據用戶的期望及現狀計算出需要執行的動作,並逐步的變更直到終態。面向終態帶來了卓越的運維效率提升,但同時也為系統工程架構提出了更高的要求。

我們知道在 k8s 內部是一個模塊化、分布式的系統,通往終態的運維決策分散在內部的多個模塊中,這些模塊都有可能對容器發起一些運維動作,比如控制器、運維 Operator、重調度器甚至是 kubelet。在高度自動化的系統中,一旦出現預期外的異常,其殺傷力可能會對其上運行的業務造成災難性的後果,加之 k8s 中決策分散在眾多的模塊中,所帶來的問題是系統風險的控制變得更加困難,對這個系統設計的質量有很高的要求。為了控制整個系統的風險,如上圖所示,我們在 k8s 系統的關鍵位置對關鍵行為行為進行了埋點,針對性的制定了限流及熔斷的策略,使得整個系統即使在出現極端錯誤的場景下,也能夠最大化的保護其上運行的業務。

自愈能力升級

在阿里巴巴傳統的運維體系下,容器平台僅生產資源,應用的啟動以及服務發現是在容器啟動後由運維平台系統來完成的,這種分層的方法給了運維繫統最大的自由度,也在容器化後促進了阿里的容器生態繁榮。但是這種方式有一個嚴重的問題,因為容器調度平台無法自主地去觸發容器的擴縮容,而需要和一個個運維平台來做複雜的聯動,上層運維繫統也因為需要感知到底層基礎設施的信息,從而導致進行了很多重複建設的工作。在工程實踐上,這些複雜性使得即使經過了細心的設計與大量的投入其工作效率也不高,嚴重妨礙宿主機發生故障、重啟,容器中進程發生崩潰、卡住等異常時的自愈修復效率,同時也讓應用彈性伸縮的實現變得非常的複雜和低效。

我們解決這一問題的思路是通過 k8s 中提供了容器命令以及生命周期鉤子,將啟動應用以及檢查應用啟動狀態這一正個流程內置到 pod 中,包括與監控、VIP、服務中心、配置中心等基礎設施的交互,通過 Pod 實現容器與應用實例的生命周期統一。容器平台不再是僅生產資源,而是交付可以直接為業務使用的服務,從而使得可以在 k8s 系統內部完成故障自愈閉環,極大地簡化了應用故障自愈以及自動彈性擴縮容能力的建設。提高系統自愈的效率,實際上也是幫助業務獲得更好的運行時穩定性和應用運維效率。

在完成了容器與應用實例的生命周期統一之後,我們正在打造一個統一控制器編程框架:Operator Platform。Operator Platform 由中心的控制組件與一個 sidecar 框架容器以及客戶端代碼組成,通過對通用的控制器能力的抽象,包括:事件通知、灰度管理、版本控制、緩存、命令管道等能力的封裝集成,支持多語言編寫operator,使得開發者無需要理解 k8s 的眾多的接口細節及錯誤處理,從而降低了基於 operator 的自動化運維能力的開發難度,使得越來越多的運維能力通過operator 的方式沉澱到 k8s 生態體系中來,讓更多的有狀態應用能夠自動化地部署,提高整個運維體系的運轉效率。通過這種方式,構建了整個機器故障自愈的體系,高效的串聯起包括機器鎖定、應用驅逐、機器線下、異常修復等流程,確保了集群宿主機的在線率以及業務的可用性。未來,我們期望通過將 operator 編寫標準化的方式去推動多個運維平台的基礎運維能力能夠被最大化的復用,減少重複建設的成本。

不可變基礎設施

第三個重要的能力升級對不可變基礎設施的升級。我知道 Docker 提供了一種統一的應用交付的形式,通過把應用的二進位、配置、依賴文件在構建過程中打到一個鏡像中,從而確保了應用被一次構建出來之後在多個環境中交付的確定性,避免了環境不一致帶來的諸多問題。而 k8s 更進一步,通過將不同用途的 Docker 容器組裝在一起成為一個 pod,通常情況下在升級 pod 時需要整個的銷毀重建,從而確保應用鏡像、卷、資源規格的一致性。在落地 k8s 的過程中,堅持了不可變基礎設施的設計理念,通過 k8s pod 將原本運行在一個富容器中的應用與運維基礎組件分離到不同的容器中,並通過升級容器鏡像的方式完成應用的升級。這裡有一個概念需要澄清,並不是使用 k8s 就等於踐行了不可變基礎設施的理念,而是必須要確保應用運維通過鏡像升級而不是動態發布文件的方式完成,而事實上因為一些歷史原因,這一用法在行業中普遍存在。

當然,與 k8s 有所不同的是,我們並未強制堅持 pod 的不可變而是取了一個折中的方式,即堅持容器不可變。原因是因為我們將應用容器與運維基礎設施容器分離之後,運維容器作為應用容器的 sidecar 容器,其擁有著不同的版本疊代策略。應用容器由應用運維人員負責發布,其策略因應用的不同而不同,比如電商應用使用 StatefulSet 而本地生活使用 Deployment 來管理應用,而基礎設施容器則由基礎設施運維負責,其發布策略與應用本身也存在一些差別。為了解決這個問題,我們開發了一個叫做 SidecarSet 的基礎設施容器管理模型,它使用同一個集合統一管理多個應用的運維容器,將基礎設施的變更與應用容器的變更進行分離,從而支持基礎設施的快速演進。將基礎設施容器定義從應用 pod 中抽離出來後,應用管理員不再關心基礎容器的啟動參數,而是交由基礎設施運維人員通過配置 SidecarSet 自動為應用注入運維容器,簡化了應用運維的複雜性。可以看到,這種關注點分離的設計,同時簡化了應用運維與基礎設施運維的負擔。

總結與展望

阿里雲通過落地 k8s 推動阿里巴巴運維體系走向雲原生,在應用容器發布管理效率、服務穩定性以及企業 IT 成本方面取得了很大的突破。我們一直在思考,通過什麼樣的方式能夠將阿里巴巴的應用管理經驗輸出到更多的場景,解決更多客戶面臨的應用管理難題,在企業全面雲化這樣的趨勢下,如何解決企業在公有雲、私有雲、混合雲以及多雲場景的應用管理複雜性。

正是在這樣的背景下,阿里雲與微軟在2019 年 11 月聯合推出了一款用於構建和交付雲原生應用的標準規範,即 Open Application Model(簡稱 OAM)。OAM 提出了一種通用的模型,讓各平台可以在統一的高層抽象上透出應用部署和運維能力,解決跨平台的應用交付問題。同時,OAM 以標準化的方式溝通和連接應用開發者、運維人員、應用基礎設施,讓雲原生應用交付和管理流程更加連貫、一致。

通過應用交付標準化的方法,我們期望未來在雲上部署一個應用,就像手機在應用商店中安裝一個淘寶一樣便捷與高效,OAM 更多的信息可以在這裡找到https://oam.dev/。

最後,本文提到的阿里在雲原生改造上完成的相關能力升級,我們都已經或者即將開源到 OpenKruise 項目 https://openkruise.io 中,歡迎大家關注與交流!

關鍵字: