天天看點

阿裡超大規模Docker化之路

12月6-7日,由阿裡巴巴集團、阿裡巴巴技術發展部、阿裡雲雲栖社群聯合主辦,以“2016雙11技術創新”為主題的阿裡巴巴技術論壇上,阿裡巴巴研究員林昊分享了阿裡超大規模docker化之路。阿裡在docker化這條路上,碰到了規模、多元化場景所帶來的各種挑戰,這次分享中将給大家介紹阿裡為什麼要引入docker,以及如何完成這次超大規模的docker化。

阿裡超大規模Docker化之路

docker化之前

docker化之前,阿裡主要交易業務已經容器化。采用t4做容器化,t4是2011年開發的一套系統,基于lxc開發,在開發t4的過程中,跟業界很大的不同在于,t4更像vm的容器。當使用者登進t4後,看起來與标準的kvm等幾乎完全一樣,對使用者來講是非常透明化的。是以,容器化不是我們推進docker的原因。

a)觸發我們docker化的主要原因一:docker最重要的一點是鏡像化,可以做到拿着鏡像就可以從一台完全空的機器的應用環境搭建起來,可以把單機環境完全從零搭好。docker化之前,阿裡巴巴的應用部署方式主要由java、c來編寫的,不同的業務bu可能采用完全不同的部署方式,沒有統一标準。内部嘗試通過基線來建立部署标準,定義的基線包括應用依賴的基礎環境(os、jdk版本等)、應用依賴的腳本,基礎環境的配置(啟動腳本、nginx配置等)、應用目錄結構、應用包、應用依賴的dns、vip、aci等,但不成功。部署标準做不了,直接導緻自動化很難做到。

b)觸發我們docker化的主要原因二:devops是一個更好的方向,阿裡巴巴做了很多運維和研發融合的調整。docker是幫助devops思想真正落地的一種手段,所有的思想最終都展現在工具或架構上,變成一個強制性的手段,docker會通過dockerfile的描述,來聲明應用的整個運作環境是怎樣的,也就意味着在編寫dockerfile過程中,就已經清楚在不同環境中的依賴狀況到底是怎樣的,而且,這個環境是通過一個團隊來維護的。

docker化目标

2016年7月,阿裡巴巴制定了兩個docker化目标:

交易核心應用100%docker化;

db其中一個交易單元全部docker化。

docker化之路

推進dcoker之前,我們有一個準備的過程。在準備階段,我們需要docker更像vm和更貼合阿裡運維體系的docker,我們将改造過的docker稱為alidocker;除了alidocker以外,我們需要支援alidocker的工具體系,比如編譯、鏡像庫、鏡像分發機制,在完成這些準備工作後,我們認為可以一帆風順地開始大規模的alidocker上線。但事實并非如此。

第一輪docker化

我們碰到了很多問題:

工具不完善,阿裡很多應用之前都是在t4容器中,怎樣将t4容器轉換成alidocker是首要面臨的問題;

鏡像build後上傳,以前阿裡一個應用轉成多個,很多時候需要在自己的機器上做build,然後自己上傳,導緻做應用時很痛苦;

應用從t4切換成走docker的鍊路,鍊路沒有完全準備好,從資源建立到釋出,很多需要手工去做,大規模去做效率非常低。

第二輪docker化

在推進的過程中,我們又遭遇了新的問題。docker的釋出模式是典型的通過鏡像,拉到鏡像後将原來的容器銷毀,重新建立一個容器,把鏡像放進去,拉起來。docker單一化的釋出方式支援不了多種釋出模式,更改velocity模闆釋出效率低;有本地記憶體cache的釋出,重新開機本地記憶體cache就會消失。怎樣在基于鏡像模式情況下又能支援多種釋出模式呢?

我們在docker的鏡像模式基礎上做出一個crofix的模式,這個模式不是繞開鏡像,而是從鏡像中拉起我們需要的檔案,去做覆寫等動作,這樣就可以完成整個釋出。docker化鏡像模式是必須堅持的,否則失去了docker化的意義。

第三輪docker化

繼續推進到很多應用切換到docker的時候,我們又遇到了更大的問題:

首先,很多研發人員都有明顯的感受,切換到docker後變慢。第一,編譯打包鏡像慢,編譯打包完應用的壓縮包後,還需要把整個環境打包成鏡像,這是在原有基礎上增加的過程,如果編譯時每次都是新機器,以前依賴的所有環境都要重新拉,一個應用docker的完整鏡像通常會很大,因為它包括依賴的所有環境。

對此,我們在編譯層做了很多優化,盡可能讓你每次都在之前編譯的基礎上進行編譯。第二,鏡像壓縮問題,go在1.6以前的版本壓縮是單線程,意味着壓縮整個鏡像時效率會非常低,是以我們選擇暫時把鏡像壓縮關閉掉。

其次是釋出問題,docker的鏡像化模式決定了分發一定是鏡像分發,使用docker時不能完全把它當作透明化東西去用,對所有研發人員來說,要非常清楚依賴的環境、dockerfile中鏡像的分層改怎麼做,将頻繁變化部分與不頻繁變化部分做好分層,鏡像分層是改變docker慢的重要方案;

阿裡制定了鏡像分發多機房優化,比如打包後将所有鏡像同步到所有機房;阿裡也做了釋出優化(p2p、鏡像預分發、流式釋出),還通過docker volume将目錄綁定到dockerfile中,可以保證鏡像檔案每次拉起時不會被删掉。

在整個docker化的過程中,我們在“慢”這個問題上遇到了最大的挑戰,不管是編譯慢還是釋出慢,都做了很多突擊的改造項目,最後才讓整個編譯過程、釋出過程在可控的響應速度内。

第四輪docker化

在推進過程中,我們還遇到規模問題:

由于規模比較大,開源軟體很容易碰到支撐規模不夠,穩定性差的問題。目前我們使用swarm來管理,swarm的規模能力大概可以支撐1000個節點、50000個容器,而我們需要單swarm執行個體健康節點數在3w+,對此,我們對swarm進行了優化。

阿裡超大規模Docker化之路

規模我們做到從支撐1000到3w+,壓力減小了很多。而swarm的穩定性對我們來講,最大的問題在ha上,一個swarm執行個體如果挂掉,重新拉起需要時間,是以我們在用swarm時進行了改造。在前面加了一層proxy,不同業務、不同場景都可以通過proxy轉換到自己不同的swarm執行個體上。另外,所有的swarm節點我們都會用一個備方案在旁邊,而且都是不同機房去備。

通過改造增強ha機制後,可以做到每次切換、簡單釋出。

bugfix和功能增強

除了上面四輪次比較明顯的問題,在整個docker化過程中,還做了很多的bugfix和功能增強,具體有以下幾方面:

daemon更新或crash後,所有容器被自動銷毀的問題;

cpuset、cpuacct和cpu子系統mount到一起時cgroup操作錯誤的bug;

支援基于目錄的磁盤配額功能(依賴核心patch);

支援制定ip啟動容器,支援通過dhcp擷取ip;

支援啟動容器前後執行特定腳本;

支援鏡像下載下傳接入各種鍊式分發和内部mirror的機制;

增加docker build時的各種參數優化效率和适應内部運維環境;

優化engine和registry的互動。

經曆了這麼多坎坷,我們終于完成了全部目标,實作雙11時交易所有核心應用都alidocker化,db其中一個交易單元全部alidocker化,生産環境共幾十萬的alidocker。

未來

容器化的好處是可以把很多對實體機型的強制要求虛拟化,可能也需要docker在核心層面的改造,對于未來,我們已經做好了準備,希望:

所有軟體alidocker化;

和docker公司緊密合作回饋社群;

alidocker生态體系逐漸輸出到阿裡雲。

本文作者:林昊,花名畢玄

來源:51cto