溫哥華OpenStack Summit,Container/Docker成為一大關注焦點,OpenStack基金會除了表示將接受Container和Google Kubernetes等容器管理平臺,還積極推進Magnum子項目,在技術上實現(xiàn)容器與OpenStack的深度整合。由此,容器取代OpenStack的說法不攻自破。讓我們來看一篇根據Magnum的Core Member劉光亞在Open Cloud 2015上的發(fā)言整理的文章,詳細了解OpenStack與Docker的集成和各相關子項目的優(yōu)劣。文章原載《程序員》電子刊,全文如下:
OpenStack和Docker
OpenStack和Docker之間是很好的互補關系。Docker的出現(xiàn)能讓IaaS層的資源使用得更加充分,因為Docker相對虛擬機來說更輕量,對資源的利用率會更加充分。如圖1所示。
圖1 OpenStack和Docker的關系
從圖1可以看出,Docker主要針對Paas平臺,是以應用為中心。OpenStack主要針對Iaas平臺,以資源為中心,可以為上層的PaaS平臺提供存儲、網絡、計算等資源。
圖2 OpenStack項目的層級關系
OpenStack中按照層來分級的一些項目,如圖2所示。圖2從下往上看:
第一層是基礎設施層,這一層主要包含Nova、Glance和Keystone,如果我們要想得到最基本的基礎設施的服務,必須安裝部署這三個項目。
第二層是擴展基礎設施層,這一層可以讓我們得到更多跟基礎設施相關的高級服務,主要包含Cinder、Swift、Neutron、Designate和Ironic等,其中Cinder提供塊存儲,Swift提供對象存儲,Neutron提供網絡服務,Designate提供DNS服務,Ironic提供裸機服務。
第三層是可選的增強特性,幫用戶提供一些更加高級的功能,主要包含Ceilometer、Horizon和Barbican,其中Ceilometer提供監(jiān)控、計量服務,Horizon提供用戶界面,Barbican提供秘鑰管理服務。
第四層主要是消費型服務,所謂的消費型服務,主要是指第四層的服務都需要通過使用前三層的服務來工作。
第四層主要有Heat、Magnum、Sahara、Solum和Murano等,其中Heat主要提供orchestration服務,Magnum主要提供容器服務,Sahara主要提供大數據服務,我們可以通過Sahara很方便地部署Hadoop、Spark集群。Solum主要提供應用開發(fā)的服務,并且可以提供一些類似于CI/CD的功能。Muarno主要提供應用目錄的服務,類似于App Store,就是用戶可以把一些常用的應用發(fā)布出來供其他用戶去使用。最右邊是Kolla,Kolla的主要功能是容器化所有的OpenStack服務,便于OpenStack安裝部署和升級。
OpenStack中和Docker有關系的項目如圖3所示。
圖3 OpenStack中和Docker有關系的項目
主要包括Nova、Heat、Magnum、Sahara、Solum、Murano和Kolla等。由圖3得知,和Docker相關的大部分項目都在PaaS和SaaS層。以下主要分別說明Nova、Heat、Magnum、Murano和Kolla。
Nova Docker Driver
如圖4所示,這個Driver是OpenStack和Docker的第一次集成,主要是把Docker作為一種新的Hypervisor來處理,把所有的Container當成VM來處理。提供了一個Docker的Nova Compute Driver,集成很簡單,通過Docker REST API來操作Container。
圖4 Nova Compute Driver,OpenStack和Docker的第一次集成
這個Driver的優(yōu)點是實現(xiàn)比較簡單,只需要把Nova Compute中的一些對虛擬機操作的常用接口實現(xiàn)就可以,現(xiàn)在主要支持創(chuàng)建、啟動、停止、Pause、Unpause等虛擬機的基本操作。因為Nova Docker Driver也是一個Nova的Compute Driver,所以它可以像其他的Compute Driver一樣使用OpenStack中的所有服務,包括使用Novascheduler來做資源調度,用Heat來做應用部署、服務發(fā)現(xiàn)、擴容縮容等,同時也可以通過和Neutron集成來管理Docker網絡。也支持多租戶,為不同的租戶設置不同的Quota,做資源隔離。
它的缺點也很明顯,因為Docker和虛擬機差別也挺大的,Docker還有一些很高級的功能是VM所沒有的,像容器關聯(lián),就是使不同容器之間能夠共享一些環(huán)境變量,來實現(xiàn)一些服務發(fā)現(xiàn)的功能,例如K8S的Pod就是通過容器關聯(lián)來實現(xiàn)的。另外一個是端口映射,K8S的Pod也使用了端口映射的功能,可以把一個Pod中的所有Container的Port都通過Net Container Export出去,便于和外界通信。還有一個是不同網絡模式的配置,因為Docker的網絡模式很多,包括Host模式、Container模式等等,以上的所有功能都是Nova Docker Driver不能實現(xiàn)的。
Heat Docker Driver
因為Nova Docker Driver不能使用Docker的一些高級功能,所以社區(qū)就想了另一個方法,和Heat去集成,如圖5所示。
圖5 Heat Docker Driver
因為Heat采用的也是插件模式,所以就在Heat實現(xiàn)了一個新的Resource,專門來和Docker集成。這個Heat插件是直接通過REST API和Docker交互的,不需要和Nova、Cinder和Neutron等來進行交互。
這個Driver的一個優(yōu)點首先是它完全兼容Docker的API,因為我們可以在Heat Template里邊去定義我們關心的參數,可以實現(xiàn)Docker的所有高級功能。另外因為和Heat集成了,所以默認就有了Multi-Tenant的功能,可以實現(xiàn)不同Docker應用之間的隔離。
但它的缺點也非常明顯,因為它是Heat直接通過REST API和Docker交互的,所以Heat Docker Driver沒有資源調度,用戶需要在Template中指定需要在哪一臺Docker服務器上去部署,所以這個Driver不適合大規(guī)模應用,因為沒有資源調度。另外因為沒有和Neutron去交互,所以網絡管理也只能用Docker本身的網絡管理功能來實現(xiàn)。
圖6是使用Heat Docker Driver的一個很典型的應用場景。主要是通過Heat在虛擬機部署一個小規(guī)模的Docker Container應用,這個例子主要是一個Web Server的應用。
圖6 Heat Docker Driver的一個很典型的應用場景
它的方法是在Heat Tempalte定義兩種類型的Resource,一種是Nova Server,一種是Docker Container,Docker Container需要依賴Nova Server,就是必須Nova Server創(chuàng)建完后才能開始創(chuàng)建Docker Container。當用戶在創(chuàng)建Nova Server的時候,需要在Nova Server上通過User Data安裝Docker,Docker Container需要等Nova Server啟動后,在Nova Server上創(chuàng)建Docker Container。這里有一個詳細的例子,大家可以參考:http://techs.eNovance.com/7104/multi-tenant-Docker-with-openstack-heat
Magnum
在OpenStack和Docker集成的過程中,我們發(fā)現(xiàn)從OpenStack現(xiàn)有的項目中,找不到一個很好的集成點,雖然和Nova、Heat都做了集成的嘗試,但缺點很明顯,所以社區(qū)就開始了一個新的專門針對Docker和OpenStack集成的項目Magnum,用來提供容器服務。Magnum是2014年在巴黎峰會后從11月開始做的,到現(xiàn)在5個月時間有27個Contributor,有700多個Commit,發(fā)展速度還可以。
Mangum的主要目的是提供Container服務的,它同時還可以和多個Docker集群管理系統(tǒng)集成,包括K8S、Swarm、CoreOS等。和這幾個平臺集成的主要原因是能讓用戶可以很方便地通過OpenStack云平臺來集成K8S、CoreOS、Swarm這些已經很成型的Docker集群管理系統(tǒng),促進Docker和OpenStack生態(tài)系統(tǒng)的融合。
首先來看Magnum的主要概念,如圖7所示。
圖7 Magnum的主要概念
在這個圖的右邊,主要有:Bay、Baymodel、Node、Pod、Service、Replication Controller和Container。
Bay在Magnum主要表示一個集群,現(xiàn)在通過Magnum可以創(chuàng)建K8S和Swarm的bay,也就是K8S和Swarm的集群。
Baymodel是Flavor的一個擴展,F(xiàn)lavor主要是定義虛擬機的規(guī)格,Baymodel主要是定義一個Docker集群的一些規(guī)格,例如這個集群的管理節(jié)點的Flavor、計算節(jié)點的Flavor、集群使用的Image等。
Node主要是指Bay中的某個節(jié)點。
Pod、Replication Controller和Service的意思和在K8S的意思是一樣的,用戶可以通過Magnum來和K8S集成,通過Magnum API來操作K8S集群。
Pod是Kubernetes最基本的部署調度單元,可以包含多個Container,邏輯上表示某種應用的一個實例。比如一個Web站點應用由前端、后端及數據庫構建而成,這三個組件將運行在各自的容器中,那么我們可以創(chuàng)建三Pod,每個Pod運行一個服務。或者也可以將三個服務創(chuàng)建在一個Pod,這取決于用戶的應用需求。
Service是Pod的路由代理抽象,用于解決Pod的高可用的問題。Service因為Pod的運行狀態(tài)可動態(tài)變化(比如Pod的IP變了或者某個Pod被刪除了等),所以訪問端不能以寫死IP的方式去訪問該Pod提供的服務。Service的引入旨在保證Pod的動態(tài)變化對訪問端透明,訪問端只需要知道Service的地址,由Service來提供代理。
Replication Controller是Pod的復制抽象,用于解決Pod的擴容縮容問題。通常,分布式應用為了性能或高可用性的考慮,需要復制多份資源,并且根據負載情況動態(tài)伸縮。通過Replication Controller,我們可以指定一個應用需要幾份復制,Kubernetes將為每份復制創(chuàng)建一個Pod,并且保證實際運行Pod數量總是與該復制數量相等(例如,當前某個Pod宕機時,自動創(chuàng)建新的Pod來替換)。
Container就是某個Docker容器。
Magnum中的主要服務有兩個,一個是Magnum API,一個是Magnum Conductor。
Magnum API和其他項目的API的功能是一樣的,主要是處理Client的請求,將請求通過消息隊列發(fā)送到backend,Magnum現(xiàn)在支持的backend有K8S、CoreOS、Swarm、Docker等,未來還會支持Rocket等Docker集群管理工具。
在Magnum,后臺處理主要是通過Magnum Conductor來做的。Magnum Conductor的主要作用是將Client的請求轉發(fā)到對應的Backend,通過對用戶請求的解析,幫用戶找到最合適的Backend,所以Magnum Conductor需要為每個API的請求找到合適的Backend處理Client的Request。
Magnum其實和Nova的架構很像,Nova主要提供IaaS服務,Magnum主要提供CaaS,Nova可以管理不同類型的Hypervisor,包括VMware、KVM、PowerVM等,Magnum也一樣,它可以管理不同的Docker集群管理工具,包括K8S、Swarm、CoreOS等。最終目標是期望和Nova一樣,能夠讓用戶不用關心后臺的Docker集群管理工具到底是什么,只管提請求,最終通過Magnum獲得自己需要的Container。
從圖7來看,Magnum很簡單,主要是做了些集成工作,但其實Magnum對開發(fā)人員的要求也很高,因為Magnum需要和Heat、Ironic、Nova、K8S、CoreOS和Swarm等集成,所以需要開發(fā)人員對這些項目都有一定的了解,至少需要對這些項目的概念和主要特性都很清楚。
Magnum現(xiàn)在的一些主要特性,包括K8S as a Service、CoreOS as a Service、Swarm as a Service等。所以有這些功能,主要是因為有的客戶已經有OpenStack集群了,現(xiàn)在想在OpenStack上運行一些以應用為中心的系統(tǒng),像K8S、Swarm、Mesos等,通過這些系統(tǒng)為用戶提供應用服務,所以用戶就可以通過Magnum來實現(xiàn)它的需求,通過OpenStack提供Iaas服務,上層的K8S、Swarm等來提供Container服務。
另外,Magnum還實現(xiàn)了多租戶的功能,可以將不同租戶之間的Resouce隔離,每個租戶可以用自己的Baymodel、Bay等對象,實現(xiàn)安全隔離。Magnum準備和K8S的開發(fā)人員合作,打造一個最好的OpenStack和K8S結合的項目。
Magnum Roadmap如圖8所示。
圖8 Magnum Roadmap
第一個是Magnum Conductor的水平擴展,Magnum服務也是無狀態(tài)的,所以可以水平擴展,一旦發(fā)現(xiàn)Conductor性能存在瓶頸時,可以通過啟動一個新的Conductor來分擔系統(tǒng)負載。
第二個是原生Docker集群的調度問題,Magnum現(xiàn)在只能管理單個的Docker的服務器,因為還沒有一個原生的調度器能夠讓Magnum管理一個Docker集群,但可以和Swarm、Gantt或Mesos集成實現(xiàn)Docker集群資源調度的功能。現(xiàn)在經過討論,可能會使用Swarm來做調度,因為通過Magnum部署完Swarm集群后,默認就可以通過Swarm來管理Docker集群了。
第三個是原生Docker集群的網絡管理,現(xiàn)在大家的一致想法是在Docker server上通過Host模式來部署一個Container的l2 agent來管理Docker Server的網絡。
第四個是Notification,其主要作用是便于追蹤Magnum中所有對象的狀態(tài),尤其是當第三方和Magnum集成的時候,可以通過Notification來監(jiān)控Magnum中的操作的對象。
最后一個是K8S深度集成,現(xiàn)在Magnum和K8S的集成是Magnum通過調用K8S命令行kubectl和K8S交互,這樣做比較簡單,但受到的限制很大,因為Magnum需要通過解析Kubectl的輸出來判斷每個調用是不是成功,但有時Kubectl并不能輸出某個API的所有Output,所以Magnum關心的一些值通過Kubectl可能拿不到。現(xiàn)在有個BluePrint就是想通過K8Sclient使用REST API來和K8S交互,這樣就可以拿到每個調用的全部輸出,Magnum可以很方便地取得自己關心的輸出,來做相應的操作。圖8下面的Link是Magnum現(xiàn)在的所有的BluePrint。
Murano
Murano是Mirantis貢獻的,并且也進了OpenStack Namespace。也和K8S集成了,用戶可以通過Murano使用K8S的功能,可以通過Murano部署Pod、Service、Replication Controller等。Murano主要是在OpenStack基礎上提供應用目錄服務。Muarno和Solum之間其實是有關系的,Solum主要是用來開發(fā)應用的,Solum把應用開發(fā)完后,可以通過Murano來發(fā)布。用戶可以通過Murano挑選自己需要的應用服務,通過應用服務組合構建自己的應用。
Murano也是通過Heat部署應用,Kubernetes和Murano集成之后,現(xiàn)在K8S也已經成為Murano的一個應用服務了。
圖9所示是Murano的一個工作流,可以看到它的使用很簡單。首先創(chuàng)建用戶的應用環(huán)境,然后為應用環(huán)境添加應用服務,接下來部署應用環(huán)境,應用環(huán)境會通過OpenStack的Heat來部署。
圖9 Murano的一個工作流
圖10主要是說明怎樣通過Murano部署一個K8S的Pod。
圖10 通過Murano部署一個K8S的Pod
Murano和K8S的集成主要在前三步,第一步是先創(chuàng)建一個K8S的環(huán)境;然后在第二步需要為我們創(chuàng)建的K8S環(huán)境添加一個應用服務,首先需要添加一個K8S的集群應用模板,然后在K8S集群的基礎上添加一個Pod的應用;第三步是在第二步Pod的基礎上,為Pod添加Container。這三步做完后,就可以部署環(huán)境了,最終Murano會調用Heat首先創(chuàng)建一個K8S的集群,然后K8S集群根據用戶的需求創(chuàng)建Pod。所有的這些操作都可以在Murano的GUI上操作,非常簡單。
OpenStack Deployment With Docker
OpenStack現(xiàn)在的部署工具很多,包括RDO、Fuel、Chef、Triple-O等,但這些工具對OpenStack升級的支持不是很好。想在OpenStack升級的話,主要有兩種方式:基于Image與基于Package 。
基于Package的更新方式通常不是原子的,升級過程中存在很多導致失敗的原因,尤其是一些公共包依賴的問題,可能導致部分package更新失敗的可能。基于Image的方式,更新是原子的。
Triple-O是一個很典型的通過鏡像部署的例子,但是Triple-O升級OpenStack集群時,粒度太大,它通常情況下是同時對OpenStack多個服務去升級,這樣對OpenStack集群影響比較大,會導致某些服務在一定時間段內不能被訪問。
所以就有Kolla這樣一個項目,來解決快速升級和回滾的問題。
Kolla:Docker+OpenStack
Kolla的主要功能是使用Docker容器快速部署升級OpenStack服務。
Kolla的最終目標是為OpenStack的每一個服務都創(chuàng)建一個對應的Docker Image,通過Docker Image將升級的粒度減小到Service級別,從而使升級時,對OpenStack影響能達到最小,并且一旦升級失敗,也很容易回滾。升級只需要三步:Pull新版本的容器鏡像,停止老版本的容器服務,然后啟動新版本容器。回滾也不需要重新安裝包了,直接啟動老版本容器服務就行,非常方便。
Kolla是通過Docker Compose來部署OpenStack集群的,現(xiàn)在主要是針對裸機部署的,所以在部署Docker Container時,默認的網絡配置都是Host模式。所以Kolla的好處就非常明顯了,將OpenStack升級的粒度細化到了Service級別,升級失敗時,可以很容易回滾。
圖11展示怎樣通過Kolla去部署一個OpenStack集群。
圖11 通過Kolla去部署一個OpenStack集群
可以看到首先需要啟動一個管理節(jié)點,只需要通過一個命令就可以把管理節(jié)點部署完成,這個命令是調用Docker Compose來部署OpenStack的所有服務,然后我們可以在每一個計算節(jié)點上通過Docker Compose安裝計算節(jié)點需要的服務,就能部署一個OpenStack集群。因為Kolla的Docker Image粒度很小,它針對每個OpenStack服務都有特定的Image,所以我們也可以通過Docker Run來操作某個具體的OpenStack服務。這個例子是通過Docker Image啟動了Glance API。
圖12是一個OpenStack compute的一個例子。
圖12 OpenStack compute的一個例子
這是一個簡單的YML文件,我們可以通過Docker compose使用這些YML文件部署OpenStack節(jié)點,可以看到這個YML文件包含Compute Data Image、Libvirt Image、Network Image、Nova API Image和Compute Image等。第一個Compute Data主要是為其他Container提供存儲服務的,可以看到Libvirt和Novacompute的Container的存儲都是從Compute Data來的,因為它們都有一個字段voluemes_from指向Compute Data這個Container。
如何選擇?
OpenStack和Docker相關的項目這么多,該怎么去選擇呢?簡單說明如下。
如果用戶只是想將以前的VM Workload遷移到Docker Container,那么它可以使用Nova Docker Driver,一個很典型的例子是Sahara通過Heat調用Nova Docker Driver來創(chuàng)建Hadoop集群。
如果用戶想使用Docker的一些高級功能來部署一個小規(guī)模集群,那就可以考慮Heat Docker Driver。
如果用戶想通過OpenStack集成現(xiàn)有的一些Docker集群管理工具像K8S、Swarm來管理大規(guī)模的Docker集群,建議使用Magnum。另外因為Magnum也是基于Heat做的,所以默認也支持混合云的功能。
Murano和Docker的集成,主要體現(xiàn)在它提供了一個K8S的應用,用戶可以通過這個K8S應用來管理Docker集群。但Murano和Docker的焦點不一樣,Magnum主要提供容器服務,Murano主要提供應用目錄服務。
最后的Kolla,主要是簡化OpenStack的安裝部署和升級的。
Kilo的層級多租戶管理
因為Docker的出現(xiàn),使得IaaS層的計算密度進一步提升,這種密集型的計算對資源調度和運維的要求很高,需要一些比較高級的資源調度策略來提高資源利用率。Docker Container和虛擬機的最大區(qū)別是它輕量的特性,對于這種輕量性的容器技術,可以通過在資源調度中加入不同租戶之間資源共享的機制來提高資源利用率。所以OpenStack在Kilo新加的層級租戶的管理,這個功能可以理解為一種基本的資源共享,因為這個功能允許父賬戶和子賬戶之間共享資源。
圖13是一個例子。
圖13 層級的多租戶管理
我們可以看到每個租戶的旁邊都有一些值,以最頂層的租戶為例,這個租戶hard_limit=1000,used=100,reserved=100,allocated=70,它們的意思分別為:hard_limit是這個租戶的資源上限;used是當前這個租戶已經使用的資源;reserved是被這個租戶預定的資源,即使當前的租戶不用,也不能分給別的租戶;allocated是當前租戶分給子賬戶的資源,它的值是直接子賬戶的hard_limit的總和。我們可以看到ORG這個租戶的直接子賬戶兩個部門1和部門2,兩個的hard_limt分別為300和400,所以ORG的allocated值是700,這四個值還隱藏了一個值,那就是free,當前賬戶的空閑資源,free是hard_limit減掉used、reserved和allocated,空閑資源有兩個作用,一個是可以供本賬戶使用,還有一個是供子賬戶使用。我們可以看到ORG的空閑資源為1000-100-100-700=100,就是說它現(xiàn)在有100個空閑的資源,可以供自己或者子賬戶使用,就是給Dept-1或者Dept-2去用。這樣就為OpenStack增加了不同層級租戶之間的資源共享的功能。
這種形式有什么缺點呢?我們可以看到賬戶之間的關系只局限于父子賬戶,同一層級的賬戶之間還是沒有關系,它們的資源也不能互相共享。我們看team11和team12,它們之間的資源不能共享,就是即使team11的資源都用完了,team12的資源一點沒用,team11也不能從team12那邊借資源過來,這樣反映到企業(yè)就是,同一層級的部門之間資源不能共享,這是一個很大的短板,會導致資源不能被充分利用。我們可以把當前Kilo的這種層級租戶資源共享理解為獨占模式。
圖14是當前Kilo的層級租戶模式,現(xiàn)在共16個資源,T1和T2各獨占8個,我們可以把每個資源看成是一個Docker Container,假定所有的Container規(guī)格都是一樣的。就是說T1和T2最多可以創(chuàng)建8個Container。
圖14 當前Kilo的層級租戶模式
T1要4個資源,因為它有8個,所以可以拿到4個,剩下4個空閑的;T2要12個資源,因為它只有8個,所以只能拿到8個資源。最終結果是T1有4個空閑的資源,T2缺少4個資源,這種獨占策略的缺點就是資源不能共享,假如能把T1的這4個空閑的資源給T2用,就能達到最優(yōu)的資源使用率。
針對Kilo即將實現(xiàn)的層級賬戶的缺點,有人正在建議OpenStack社區(qū)作出改進增加同一層級租戶之間的資源共享,主要有兩種形式:同一層級資源借入/借出和同一層級資源資源共享。
圖15是同一層級的租戶之間資源共享改進的第一個模式:同一層級租戶間資源借入借出。
圖15 同一層級租戶間資源借入借出
借入借出是基于獨占策略來改進的。這個例子和剛才的獨占策略很像,從這個例子我們可以看到,租戶T1和T2個獨占8個資源,租戶T2可以從租戶T1借入4個資源。現(xiàn)在T1要4個,我有8個,可以拿到4個用著,然后有4個是空閑的,T2來了,要12個,先拿到自己獨占的那8個,還需要4個,然后發(fā)現(xiàn)可以從T1那借4個,正好滿足T2的請求。再進一步,就是假如這時候T1又來資源請求了,T1可以通過某種策略將借給T2的那4個要回來。
圖16是同一層級的租戶之間資源共享改進另一種模式:同一層級租戶之間資源共享。
圖16 同一層級租戶之間資源共享
現(xiàn)在同一層的租戶之間的資源是不能共享的,所以我們需要讓同一層級租戶之間的資源能夠共享來提升系統(tǒng)的資源使用率。所以我們現(xiàn)在可以引入同一層級的租戶之間的共享模式。
舉例來說,現(xiàn)在有兩個租戶,T1和T2,都不獨占任何資源,共享所有資源,并且T1和T2的共享比例為1:1,現(xiàn)在一共有16個資源,這16個資源都是共享的,T1和T2的共享比例為1:1,所以T1和T2都deserve 8個資源,但這8個并不是被T1或者T2獨占的,而是共享的。
也就是說,現(xiàn)在T1和T2都有資源請求了,T1要4個,T1現(xiàn)在deserve 8個,那就可以直接去拿4個資源。T2來了,T2要12個,但是T2只deserve 8個,那T2就先拿到deserve的這8個,然后它發(fā)現(xiàn)share pool里邊還有4個資源沒人用,那它就可以把這4個再拿過來,這樣T1和T2的請求就都滿足了。
這種借入借出模式和共享模式也可以同時去使用,我們可以把一部分資源設置成獨占的,一部分設置為共享的,給用戶更大的空間來配置它的資源規(guī)劃。