在容器技術改造與應用上,美團雲如何做到擇善而從?
1、私有云壓力
先介紹一下私有云面臨的問題。私有云承載著美團自己的業務。美團業務一個最大的特點是業務流量有非常明顯的週期性和突發性。比如外賣或者團購每天都有上午和下午兩個請求高峰,夜間則請求量很低。同時還有一些突發情況導致的突發流量,例如情人節,七夕等活動大促。還有美團點評有一些直播,一開直播,馬上就會有一些突發的請求流量。另外一些異常天氣也會引起突發的請求流量。例如, 在下雨、下雪等異常天氣時,外賣流量會比平時高很多。這些特點就要求我們的業務容量必須要做N倍的冗餘。我們規劃系統容量時,不能僅按照平常的波峰來設計,還得在這個基礎上高2~3倍,這樣才能應對突發的業務請求。
雖然美團點評的主機已經完全虛擬化,交付效率已經比較高,但面對這樣突發的業務請求,這樣的交付效率還是無法滿足在高峰來臨前立即分配資源來應對突發業務的需求。因為雲平臺交付給業務的還是虛擬機器,交付完之後業務還需要做很多操作,包括環境部署、程式碼釋出,配置變更等。所以一般虛擬機器交付業務團隊之後,他們就不太願意把虛擬機器還回來,一般在做擴容之後就不再會縮容。
為了應對突發流量,剛才說需要按照峰值的2到3倍冗餘去部署。用虛擬機器的方式,系統容量就是峰值的2到3倍,這些冗餘的處理能力在平時是用不了的,但也不會被釋放,所以就出現了資源的浪費。這就導致我們希望能夠更自動化的讓應用部署起來,更自動化地讓業務能夠提供服務,這樣可以讓業務系統容量彈性起來,降低系統資源的浪費。
2、公有云壓力
同時,公有云也面臨一些變更效率的問題。美團雲的公有云業務除了基礎的雲主機產品之外,還會提供PaaS產品。一個典型的PaaS產品就是MySQL的RDS服務例項。比如使用者購買一個MySQL例項,後臺會自動化為他建立一對一主一從的虛擬機器,裡面部署一對主從同步的MySQL例項,對使用者提供MySQL資料庫服務。用虛擬機器實現這種PaaS產品的問題是,虛擬機器的部署時間比較長,達到分鐘級。使用者提交一個建立MySQL的請求,需要建立兩個虛擬機器,上面部署MySQL,等待他們啟動,啟動完了使用者才開始使用,整個流程需要幾分鐘。擴容流程也很複雜,這裡給了一個擴容流程的簡單示例。
兩臺主備的MySQL例項,如果要擴容CPU和記憶體,需要首先關機擴容備份節點,備份節點擴容完成啟動後啟動,與主節點追同步,等資料同步完成,開始做主備切換,切換完成後,關機擴容原來的主節點,擴容完成啟動後,再次追資料同步,整個一個擴容也可能要十幾二十分鐘的時間,流程太長,也容易出錯。
3、對容器技術的調研與考量
通過調研,發現容器技術能夠幫助我們解決以上問題。
(1)虛擬機器和容器的區別
首先,我們調研了虛擬機器和容器的區別。上圖的左邊是虛擬機器的架構。虛擬機器是在宿主機上虛擬出一個個的虛擬機器例項。每個虛擬機器是一個完整的主機,包括虛擬硬體,作業系統核心,使用者態環境。一個虛擬機器啟動需要等核心啟動,然後虛擬裝置、應用環境準備好,應用才能啟動執行。因此虛擬機器的啟動時間較長。右邊是容器。容器虛擬化的是應用環境,容器裡的程序其實還是共享宿主機的核心,但通過Linux namespace偽造了一個獨立的執行環境,讓執行在容器裡的應用感覺自己是在一個獨立的執行環境裡面。啟動一個容器,其實就是在宿主機上啟動了一系列程序。這些程序啟動後,立即就能提供服務。因此,容器的啟動速度要大大快於虛擬機器的啟動速度。
與此同時,因為虛擬機器需要從通過虛擬化的硬體裝置去訪問底層的硬體裝置,所以它的磁碟IO和網路虛擬化的消耗都很高,效能不如容器。我們做過虛擬機器和容器的效能對比測試。在同一臺宿主機上對比同樣配置的虛擬機器和容器,在磁碟IO上,虛擬機器的效能大概是容器的80%到90%。
(2)容器映象
容器除了上面說的特性外,還有一個更好的特性,就是容器映象。雖然容器技術出現非常早,在80年代就已經有類似容器的技術出現。但2013年、2014年出現的Docker容器才讓容器技術火爆起來。
Docker最大的亮點就是 Docker映象。Docker映象能夠把應用和執行環境一起打包交付,容器啟動後應用立即就能執行,不需要做額外的配置,真正做到build once,run anywhere。同時Docker映象是分層的。一個Docker映象可以基於更基礎的Docker映象構建,儲存這個映象的時候,會把差異部分做為一個層和基礎映象的層一起打包。拉取映象時,只會拉取映象倉庫中不存在的層次。
例如一個Java Tomcat web app的Docker映象,一般是四個層次,最底層是基礎的Linux執行環境,第2層包含了Java執行環境和配置,第3層包含了Tomcat的執行環境和配置,最上層則是web app的war包。當第一次部署時,會把整個映象的4個層次都拉取到本地映象倉庫,之後應用升級時,構建Docker映象一般就更新第4層的war包。這樣後續部署,則只會拉取變化的第4層,那麼拉取的資料量就大大降低了。通過分層和按需拉取的機制,Docker映象使得容器能夠做到秒級啟動、非常高效地部署一個獨立的應用環境。
我們在虛擬機器時代交付的是一臺虛擬機器,使用者獲得虛擬機器之後,先要部署執行環境,然後再部署應用才能夠使用。但到了容器時代,這個流程就大大簡化了。使用者提交應用程式碼後,系統就會自動把程式碼編譯打包成一個Docker映象。使用者擴容系統時,系統只需要拉取應用的映象,啟動容器,應用立刻就可以提供服務了。原來基於虛擬機器的擴容是小時級別,使用者不願意縮容。但用了容器技術之後,擴容秒級完成。容器的這個特點可以幫助我解決私有云彈性的問題。
(3)容器資源限制的技術
下面說一下容器資源限制的技術。容器使用Linux核心的cgroups技術對每個容器的資源在核心層次做限制。比如一個容器,它最多能用多少記憶體、多少CPU資源、多少IO頻寬等。這個限制方式也跟虛擬機器不一樣。虛擬機器的資源限制是在虛擬機器啟動時指定的,一般不能在啟動之後更改。要變就得先關閉虛擬機器,然後用新的引數重新啟動。對於容器,對資源限制的變更是非常低代價的,比如啟動了一個4G的容器,現在想改成8G的,核心裡cgroups的記憶體限制引數從4G改成8G就可以,容器不需要做任何改變。因為這個特點,更改容器的配置效率也非常高,基本沒有任何代價。所以前面說到的PaaS遇到的配置變更效率的問題也迎刃而解。
基於以上的原因,我們在2015年中開始著手實施美團雲平臺引入容器技術。這個過程並不是一帆風順的,也遇到了一些技術困難和技術切換的挑戰。容器技術雖然很火,但它其實是個不斷髮展、不斷成熟的過程。整體上容器的特性都不錯,能夠解決我們的問題,但在細節上還存在不少缺陷和問題,把容器整合在雲平臺上也需要很多工作。
三、美團雲的容器實踐之路
我們引入容器的初期,確定了一個切合實際的目標和執行策略。
首先定了一個初始目標,要實現一個統一的虛擬機器和容器的管理平臺,把公司的資源作為一個整體的資源池提供給虛擬機器和容器使用,避免資源的碎片化。同時要能夠實現業務容器的一鍵釋出,無需人工干預,從而支援業務的秒級擴容和縮容,不再需要預留資源。
其次,在推進策略上,前提是“穩”字當先。因為我們的雲平臺是給美團的自有業務,同時對外給使用者使用,都是真正的生產環境,不能出現偏差。基於這個“穩”字,我們的策略第一是基於美團現有的雲平臺去升級改造,讓它能夠支援容器。先做好架構,再去優化。基於這樣的策略路徑,我們開始把容器引入到美團雲。
1、對Docker技術的改造
首先,我們沒有因為容器再去新引入一套雲管理的平臺,而是基於美團已有的比較成熟的雲平臺開發改造,提供對容器的支援。因為虛擬機器和容器的區別主要體現在映象、建立、變更、刪除等方面,在整體雲平臺的視角看,引入容器只是給雲平臺增加了另外一種計算資源的交付方式。雲平臺現有的很多元件,例如資源管理,排程,虛擬網路管理,任務管理等方面,技術上基本都是一致的, 完全可以複用現有云平臺的元件。只有在容器獨特的地方,比如映象管理、容器生命週期管理等這些方面,我們加入新的程式碼和元件,讓我們的雲平臺能夠支援 容器的管理和執行。這樣可以最小風險地引入容器,並迅速實現大規模的部署,並且和虛擬機器共享資源池。避免了因為引入新的雲管理平臺在資源池管理,排程、虛擬網路等方面必然出現的磨合和折騰。
其次,在容器技術上選用的是Docker 1.11版本,並且把版本固定下來,在這個版本的基礎上修正發現的BUG,並針對美團雲的需求進行改造。我們沒有選擇跟隨社群的最新版本,這樣也能最大程度地低降低跟隨社群引入不穩定因素的風險。我們修正了Docker的一些常見問題,比如說Docker一個比較大的問題是Docker Daemon退出會導致管理的所有容器退出,這對生產環境的穩定有致命的影響,因此我們在這方面做了改進。
同時容器在某些資源限制上並不支援持久化,在容器重啟之後就重置了,我們也做了相應的改造。支援美團雲的底層網路,我們開發了MosBridge讓Docker支援美團雲的虛擬網路。另外也改造了Docker registry mirror,以支援後端儲存使用美團雲的雲端儲存。還有一些其它擴充套件,這裡就不詳細介紹。總之,我們基於Docker1.11維護了一個相對穩定可靠、符合美團對容器需求的Docker版本。
2、構建容器化生態環境
除了改造Docker技術外,為了讓Docker能融入到美團整體的研發流程裡,我們還需要構建一個容器化的生態環境,從而讓容器能夠被使用者使用。
首先, 在公有云,我們通過PaaS產品來讓使用者使用上容器。在私有云,則通過公司其他部門負責的元件,主要是PLUS和HULK兩個元件,來讓業務接入容器。其中,PLUS負責程式碼倉庫的維護和容器的構建,HULK負責業務的彈性伸縮。另外,還需要改造公司的應用釋出流程,以支援容器化的流程。在這個過程中,比較頭疼的一個問題是從虛擬機器切換到容器,容器映象的打包由誰來負責。如果我們用原生的Docker映象的打包方式,就需要使用者自己去寫Docker file,根據自身業務應用的特點編寫Docker file,由研發負責Docker映象的打包。但是,這要求所有研發要去學習Docker技術,不太切實可行。
因此,我們其實是把Docker映象打包放在PLUS系統中實現。對業務來說研發還是把程式碼提交到倉庫,但增加了一個構建映象的步驟,PLUS的構建系統會自動構建出包含業務程式碼的Docker映象。當業務釋出時,原來是釋出釋出程式碼,現在釋出的是Docker映象。這樣,我們把做映象的流程放到以前釋出流程裡,Docker映象對研發透明化了,這樣就能讓業務比較平滑地從以前的基於虛擬機器的業務釋出流程切換到基於容器的釋出流程中去。
3、實施效果評估
經過多個團隊的努力,容器化取得了一些初步的效果。到2015年11月,雲平臺對容器的支援基本開發上線了,同時HULK PLUS團隊開始基於雲平臺的容器開始業務流程改造。2016年3月,HULK的彈性伸縮服務上線。2016年6月,公有云的PaaS產品也開始逐步接入容器。
美團業務容器化後效果初步顯現。首先表現在效能方面。由於虛擬化開銷降低,同配置的容器提供的服務的能力提高了。單機QPS可以提高85%。更重要的是,通過彈性伸縮,為應對業務高峰的資源預留不再需要那麼高的榮譽度了。引入容器之後,業務的服務例項數量是動態變化的,每天比如說在業務高峰來臨前面擴容上去,訂單數下降後,這些容器就被銷燬。通過基於容器的彈性伸縮服務,平均資源佔用大約降低30-60%。
同時,PaaS產品通過容器部署也有較明顯的收益。首先是效能有一定的提高。而最明顯的是例項部署時間的降低。原來基於虛擬機器部署MySQL例項可能要3分鐘,通過容器化後30秒就能夠部署成功。配置變更的代價則幾乎可以忽略。把MySQL例項從2核4G提高到4核8G,只要改一下cgroup配置就可以了,瞬間完成。但如果是虛擬機器,就得經過關機、切換這麼一個複雜的過程。
四、未來的發展思路
綜上所述,通過引入容器技術,我們解決了一些基於虛擬機器無法解決問題,收益明顯。後續還會繼續深入容器在業務中的應用。
首先是會進一步提高資源利用率。目前容器主要是針對線上業務的彈性伸縮,下一步希望能夠把了離線/線上業務混部,探索通過離線業務的削峰填谷,進一步提高資源利用率。離線業務的一個特點是不要求實時性,只要在某個時間點之前輸出結果即可。目前公司的線上業務和離線業務叢集還是分開部署的,所以離線叢集的資源在離線計算不需要時,其實也是空置浪費的。所以,下一步希望把離線和線上的業務也能混合部署在一起。當線上業務繁忙時,離線業務就把資源讓出來;當線上業務處於業務低谷時,離線業務再全速執行。這樣能進一步提高資源的利用率,節省成本。
其次,公司整體研發流程圍繞容器的重構和再造。現在我們只在生產環境引入了容器,實現線上業務自動化的彈性伸縮。我們希望能把容器引入到研發的全流程,從開發、測試到真正生產環境,都基於容器。不僅開發時用容器環境開發,測試時也是通過自動化Docker映象的方式釋出到測試環境測試,這樣就保證了我們測試環境和生產環境的流程一致,更進一步提高研發的效率。
文章來自微信公眾號: DBAplus社群