1. 程式人生 > >阿里集團八年容器化演進之路

阿里集團八年容器化演進之路

640

近日,阿里集團內部已經實現 100% 容器化映象化;距離 PouchContainer 開源不到一年時間,PouchContainer 開源版 1.0 GA 版本釋出,已經完全達到生產級別。另外,作為百萬級開源容器技術,PouchContainer 被收錄進為高校教材《雲端計算導論》。PouchContainer 現在服務於阿里巴巴集團和螞蟻金服集團的絕大部分 BU, 包括交易&中介軟體,B2B/CBU/ICBU,搜尋廣告資料庫,還有收購或入股的一些公司,比如優酷高德、UC等。其中體量最大的是交易和電商平臺,在 2017 年雙 11 的時候我們支撐了破紀錄的峰值,背後的應用都是跑在 PouchContainer 裡面,整體容器例項已經到了百萬級規模。使用了 PouchContainer 的應用涵蓋了各種各樣的場景。這些場景從執行模式來看,有標準的線上 App,還有像購物車、廣告、測試環境等比較特殊的場景。不同的場景對 PouchContainer 有不同的使用方式和需求。從程式語言看,實際執行著 Java、C/C++,Nodejs,GoLang 等語言編寫的應用。從技術棧的角度看,包含了電商、DB、流計算、大資料、專有云等場景,每個場景對於容器各方面要求,所用到的特性都不太一樣,PouchContainer 針對每個場景的需求都在產品上都做了支援。
PouchContainer 容器技術在阿里的演進過程伴隨著阿里技術架構本身的演進。阿里內部技術架構經歷了一個從集中式單體應用到分散式微服務化的演進。
淘寶最開始是一個巨石型的應用,一個應用裡包含了商品、使用者、下單等等所有交易鏈路的功能。隨著功能越來越完善,維護起來也越來越困難。為了提高研發效率,從 2008 年開始我們逐漸把這個應用拆分成了多個分散式應用,商品的,交易的,使用者的,前臺的,後端的;通過 HSF 遠端呼叫框架,TDDL 分散式資料層和 Notify 分散式訊息中介軟體串聯起來。其中每個服務都有多個例項,都可以獨立研發演進,並可以進一步繼續拆分。於是就逐漸形成了一個龐大的分散式服務叢集。從巨石型應用到多個單一功能的輕量級服務型應用,總的應用例項數變多了,每個例項需要的系統資源變少了。於是從最初的每個例項直接使用物理機自然過渡到使用 Xen,KVM 等虛擬化技術。VM 使用了一段時間之後,發現整體物理機的利用率還是很低。當時一個 24 核的物理機只能虛出 4 臺 4 核的 VM,除了當時虛擬化本身的開銷不小外,每個應用例項在 VM 裡仍然用不完分到的資源。於是就想能不能不用虛擬機器,用更輕量的基於程序級別的資源切分使用方式。
這個時候阿里內部的運維體系已經比較龐大了,從應用的構建部署到分發,到一些執行期的監控告警等管控系統,都依賴於一個應用例項跑在一個獨立機器裡的假定。這個假定已經不經意間貫穿到了研發運維的各個環節裡面,包括系統的設計,運維習慣等都嚴重依賴這個假定。我們不可能重新搭建叢集,把存量的業務停掉再到新的叢集裡面用新的運維模式去跑起來,這個業務和運維上都是沒法接受的,不可能電商交易的研發停幾個月,系統停幾天來搞這個事情。所以我們首先要做到相容,新的資源使用方式必須相容原先的假定。我們經過仔細分析了這個假定的內涵,發現每個應用例項歸納下來無非有如下 4 點要求:
  • 有獨立IP

  • 能夠SSH登陸

  • 有獨立的,隔離的檔案系統

  • 資源隔離,並且使用量和可見性隔離


首先是有獨立 IP,能夠 SSH 登入。其次有獨立的檔案系統,應用程式跑起來,希望程式看到的整個檔案系統都是給他專用的,因為現有的程式碼和配置中必然有很多路徑的硬編碼,需要滿足這個潛在要求。還有不管通過工具還是程式碼,他只能看到分配給他自己的資源。比如 4 個 CPU,8G 的記憶體,他能夠根據這些資源的用量做一些監控,做一些對自己資源使用量的採集和告警。這四個特點總結下來就是新的資源使用方式要做到和物理機或者 VM 的使用體驗一致。能夠做到這樣的話原先跑在 VM 裡的應用就可以很平滑的遷移過來,現有的應用系統和運維繫統不需要做很大的改動。
我們為了能達到這四點,最開始是多隆大神手工 Hack 系統呼叫,glibc 基礎庫等,實現了一些資源上的隔離。像有獨立的 IP 可登入 ,就用虛擬網絡卡,在每個容器裡面起一個 sshd 程序;資源的隔離和可見性上,就用 Cgroup 和 Namespace 等核心特性;後來發現開源的 LXC 專案也在做同樣的事情,並且比手工 Hack 更通用化,更優雅一些。於是我們整合 LXC,並且在核心上加了定製的資源可見性隔離的 patch,讓使用者的例項只能看到分配給他的 CPU和記憶體,另外還增加了基於目錄的磁碟空間隔離的 patch,這樣就形成了我們第一代的容器產品。這個產品當時代號是 T4,寓意是第四代淘寶技術,淘寶 4.0;在 2011 年的時候 T4 容器技術灰度上線。T4 相比 VM,完全沒有虛擬化 Hypervisor 層的開銷,資源切分和分配上更加靈活,可以支援不同程度的資源超賣。這樣就很好的支援了業務爆發增長的需求,控制了物理機按業務增長比例膨脹的勢頭。另外因為 T4 完全相容了之前研發和運維對物理機和 VM 的使用習慣,絕大多數應用都能夠做到透明的切換,應用無感知。因為有這些特性,在接下來的短短几年時間裡,T4 逐步接管了交易和電商主體的線上應用。
到 2015 年的時候 Docker 技術火起來了。我們寫程式的都知道有個著名的公式,程式=資料結構+演算法。從程式交付使用變成一個軟體產品的角度來看,我們可以套用這個公式:
  • 軟體= 檔案(集)+ 程序(組);

從靜態來看,軟體從構建分發到部署,最終形式是一個有依賴層次的檔案集。從動態來看,這些檔案集,包括二進位制和配置,由作業系統載入到記憶體後執行,就是一個有互動關係的程序組。我們之前的 T4 容器在程序(組),或者說執行時上做的事情和 Docker 基本類似,比如說都使用了 Cgroup、Namespace、linux bridge 等技術。還有些是 T4 特有的,比如基於目錄的磁碟空間的隔離,資源可見性隔離,對老版本核心的相容等。我們從最早物理機演化到 VM,再到現在的容器,核心的升級週期比較漫長,迭代很慢,15年的時候存量的機器上全部都是 2.6.32 核心,T4是相容 2.6.32 核心的。 但是另一方面在檔案(集)的處理上 Docker 做得更好,更加系統化。 T4 只做了很薄的一層映象,給相同的業務域做了一個基礎的執行和配置環境,這個映象沒有深入到每一個特定的應用。 而 Docker 是將每個應用的整個依賴棧打包到了映象中。因此在 2015 年我們引入了 Docker 的映象機制來完善自己的容器。

640

在將 Docker 映象整合進來之後,原來基於 T4 的研發運維體系受到了很大的衝擊。 首先交付方式變了,之前是 build 一個應用的程式碼包,把程式碼包交給我們的部署釋出系統,後者建立一個空的容器,根據這個業務所在的很薄的模板把一個空的容器跑起來,再到容器裡面安裝依賴的一些 IPM 包,設定一些配置,按每個應用定好的一個列表一個一個的安裝好,然後把應用包解壓啟動起來。這個應用依賴的軟體和配置列表我們內部叫做應用的基線。引入映象之後,在將 Docker 映象整合進來之後,原有的交付方式發生了變化。之前是 build 一個應用的程式碼包,把程式碼包交給我們的部署釋出系統,後者建立一個空的容器,根據這個業務對應的很薄的一個模板,把一個空的容器跑起來,再到容器裡面安裝依賴的一些 RPM 包,設定一些配置,按每個應用定好的一個清單一個一個的安裝好,然後把應用包解壓到主目錄啟動起來。這個應用依賴的軟體和配置清單我們內部叫做應用的基線。引入映象之後,我們應用的程式碼包和依賴的所有的這些三方軟體、二方軟體都會打成一個映象。之前通過基線維護應用依賴環境,現在都放到每個應用自己的 Dockerfile 中了,整個研發構建和分發運維的過程大大簡化了。
做了這個事情之後,研發和運維之間的職責和邊界就發生了變化。之前研發只需要關注功能,效能,穩定性,可擴充套件性,可測試性等等。引入了映象之後,因為要自己去寫 Dockerfile,要了解這個技術依賴和執行的環境倒底是什麼,應用才能跑起來,原來這些都是相應運維人員負責的。研發人員自己梳理維護起來後,就會知道這些依賴是否合理,是否可以優化等等。研發還需要額外關注應用的可運維性和運維成本,關注自己的應用是有狀態的還是無狀態的,有狀態的運維成本就比較高。這個職責的轉換,可以更好的讓研發具備全棧的能力,思考問題涵蓋運維領域後,對如何設計更好的系統會帶來更深刻的理解。所以引入 Docker 之後對研發也提出了新的要求。我們總結新的時期,新的運維模式下對研發能力要求的幾個要素,總結起來就是幾個原則:
640
為了更好的把自己的系統建設好,我們要倡導研發從第一天建立系統的時候,就要考量最終的可運維性,比如引數是否可配置,是否可以隨時重啟。機器每天都有硬體故障產生,這些硬故障不可能每天都人工處理,必須要儘可能自動化處理,自動化處理時,雖然有些故障隻影響了一部分例項,另一部分是好的,但是也可能需要一起處理,比如需要物理機上的業務全部遷移走來維修物理機的時候。所以不管當時容器裡的業務是好的還是不好的,都要滿足隨時可重啟,可遷移的要求。原來是部分交付,現在要考慮你到底執行環境是什麼樣的,什麼樣的執行環境才能跑起來,儘量做標準化的操作。比如說啟動,Dockerfile 裡面寫好啟動的路徑,不要再搞一些特殊的處理,如果有任何特殊的處理都沒法做統一的排程和運維。統一的業務遷移,機器騰挪也沒法做。我們的目標其實就是從一開始的比較粗放的運維,到不斷的開發自動化的工具和系統,形成一個體系,通過前期人工運維的過程把一些固定的故障處理的流程模式化,最後提取出來一些可以自動處理故障,自動恢復的機制。我們的最終目標是無人職守。所有這些加起來其實就是我們引入映象化之後,並且要朝著無人值守的方向演進時,對研發和運維的新的要求。
640
上面是 PouchContainer 容器的 Roadmap, 2011 年的時候 T4上線 ,到 2015 年 3 月的T4 覆蓋了交易的大部分應用。這個時候開始引入了 Docker 映象機制,這裡面做了很多相容性的工作。比如說原來 T4 輕量化的模板轉化成對應的基礎映象,裡面相容了很多之前運維的習慣和運維的工具,如賬號推送,安全策略,系統檢測。我們在 2016 年初上線了第一個映象化應用,到 5 月份的時候集團決定主站全部應用容器化。在做映象之前阿里是有一兩百人的團隊做每個應用的部署,運維,穩定性控制,後來這個團隊都沒有了,全部轉成了 DevOps,轉向開發工具和運維平臺,通過程式碼的方式,工具的方式解決運維的問題。之前專職做運維的同學最大的負擔就是線上環境的變更,研發提交變更申請給運維同學,運維同學做線上操作,研發不知道程式碼執行環境具體依賴了哪些基礎軟體。做了映象化的事情後,研發自己負責編寫 Dockerfile,運維就把環境變更的事情通過 Dockerfile 的機制移交給了研發。運維和研發之間的邊界就非常清楚了,這個邊界就是由 Dockerfile 來定義的。研發負責把他程式碼依賴的環境在 Dockerfile 定義好,運維保證其構建分發時沒有問題。我們在 2016 年雙11的時候完成了交易核心應用的映象化 PouchContainer 化改造。在 2017 年雙11的時候交易全部應用完成了映象化改造。然後我們在 2017 年 11 月 19 日的時候宣佈了 PouchContainer 的正式開源。
我們的內部 PouchContainer 經過大規模的執行,支援了各種各樣的業務場景,各種不同的技術棧,不同的執行形態,積累了非常多的經驗。這些經驗之前跟阿里內部的環境耦合性比較大。比如說我們的網路模型,我們其實是嵌入到了阿里內部的網路管控平臺,包括IP分配在內部都有獨立的系統去完成。比如什麼時候啟用 IP,什麼時候下發路由等等,這些是有一個統一的 SDN 網路管理系統來管理的。還有類似的內部儲存系統,還有運維的一些指令推送系統。內部系統耦合性比較大,沒法直接開源。所以我們最後選擇的策略是先在外部孵化一個從零開始全新的專案,把內部的特性一點點搬上去。這個過程中我們內部的版本也會做重構,把內部的依賴做一些外掛化解耦合的方式,這樣最後全新的專案在外部可以跑得很好;在內部用一些耦合內部環境的外掛也可以跑起來,最終的目標是內外用一套開源版本。
那麼我們的 PouchContainer 容器相對於其他容器有什麼差異呢?主要體現在隔離性、映象分發優化、富容器模式、規模化應用和核心相容性幾個方面。傳統的容器隔離維度就是 namespace、cgroup;在資源可見性方面,我們前幾年是通過在核心上打 patch,在容器內看記憶體和 CPU 利用率等資料時,把統計數值和當前容器的 Cgroup 和 Namespace 關聯起來,使容器能使用的資源和已使用的資源都是容器自己的。18年的時候我們引入了社群的lxcfs,這樣就不需要對特定核心 patch 的依賴了。磁碟空間的限制也是在低版本核心上加了補丁,支援了基於檔案目錄的磁碟空間隔離,能夠把每個容器的 rootfs 限制住。在 4.9 以上的核心上,我們是用 overlay2 檔案系統來完成同樣功能的。我們也在做基於 hypervisor 的容器方案,提升容器的隔離性和安全性,我們在 PouchContainer 裡面集成了 RunV,用於一些多租戶的場景。
640
阿里內部的離線上混部之所以能推進,在同一個機器上既能跑線上的業務又能跑離線的一些任務,互相之間不會出現太大的干擾,其核心的技術就是 PouchContaienr 容器可以根據優先順序,把不同業務的資源使用隔離開來,保證線上業務優先使用資源。這個資源包括很多的維度,比如 CPU、記憶體,CPU cache、磁碟、網路等等。
640
這是 PouchContainer 的映象分發設計。我們內部有很多比較核心的應用,體量比較大,例項會分佈在上萬臺物理機上。釋出新版本的時候上萬臺機器同時拉映象,任何中心的映象倉庫都扛不住。因此我們設計了一套映象分發的二級架構,在每個地域建一個 mirror,在同一個地域內拉映象的時候用 P2P 分發技術---我們內部的產品名叫蜻蜓,已經開源;需要拉映象的伺服器之間可以分散互相拉檔案片段,這樣就直接化解了中心映象倉庫的服務壓力和網路壓力。後面其實還有更好的解決映象分發的思路,我們正在嘗試映象的遠端化,通過儲存計算分離技術,用遠端盤的方式掛載映象,直接跳過或者說非同步化了映象分發這一步,目前正在內部環境灰度執行中。
640
這是 PouchContainer 內部版本的體系結構。在最底層的宿主機層面,我們會做一些管理和運維,目的是為了確保容器執行依賴的基礎環境是健康的,包括宿主機的一些映象清理,包括安全控制、許可權管理等。OS 的低版本核心我們是適配到最低 2.6.32 核心,包括容器裡面的程序管理也做了很多的適配。資源隔離前面講過了,網路模型我們內部其實主體用的是 Bridge,但是其他各種各樣的場景也都支援。我們開發了很多外掛,PouchContainer 開源後,我們才將這些外掛逐步做了標準化,相容適配了社群的 CNI 標準。最上層是一個富容器模式的支援,每個容器裡面會啟動一些跟內部的運維工具,運維繫統息息相關的一些元件,包括一些釋出模式的優化。可以看到我們內部體系結構是比較複雜的,尤其依賴內部的其他系統比較多,在外部直接跑是跑不起來的,因此也沒法直接開源。
640
所以我們開源版本是重新開始搭建的,這樣會比較清爽一些。我們引入了contained,支援不同的 runtime 實現,包括我們自己包裝 lxc 開發的 RunLXC 執行時,可以用來支援老版本 2.6.32 核心。開源版 PouchContainer 相容所有 Docker 的介面,也支援 CRI 協議,這樣也就同時支援了比較主流的兩種叢集管理系統。網路方面我們內部基於 libnetwork 做了增強,包括不同場景暴露出來的一些問題,一些穩定性,規模化的時候各種細節的一些優化。儲存方面我們支援了多盤,記憶體盤,遠端盤等各種不同形式的儲存。PouchContainer 可以無縫整合到上層編排工具中,包括 Kubelet 和 Swarm 等。我們內部的 Sigma 排程系統,不同的版本Docker 協議和CRI協議都會使用。
這是 PouchContainer 的開源地址:https://github.com/alibaba/pouch
如何貢獻:https://github.com/alibaba/pouch/blob/master/CONTRIBUTING.md
最近 PouchContainer 開源版本 GA 已經發布,PouchContainer 能夠在如此短的時間內 GA,離不開容器社群的支援,在超過 2300 個 commit 的背後,有 80 多位社群開發者的踴躍貢獻,其中不乏國內一線網際網路公司、容器明星創業公司貢獻者的參與。
PouchContainer 開源版本釋出 GA 之前,此開源容器引擎技術已在阿里巴巴資料中心得到大規模的驗證;GA 之後,相信其一系列的突出特性同樣可以服務於行業,作為一種開箱即用的系統軟體技術,幫助行業服務在推進雲原生架構轉型上佔得先機。
Q:你們是怎麼樣做到把阿里巴巴集團包括高德還有菜鳥那些,都能把這個技術推過去,因為大公司在不同的部門跨部門甚至是跨子公司之間要想推行你們的某一個部門的研究成果是一件比較困難的事情。A:這是一個好問題,我們其實也面臨過這個問題。我們的方法就是首先要和大家宣導這個理念,讓大家在認知上都接受映象化運維能帶來的優勢,長遠發展的好處。雖然很難有直接立竿見影的收益,長遠來看一定能提高運維效率,降低資源使用的成本。實際上從這兩年來看,我們確實降低了不少運維成本。
Q:你好,我想問一下容器裡面的那些持久化是怎麼處理的?A:容器我們持久化現在大體分兩類資料,一個是日誌,一種是應用自己會寫一些資料,像搜尋業務。要麼就是放在本地盤,放在本地的話做遷移的時候要自己處理資料的遷移,每個不同的業務處理的都不太一樣。還有一種方式是用遠端,資料遠端化。我們有分散式儲存系統“盤古”,通過容器建立的時候在遠端儲存叢集建一塊遠端盤,我們現在用的是塊裝置,然後掛載到容器裡面,容器用完或者是遷移的時候,資料是在遠端的,可以隨意遷移到另一個地方,再把這個資料盤掛載回來。
搜尋也可以放遠端,對於阿里各種搜尋場景,我理解如果replica數多的話,用遠端儲存是比較經濟划算的,如果replica數就1行,或2行,而且遠端效能又滿足不了部分場景的需求,短時間內就不如本地多塊盤來進行混部。總體趨勢來說,如果沒有效能要求的話,都放遠端是趨勢。Q:哪種方式會更多一些?A:宿主機直接到容器裡面,相對來說最大的場景是在資料庫,資料庫現在大部分是在本地,但是有一部分是放在遠端的,正在演進的過程中,還沒有百分之百完成儲存計算的分離。後面有一天可能就完全沒有本地資料了。Q:這是雲框架,一聽到雲這個架構就感覺很大,是一個什麼海量運維,海量資料,對於中小型公司規模可能沒那麼大,對於要想用這套框架,實施的成本是多少,使用者量在多少以下適合或者不適合?A:很難有明確的臨界點,說什麼時候該用雲化架構了。從中小型公司來說可以從第一天就往這個方向,或者是朝這個模式去實現。比如說搭一個很小的資源池,通過彈性混合雲的方式,在雲上去擴容,這也是一種很好的方式。如果第一天完全不考慮這些事情,怎麼方便怎麼搭建,也不考慮這些單點,容災這些彈性的事情,後面改造起來可能就會比較痛苦。
Q:這個部署的成本,兩個人或者三個人的研發團隊,用你這個東西周期有多長時間呢?它的難易度,因為要理解整個框架,你要部署這個東西要理解這個東西,我覺得學習的曲線還有部署的難度到底是什麼樣的?A:後面這套系統在做 Sigma 敏捷版就是解決中小企業的問題,兩三個開發者不可能開發出一套像現在這個規模的完整雲化架構,最好的是用雲上支援這些場景的產品。雲產品本身經過很多使用者的考驗,有這麼多雲上運作的一些經驗,一些技術上的沉澱,比自己開發要靠譜得多。
Q:我想問一下 PouchContainer 這個容器跟底層還會去封裝 Docker 之類的東西,我第一次接觸這個,另外映象庫的話是能夠跟 Docker 相容嗎?A:首先映象庫跟 Docker 是完全相容的,Docker 分了很多層,底層的 runV 和 containerd 都貢獻到了社群,是開源的,我們在 runV 和 containerd 的基礎上做了增強。總體來說是相容兩個社群的兩種主流的技術路線,兩種叢集管理系統,Kubernetes 和 Docker 公司 Swarm,這種兩種路徑都支援。本文轉載自公眾號: 阿里系統軟體技術,點選檢視原文。Kubernetes實戰培訓

640?

Kubernetes應用實戰培訓將於2018年10月12日在深圳開課,3天時間帶你係統學習Kubernetes本次培訓包括:容器基礎、Docker基礎、Docker進階、Kubernetes架構及部署、Kubernetes常用物件、Kubernetes網路、儲存、服務發現、Kubernetes的排程和服務質量保證、監控和日誌、Helm、專案實踐等,點選下方圖片檢視詳情。

640?