基于Kubernetes的容器雲
容器雲最主要的功能是以應用為中心,幫助使用者把所有的應用以容器的形式在分布式裡 面跑起來,最後把應用以服務的形式呈現給使用者。容器雲裡有兩個關鍵點,一是容器編排,二是資源排程。
容器編排就是我們期望能把一些微服務通過容器編排來幫助使用者組建一個比較龐大的系統,而資源排程在容器雲這種大規模分布式環境是必須的,需要一個比較好的排程平台來提升系統的資源使用率以及根據使用者的資源請求幫助使用者來調配資源。
我們IBM的BlueDock就是這樣一個容器雲平台,主要基于Kubernetes實作了容器的編排和資源排程,并預設使用Mesos作為底層的資料總管,但如果使用者沒有運作多個framework的需求,可不使用Mesos。
為什麼是Kubernetes和Mesos

為什麼選擇Kubernetes和Mesos作為容器雲的基礎平台?在項目啟動前,我們對目前流行的容器社群做了很多調研,主要是Docker、Mesos和Kubernetes社群。
我們先看一下Docker,Docker社群主要由Docker公司把控,雖然是開源的,但其實Docker社群相對來說不是很開放,因為Docker公司有基于Docker的所有産品,包括Docker的公有雲、私有雲Docker Data Center等等。這樣就導緻了其他公司如果想基于Docker創業的話會比較困難,因為難以與Docker公司競争。
而Mesos社群則更開放一些,主要原因是Mesosphere在基于Mesos研發了DC/OS,正在積極尋找一些合作者來推動DC/OS在企業的落地。同時Mesosphere也期望更多的公司、更多的人加入到這個社群,增加Mesos的影響力。是以這個社群相對Docker來說更開放一些,而且Mesos已經有很多落地的案例,在剛結束的MesosCon Asia上,我們可以看到國内其實有很多骨灰級的Mesos使用者,但這些使用者過于低調,沒有及時将自己的經驗分享出來,是以也希望這些使用者或已在生産使用Mesos的使用者能及時為大家分享一些經驗,促進Mesos生态的發展。
相比起來,Kubernetes社群是最開放、最活躍、最多元化的,雖然Kubernetes是Google開源的,但Google沒有任何一個産品是基于Kubernetes的。這樣就給了大家很公平的機會,基本上每個人、每個公司都可以基于Kubernetes開發自己的産品。但Kubernetes目前欠缺的是一些落地的案例,另外其支援的叢集規模大小也需要提升。
我曾試着把容器的這幾個社群和我們以前做虛拟化的社群做過一些對比,不知道合不合适,Docker可以類比到VMWare,Mesos可以類比到Citrix,Kubernetes可以類比到KVM。大家可以在調研選型或者使用的時候,根據自己的需求選擇合适的技術。
另外一個問題,大家應該可以看到Mesos和Kubernetes都在提供除了Docker之外的容器管理能力,Mesos花了很多時間去做Unified Container這個項目,目的就是即使沒有Docker Daemon,使用者也可運作Docker容器,同時使用Unified Container,還可運作其他容器,例如AppC、OCI等;Kubernetes也在內建Rkt給使用者除了Docker之外的另一種選擇。
整體架構
以上是我們容器雲的總體概覽,最左邊是我們很熟悉的雲平台的最重要的三層,IaaS、PaaS、SaaS,我們的BlueDock主要是提供PaaS的功能,是基于Kubernetes和Mesos(可選)來研發的。但如果我們建容器雲的話,隻有這兩個是遠遠不夠的,因為容器雲裡還有很多其他的功能,是以我們圍繞着Kubernetes和Mesos,在上面加了很多企業級的東西,包括應用商店,資源排程的改進政策,應用、伺服器的雙層擴充,多租戶管理,鏡像管理,統一界面等等。
應用商店:最主要的功能是把使用者常用的一些應用做成模闆,類似手機上的App Store,使用者可以很友善地通過應用市場來對應用進行部署,同時BlueDock還支援對不同版本的應用在同一個應用商店進行管理。我們還支援使用者對應用市場進行定制,這樣就可以讓使用者把一些自己常用的應用上傳到應用商店,供其它使用者使用。
資源排程的改進政策:因為容器的使用是一種高密度計算,對資源排程的要求很高,尤其是一些資源的搶占政策等等,這部分是原生的Kubernetes和Mesos都沒有的功能,IBM對這塊功能做了很大的改進,為容器雲加入了資源搶占的功能。
應用、伺服器的雙層擴充:這個我們可以了解為是一種關聯擴充。當使用者的應用因為負載的變化在擴充的時候,如果發現底層的伺服器不夠了,那應用就沒辦法去擴充了。這時我們的容器雲就會和底層的OpenStack互動,通過OpenStack去申請一些新的伺服器加入到容器雲中,實作了容器雲平台和用于應用的關聯擴充。我們的容器雲可以和多個不同的雲平台內建,實作關聯擴充的功能。
多租戶管理:這塊主要是和OpenStack Keystone內建來對租戶進行管理,同時将Keystone的Project映射為Kubernetes的namespace。另外一個是我們還通過和Keystone內建實作了層級的租戶管理。按照這種層級的租戶管理,一個很大的優勢是可以按照層級的結構來對資源做事先的定義,這樣的話就可以和企業的組織架構就可以很好的比對起來,便于企業内部的資源配置設定。
鏡像管理:這個服務主要是對鏡像進行管理,然後我們也調研了很多開源的對鏡像管理的軟體,例如Harbor,但是Harbor功能太多了,裡面不單單有鏡像管理的功能,還有對使用者,租戶管理的功能,權限控制等等,裡邊很多功能和我們的容器雲是重複的,是以我們最終決定我們沒有用這個項目,而是參考Harbor自己開發了一個新的服務來對鏡像進行管理。
日志管理:主要是通過ELK來實作。
持續內建:主要是通過Kubernetes Jenkins插件來實作的。這個插件的優勢是在資源配置設定時,Jenkins根據任務屬性自動建立臨時Docker容器,并作為slave節點加入Jenkins叢集,實作資源的配置設定;另外在任務執行結束後,Jenkins自動删除相關節點,并銷毀相關Docker容器,實作資源的釋放;整個資源配置設定和資源釋放過程對使用者來說是透明的,使用者隻需要建立好任務就可以了,不需要操作節點;對于Jenkins來說,slave節點(容器)是臨時的,任務一結束就會銷毀。為了實作資料持久化,需要和一些分布式的存儲內建,例如Ceph、Glusterfs等等。
統一的UI:對所有的服務進行操作,包括可以對UI對服務對鏡像進行管理,對應用市場進行管理等等。
如何實作self-healing
上圖是BlueDock中使用Kubernetes+Mesos的方案元件圖。BlueDock中的所有元件,都是通過container來部署的。用container的一個最大的優勢就是安裝部署更新是很簡單的,同時不會修改實體伺服器的一些配置,對實體伺服器不會有任何改動。我們現在的BlueDock,隻需要一個通過一個“docker run”指令,就可以很友善在上百台伺服器上把容器雲跑起來,我們做過一些測試,如果要去部署五百台左右的伺服器,我們可以在十分鐘以内把整個容器雲叢集安裝部署完成。
在圖中的最下邊用不同顔色的方框表示出了BlueDock中不同元件的管理方式。其中有三個比較重要的概念:Static pod、DaemonSet和Deployment。
Static pod是在特定節點上由kubelet守護程式直接管理的,Kubernetes APIServer不會對其進行管理。 它沒有關聯任何Relication Controller,kubelet守護程序來負責對Static pod的監控,并在static pod crash時重新啟動它。 Static pod始終綁定到一個kubelet守護程式,并且始終在同一節點上運作。
DaemonSet可以確定所有(或一些)節點始終運作某個pod的副本。 當節點添加到叢集時,DaemonSet可以保證自動在新添加的節點建立pod;如果節點被删除後,這些pod也會相應的被DaemonSet删除。
Deployment是kubernetes 1.2的一個新引入的概念,它包含着對Pod和将要代替Replication Controller的Replica Set的描述。
BlueDock主要通過Static Pod、DaemonSet和Deployment來對主要元件進行管理,這三個功能可以通過Kubernetes自身的功能保證BlueDock self-healing的功能,某些Pod crash後,Static Pod、DaemonSet和Deployment可以保證其會被重新開機,進而保證系統的高可用。
基本流程是通過ansible調用docker-py通過docker container的形式在master節點啟動kubelet,在master節點的kubelet服務啟動後,就會以static pod的形式建立master節點的一些元件,例如k8sm-apiserver、k8sm-scheduler等等,當master節點的所有元件啟動完畢後,開始通過docker-py在不同的worker上啟動mesos agent,當整個BlueDock叢集開始運作後,再通過DaemonSet的形式啟動一些BlueDock的add-on的一些元件服務,例如日志管理、網絡管理等等。
日志管理主要是通過DaemonSet的形式啟動了Filebeat,來搜集每個worker的容器日志資訊。網絡管理主要是通過DaemonSet在每個worker節點啟動了Calico node的container,這個container裡面包含了Bird路由管理、Felix協定等。其它還有一些元件通過Deployment來管理,例如用于對log進行過濾的logstash,用于對Network Policy進行管理的calico congtroller等等。
上圖是BlueDock沒有Mesos的部署方式,基本和帶有Mesos的部署模式是一樣的,全部都是通過容器來對所有元件進行管理,同時可以self-healing。在這裡主要想強調的是,BlueDock對k8s-scheduler做了很大的改進,支援資源的搶占,智能回收的政策。因為一台伺服器上可以啟動成百上千個容器,是以在這種高密度計算中,對資源的排程政策要求很高。BlueDock通過和IBM Platform的EGO內建,實作了資源的搶占和智能回收的政策。
上圖是BlueDock的一個簡單的改進的資源借入借出的一個例子。現在有兩個tenant,T1和T2,都獨占8個資源,但是我們看到在T1和T2之間有個虛線,這個虛線表示T2可以從T1借入4個資源。是以當T1和T2去申請資源的時候,T1要4個,T2要12個,那T1可以直接拿到他獨占的4個資源,T2要12個,但是他隻獨占8個資源,是以他會先拿到自己獨占的這8個資源。
拿完之後,T2發現,他可以再從T1借4個,是以當T2從T1借完4個後,T1和T2的資源請求都得到了滿足,同時系統的資源使用率也達到了100%,是以這個是我們通過資源借入借出實作的提升資源使用率的一個例子。另外,如果T1的請求再提升的話,T1可以把借給T2的資源再搶占回來,保證T1的SLA。
上圖是BlueDock的兩種不同的安裝模式:包含和不包含Mesos,這個可以在使用者對BlueDock安裝的時候,通過“—enable-mesos”來控制。當BlueDock安裝完成後,這兩種模式會有統一的GUI界面,終端使用者不會感覺Mesos的存在,唯一的差別就是如果使用了Mesos,可以通過BlueDock管理Mesos的Framework。
BlueDock的Auth主要是通過Keystone實作了一個Kubernetes OpenID的provider,友善與其它第三方的應用內建實作單點登入的功能。同時利用了Kubernetes的RBAC的功能,可以定義細粒度的權限控制。另外在和Keystone的內建過程中,BlueDock将Kubernetes的namespace映射為Keystone的project,這樣的話,可以借助keystone來對Kubernetes的使用者和namespace來統一管理。
在BlueDock叢集中的每個節點上運作一個Filebeat的容器,收集容器的日志發送給到LogStash來進行過濾,然後統一存儲到ElasticSearch叢集中,使用者可以通過Kibana檢視任意Node、Namespace、Service、Pod和容器的資料。在BlueDock中,ElasticSearch是作為DaemonSet在所有管理節點啟動的。
應用管理主要通過Kubernetes Helm來管理,Helm是官方Kubernetes的一部分,主要用來進行軟體包的管理。Helm的一個很重要的概念是Charts,表示可以安裝并組成的預配置Kubernetes資源包。Helm采用用戶端機伺服器模式。伺服器部分被稱為tiller,同時包括你運作Kubernetes叢集。用戶端部分被稱為helm,安裝在本地的開發系統上。
在BlueDock中,為了讓BlueDock的UI能直接調用Helm的API,我們通過Helm的Client實作了Helm的Rest API,這樣可通過BlueDock的UI來調用Helm的Rest API實作對Kubernetes應用包的管理。同時在BlueDock中将Rest API、Helm Client和Tiller通過一個Kubernetes Deployment進行管理部署,這樣可通過Kubernetes自身來對Helm的所有元件進行管理。
注:IBM釋出了BlueDock的開源版本,可以下載下傳來玩一下。BlueDock安裝的Docker鏡像可從這裡下載下傳:https://hub.docker.com/r/ibmcom/cfc-installer/ ,一個“docker run”指令可幫助安裝整個叢集。如果在安裝時有任何問題,可到slack channel尋求幫助,具體資訊可參考:https://www.ibm.com/developerworks/community/wikis/home?lang=zh#!/wiki/W1559b1be149d_43b0_881e_9783f38faaff
本文轉自中文社群-
IBM基于Kubernetes的容器雲全解析