阿里如何實現100%容器化鏡像化?八年技術演進之路回顧

八年時間,阿里集團實現了 100%內部容器化鏡像化,經歷了幾代演進。本文將從最初的架構開始,向你們介紹下阿里內部的容器化演化過程。linux

PouchContainer 如今服務於阿里巴巴集團和螞蟻金服集團的絕大部分 BU, 包括交易&中間件,B2B/CBU/ICBU,搜索廣告數據庫,還有收購或入股的一些公司,好比優酷高德、UC等。其中體量最大的是交易和電商平臺,在 2017 年雙 11 的時候咱們支撐了破紀錄的峯值,背後的應用都是跑在 PouchContainer 裏面,總體容器實例已經到了百萬級規模。使用了 PouchContainer 的應用涵蓋了各類各樣的場景。這些場景從運行模式來看,有標準的在線 App,還有像購物車、廣告、測試環境等比較特殊的場景。不一樣的場景對 PouchContainer 有不一樣的使用方式和需求。git

從編程語言看,實際運行着 JAVA、C/C++,Nodejs,GoLang 等語言編寫的應用。從技術棧的角度看,包含了電商、DB、流計算、大數據、專有云等場景,每一個場景對於容器各方面要求,所用到的特性都不太同樣,PouchContainer 針對每一個場景的需求都在產品上都作了支持。github

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 的鏡像機制來完善本身的容器。

clipboard.png

在將 Docker 鏡像整合進來以後,原來基於 T4 的研發運維體系受到了很大的衝擊。 首先交付方式變了,以前是 build 一個應用的代碼包,把代碼包交給咱們的部署發佈系統,後者建立一個空的容器,根據這個業務所在的很薄的模板把一個空的容器跑起來,再到容器裏面安裝依賴的一些 IPM 包,設置一些配置,按每一個應用定好的一個列表一個一個的安裝好,而後把應用包解壓啓動起來。這個應用依賴的軟件和配置列表咱們內部叫作應用的基線。

引入鏡像以後,在將 Docker 鏡像整合進來以後,原有的交付方式發生了變化。以前是 build 一個應用的代碼包,把代碼包交給咱們的部署發佈系統,後者建立一個空的容器,根據這個業務對應的很薄的一個模板,把一個空的容器跑起來,再到容器裏面安裝依賴的一些 RPM 包,設置一些配置,按每一個應用定好的一個清單一個一個的安裝好,而後把應用包解壓到主目錄啓動起來。這個應用依賴的軟件和配置清單咱們內部叫作應用的基線。引入鏡像以後,咱們應用的代碼包和依賴的全部的這些三方軟件、二方軟件都會打成一個鏡像。以前經過基線維護應用依賴環境,如今都放到每一個應用本身的 Dockerfile 中了,整個研發構建和分發運維的過程大大簡化了。

作了這個事情以後,研發和運維之間的職責和邊界就發生了變化。以前研發只須要關注功能,性能,穩定性,可擴展性,可測試性等等。引入了鏡像以後,由於要本身去寫 Dockerfile,要了解這個技術依賴和運行的環境倒底是什麼,應用才能跑起來,原來這些都是相應運維人員負責的。研發人員本身梳理維護起來後,就會知道這些依賴是否合理,是否能夠優化等等。

研發還須要額外關注應用的可運維性和運維成本,關注本身的應用是有狀態的仍是無狀態的,有狀態的運維成本就比較高。這個職責的轉換,能夠更好的讓研發具有全棧的能力,思考問題涵蓋運維領域後,對如何設計更好的系統會帶來更深入的理解。因此引入 Docker 以後對研發也提出了新的要求。咱們總結新的時期,新的運維模式下對研發能力要求的幾個要素,總結起來就是幾個原則:

clipboard.png

爲了更好地把本身的系統建設好,咱們要倡導研發從第一天創建系統的時候,就要考量最終的可運維性,好比參數是否可配置,是否能夠隨時重啓。機器天天都有硬件故障產生,這些硬故障不可能天天都人工處理,必需要儘量自動化處理,自動化處理時,雖然有些故障隻影響了一部分實例,另外一部分是好的,可是也可能須要一塊兒處理,物理機上的業務所有遷移走來修物理機。因此無論當時容器裏的業務是好的仍是很差的,都要接受隨時可重啓,可遷移。原先是部分交付,如今要考慮你到底運行環境是什麼樣的,什麼樣的運行環境才能跑起來,儘可能作標準化的操做。

好比說啓動,Dockerfile 裏面寫好啓動的路徑,不要再搞一些特殊的處理,若是有任何特殊的處理都無法作統一的調度和運維。統一的業務遷移,機器騰挪也無法作。咱們最後的目標其實就是從一開始的比較粗放的運維到不少人都能介入,到最後的自動化不斷的開發自動化的工具,造成一個體系,經過前期人工運維的過程把一些固定的故障處理的流程模式化,最後提取出來一些能夠自動處理故障自動恢復的機制,最後咱們的目標是無人職守。全部這些加起來其實就是咱們引入鏡像化以後,而且要朝着無人值守的方向演進時,對研發和運維的新的要求。

clipboard.png

上面是 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,用於一些多租戶的場景

clipboard.png

阿里內部的離在線混部之因此能推動,在同一個機器上既能跑在線的業務又能跑離線的一些任務,互相之間不會出現太大的干擾,其核心的技術就是 PouchContaienr 容器能夠根據優先級,把不一樣業務的資源使用隔離開來,保證在線業務優先使用資源。這個資源包括不少的維度,好比 CPU、內存,CPU cache、磁盤、網絡等等。

clipboard.png

這是 PouchContainer 的鏡像分發設計。咱們內部有不少比較核心的應用,體量比較大,實例會分佈在上萬臺物理機上。發佈新版本的時候上萬臺機器同時拉鏡像,任何中心的鏡像倉庫都扛不住。所以咱們設計了一套鏡像分發的二級架構,在每一個地域建一個 mirror,在同一個地域內拉鏡像的時候用 P2P 分發技術---咱們內部的產品名叫蜻蜓,已經開源;須要拉鏡像的服務器之間能夠分散互相拉文件片斷,這樣就直接化解了中心鏡像倉庫的服務壓力和網絡壓力。

後面其實還有更好的解決鏡像分發的思路,咱們正在嘗試鏡像的遠程化,經過存儲計算分離技術,用遠程盤的方式掛載鏡像,直接跳過或者說異步化了鏡像分發這一步,目前正在內部環境灰度運行中。

clipboard.png

這是 PouchContainer 內部版本的體系結構。在最底層的宿主機層面,咱們會作一些管理和運維,目的是爲了確保容器運行依賴的基礎環境是健康的,包括宿主機的一些鏡像清理,包括安全控制、權限管理等。OS 的低版本內核咱們是適配到最低 2.6.32 內核,包括容器裏面的進程管理也作了不少的適配。資源隔離前面講過了,網絡模型咱們內部其實主體用的是 Bridge,可是其餘各類各樣的場景也都支持。

咱們開發了不少插件,PouchContainer 開源後,咱們纔將這些插件逐步作了標準化,兼容適配了社區的 CNI 標準。最上層是一個富容器模式的支持,每一個容器裏面會啓動一些跟內部的運維工具,運維繫統息息相關的一些組件,包括一些發佈模式的優化。能夠看到咱們內部體系結構是比較複雜的,尤爲依賴內部的其餘系統比較多,在外部直接跑是跑不起來的,所以也無法直接開源。

clipboard.png

因此咱們開源版本是從新開始搭建的,這樣會比較清爽一些。咱們引入了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/po...

最近 PouchContainer 開源版本 GA 已經發布,PouchContainer 可以在如此短的時間內 GA,離不開容器社區的支持,在超過 2300 個 commit 的背後,有 80 多位社區開發者的踊躍貢獻,其中不乏國內一線互聯網公司、容器明星創業公司貢獻者的參與。

PouchContainer 開源版本發佈 GA 以前,此開源容器引擎技術已在阿里巴巴數據中心獲得大規模的驗證;GA 以後,相信其一系列的突出特性一樣能夠服務於行業,做爲一種開箱即用的系統軟件技術,幫助行業服務在推動雲原生架構轉型上佔得先機。

【Q&A】

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,這種兩種路徑都支持。

本文做者:林軒

閱讀原文

本文來自雲棲社區合做夥伴「阿里技術」,如需轉載請聯繫原做者。

相關文章
相關標籤/搜索