美團云的Docker實踐之路
本文根據美團云工程師鄭坤在2016.1.26北京容器大會上的分享內容整理
首先自我介紹一下,我是來自美團云的工程師:鄭坤。
很高興能和大家分享我們從去年(2015.6)到現在(2016.1)美團云在設計和開發上的一些思路和心得。
美團云是公有云提供商,我們從云提供商的角度來看,如何從云平臺端為用戶提供更好的Docker服務。不過今天分享的內容都是私有云場景下的,因為截止目前(2016.1)Docker還存在多租戶安全隔離問題,這個問題還不是很容易解決。
Why(我們為什么要用Docker?)
2012年美團上線私有云,2013年共有云正式上線,剛開始所有業務和交易都放在私有云上(KVM和VM),后來遷移到了Docker上,怎么說服內部要做遷移的呢?這里用美團的外賣業務舉個例子:外賣每天都有幾個時間段內峰值是很高的,為了支撐業務我們有提供彈性的需求,VM來做彈性的話效果不是很理想,scale out周期太長無法滿足,資源的回收也是個問題。Docker的輕量級/高效/敏捷靈活能很好的滿足需求。
How(MOS是怎樣使用Docker的?)
Docker發展了這幾年,生態鏈已經日趨完善:編排、倉庫、監控等都有很多startup在做,也已經做出了很多現成的東西。我們美團云內部有自己的控制器、registry、網絡、除了鏡像倉庫和身份鑒別用的是openstack的glance和keystone外,剩下的所有組建都是自己寫的,鏡像倉庫的后端也在開發計劃中。
現在主要問題是怎樣結合現有架構來使用Docker,在可接受的成本內如何發揮Docker自身的優勢來實現快速開發、部署和上線,然后不適合Docker的地方就盡量針對VM來做優化:主要是low latency、批量調度、啟動、創建等的流程的優化。詳細分為幾個部分:控制計算和調度架構用美團云現有的VM框架,鏡像倉庫和后端存儲為glance和swift,目標是支持Docker;然后宿主機要支持Docker;使用統一的配置方式來配置網絡;最后是隔離和鑒權,目前私有云對這方面要求不高。
如圖示美團云Docker系統框架,這個框架其實也是美團云的框架,為Docker和VM共同復用。共用框架的好處是我們可以用一個云平臺同時支持VM和Docker兩種不通的計算服務,有效降低我們的開發、運維的成本。Docker和VM復用的前提條件是一致的數據結構定義,統一的API接口規范。我們將Docker的鏡像、容器、網絡都用已有的VM對應的數據結構定義。整個系統框架由4部分構成:
- 客戶端
- 控制器
- 宿主機服務
- 鏡像倉庫
客戶端工具是一個CLI,有兩個接口:一個對Docker鏡像的管理接口,一個是對容器/set的管理接口。通過一個客戶端可以管理Docker鏡像,也可以控制容器的創建、刪除、啟動停止等操作。
控制器:Docker和VM復用一個控制器,負責API處理、Docker容器的數據庫管理,任務控制等計算服務
鏡像倉庫:負責Docker鏡像的存儲。分為兩個部分,Glance是數據庫和API,后端存儲是分布式的key-value存儲系統,由美團云自主開發。set,
宿主機服務:負責容器的控制執行、監控等功能。
所有組件都是通過RESTful API通信。
對于Docker的控制流,我們復用了原有的VM API,支持:create、start、stop、suspend、sync-status、delete、update、deploy等,然后rebuild_disk備份,重置密碼,傳文件都可以在容器當中執行。
云平臺上的基礎設施包括我們在宿主機上更好的儲存網絡、本地服務管理等等,Docker都可以復用。
如圖,我們看一下美團云Docker的相關組件,mcclient是我們的客戶端,自己開發的。keystone是openstack的,Region就是我們的控制節點;對象存儲swift,和一個自研的后端存儲,預計2016.3上線;host是自主開發, image glance 是openstack組件。從接入層來說,紅色的部分是我們做擴展的部分,藍色的部分是沒有修改的。控制層有兩個節點:一個是region是控制節點,還有glance image節點,glance image負責管理鏡像,所有Docker的鏡像操作都是由glance來控制的,由DB來提供維護的信息。容器我們把它當成是VM或者server,那它就由region來控制;主機端:Host server部分我們也做了擴展。
我們舉一個簡單的例子:一個鏡像查詢功能,我們怎么把查詢一個鏡像是否上傳、是否存在,綠色的線就是客戶端那邊通過RESTful API查詢glance,藍色的是鏡像,去查glance,glance這里會帶身份認證的keystone,然后它會去先拿token查glance,glance拿著這個token到keystone去認證,認證通過就去檢查數據庫,然后返回信息。所以說容器也是一樣,我們把容器當成VM了,所以指的是在region節點。
我們來看稍微復雜一點的,如上圖:一個容器的創建,可能這里面就有更多的細節。這個說一下,就是云平臺大家知道訪問的時候都需要鑒權的,第一步還是要獲取keystone去拿token,然后帶著token去發起post請求,這邊創建一個server的時候,它首先去glance查詢創建server的Docker load在不在,如果存在的話就把這個請求發到Host server,Host server去拿這個token的時候到glance拉Docker的鏡像,我們把這個鏡像通過Docker的pull 把它下到Docker的本地,這樣的話就完成了準備工作。然后這個流程回來的時候,再到region,如果這一邊就是auto start,那么region把這個調過來,把這邊啟動變成Docker start的一個API,這時在數據庫上這個容器就起來了。當然整個過程全是layer pull的API的形式,所有的流程都是自動化的。雖然過程看起來比較復雜,但實際上所有地方都很快。
剛才談到的是計算,現在來談一下存儲。
一個Docker鏡像實際上是由若干個子鏡像,或稱layer組成的,每個layer里面再打開,就發現里面是有若干個文件還帶一個reference文件。Docker鏡像的存儲,分層打包這一塊的創新是Docker的創新,Docker公司將這個申請專利了。Docker將底層存儲,鏡像打包,部署、存儲這一些列功能都做到了Docker daemon里,底層文件系統的細節,容器的namespace隔離細節,大家都不用關心。這里面有很多精妙的設計,docker commit之后,在container上面加了一層FS。Docker把FS這些復雜性的東西都屏蔽掉然后封裝起來。只要Docker pull、 Docker run就能搞定。所以Docker image包含了業務運行的一個環境配置,如果要把image保存到倉庫里,就可以把每一層layer看成是一個key-value的一個object對象,Glance實際上就是保存著key-value的一個object對象,每一層layer就當成一個對象,但是Glance每一個對象之間是沒有一個邏輯關系的,也就是說沒有一個邏輯來組織這些鏡像。一個Glance的一個VM鏡像就是一個VM鏡像。所以它跟Docker不一樣,因為Docker是由N個鏡像組成的,我們做的事情就是把Docker做成像Glance這樣簡單化,我們把Glance加了一個Docker ID,即每個鏡像都帶一個ID,它可以指向它到父鏡像,也就是每一層layer都單獨保存并記錄它們的繼承關系,然后保存到Glance數據庫中,這樣我從Glance上去查Centos的時候,對應這個parent,我把這個layer一層層顯示出來,和我們用Docker image是一樣的。
接下來談談網絡。
網絡是另一大塊標準化突破,大家都用Docker的一個原因是Docker的靈活性,給大家提供了靈活性。網絡Docker支持四種網絡配置模式,美團云選擇了None,也就是說在宿主機上可以看到,云服務商你們買VM,網絡和IP是云服務商提供的。所以我們分給容器更多的IP,我們內部網絡,二層網絡我們自己做,那這個IP從來沒有通,我們就需要在容器的配置上把這個網絡,這個IP配進去。先講一下宿主機網絡,美團云的宿主機網絡是用OVS做本地管理的,OVS一端連著物理接口,從網卡出去直接到物理交換機。另一層通過port連接本地的VM。容器也是一樣的,在啟動的時候創建一個eth pair,然后把它放到容器的Namespace里面,另一端接入到OVS當中,然后我們的網絡隔離是在OVS的flow table上做的,這是一個事先做好的,只要網絡配好,容器會自動帶有網絡隔離的功能。我們對網絡的限流、限速是在eth這個物理網卡跟tc這塊來做,這樣做之后,原來對VM的這些flow table全都在Docker上自動生效,不需要為限速等功能做額外的開發。
我們再來說說set。
先講一下PaaS,我們之前調研過業界PaaS平臺,包括主流的Kubernets,對我們來說,k8s太大了,過于復雜,需要專業的團隊搭建集群,運維,開發。短期內難以滿足我們快速迭代、快速定制功能滿足需求,以及穩定性的要求。我們更傾向于利用現有的云平臺,采納k8s比較先進的設計思想,通過擴展云平臺來支持我們的PaaS。經過調研,我們發現k8s有很多可以借鑒的地方,比如說Pod。Pod設計上一個很先進的地方在于它很適合微服務,一個Pod由多個容器組成,對應一個微服務,Pod內的容器是共享網絡和volume的,因此一個微服務內的通信成本是非常低的。結合美團的業務來說,我們的每一個線上服務都是標準化的,即一個服務是由若干個進程組成的。典型的服務包含幾個進程:infra進程、sg-agent進程和app進程。
infra 進程:負責網絡、volume配置
sg-agent進程:負責日志收集工作和其他支撐服務
app進程:負責具體的業務。
在VM環境里,一個服務的幾個相互依賴的進程最好放到一個VM內,而對于Docker,這幾個進程最好放到一個容器內。但Docker的哲學是一個容器跑一個進程。自然就聯想到Pod。我們把幾個容器抽象成一個Pod,部署到一個宿主機上,容器之間共享網絡,共享volume。Set,可以說是我們美團云版本的Pod,它是調度的基本單位,你不能將set內的幾個容器調度到不同的宿主機上。它代表一個微服務實例,所以業務的擴容、縮容,都是以set為單位的。
最后介紹一下項目發展情況,私有云方面,我們在和另外一個基于Docker彈性伸縮的開發團隊合作,他們調用我們的接口實現業務的彈性擴容縮容,目前在公司內部已有一些用戶,2016年將大規模推廣。公有云方面,2016年將接入美團云的PaaS服務。
我們2016年的規劃,項目從2015年開始調研,立項,開始開發,上線私有云;2016年準備接入RDS,上線公有云調研,開發。