1. 前言
Together we will ensure that Kubernetes is a strong and open container management framework for any application and in any environment, whether in a private, public or hybrid cloud.
Urs Hölzle, Google
Kubernetes作為Docker生態(tài)圈中重要一員,是Google多年大規(guī)模容器管理技術(shù)的開(kāi)源版本,是產(chǎn)線(xiàn)實(shí)踐經(jīng)驗(yàn)的最佳表現(xiàn)[G1] 。如Urs Hölzle所說(shuō),無(wú)論是公有云還是私有云甚至混合云,Kubernetes將作為一個(gè)為任何應(yīng)用,任何環(huán)境的容器管理框架無(wú)處不在。正因?yàn)槿绱耍?目前受到各大巨頭及初創(chuàng)公司的青睞,如Microsoft、VMWare、Red Hat、CoreOS、Mesos等,紛紛加入給Kubernetes貢獻(xiàn)代碼。隨著Kubernetes社區(qū)及各大廠(chǎng)商的不斷改進(jìn)、發(fā)展,Kuberentes將成為容器管理領(lǐng)域的領(lǐng)導(dǎo)者。
接下來(lái)我們會(huì)用一系列文章逐一探索Kubernetes是什么、能做什么以及怎么做。
2. 什么是Kubernetes
Kubernetes是Google開(kāi)源的容器集群管理系統(tǒng),其提供應(yīng)用部署、維護(hù)、 擴(kuò)展機(jī)制等功能,利用Kubernetes能方便地管理跨機(jī)器運(yùn)行容器化的應(yīng)用,其主要功能如下:
1) 使用Docker對(duì)應(yīng)用程序包裝(package)、實(shí)例化(instantiate)、運(yùn)行(run)。
2) 以集群的方式運(yùn)行、管理跨機(jī)器的容器。
3) 解決Docker跨機(jī)器容器之間的通訊問(wèn)題。
4) Kubernetes的自我修復(fù)機(jī)制使得容器集群總是運(yùn)行在用戶(hù)期望的狀態(tài)。
當(dāng)前Kubernetes支持GCE、vShpere、CoreOS、OpenShift、Azure等平臺(tái),除此之外,也可以直接運(yùn)行在物理機(jī)上。
接下來(lái)本文主要從以下幾方面闡述Kubernetes:
1) Kubernetes的主要概念。
2) Kubernetes的構(gòu)件,包括Master組件、Kubelet、Proxy的詳細(xì)介紹。
3. Kubernetes主要概念
3.1. Pods
Pod是Kubernetes的基本操作單元,把相關(guān)的一個(gè)或多個(gè)容器構(gòu)成一個(gè)Pod,通常Pod里的容器運(yùn)行相同的應(yīng)用。Pod包含的容器運(yùn)行在同一個(gè)Minion(Host)上,看作一個(gè)統(tǒng)一管理單元,共享相同的volumes和network namespace/IP和Port空間。
3.2. Services
Services也是Kubernetes的基本操作單元,是真實(shí)應(yīng)用服務(wù)的抽象,每一個(gè)服務(wù)后面都有很多對(duì)應(yīng)的容器來(lái)支持,通過(guò)Proxy的port和服務(wù)selector決定服務(wù)請(qǐng)求傳遞給后端提供服務(wù)的容器,對(duì)外表現(xiàn)為一個(gè)單一訪(fǎng)問(wèn)接口,外部不需要了解后端如何運(yùn)行,這給擴(kuò)展或維護(hù)后端帶來(lái)很大的好處。
3.3. Replication Controllers
Replication Controller確保任何時(shí)候Kubernetes集群中有指定數(shù)量的pod副本(replicas)在運(yùn)行, 如果少于指定數(shù)量的pod副本(replicas),Replication Controller會(huì)啟動(dòng)新的Container,反之會(huì)殺死多余的以保證數(shù)量不變。Replication Controller使用預(yù)先定義的pod模板創(chuàng)建pods,一旦創(chuàng)建成功,pod 模板和創(chuàng)建的pods沒(méi)有任何關(guān)聯(lián),可以修改pod 模板而不會(huì)對(duì)已創(chuàng)建pods有任何影響,也可以直接更新通過(guò)Replication Controller創(chuàng)建的pods。對(duì)于利用pod 模板創(chuàng)建的pods,Replication Controller根據(jù)label selector來(lái)關(guān)聯(lián),通過(guò)修改pods的label可以刪除對(duì)應(yīng)的pods。Replication Controller主要有如下用法:
1) Rescheduling
如上所述,Replication Controller會(huì)確保Kubernetes集群中指定的pod副本(replicas)在運(yùn)行, 即使在節(jié)點(diǎn)出錯(cuò)時(shí)。
2) Scaling
通過(guò)修改Replication Controller的副本(replicas)數(shù)量來(lái)水平擴(kuò)展或者縮小運(yùn)行的pods。
3) Rolling updates
Replication Controller的設(shè)計(jì)原則使得可以一個(gè)一個(gè)地替換pods來(lái)rolling updates服務(wù)。
4) Multiple release tracks
如果需要在系統(tǒng)中運(yùn)行multiple release的服務(wù),Replication Controller使用labels來(lái)區(qū)分multiple release tracks。
3.4. Labels
Labels是用于區(qū)分Pod、Service、Replication Controller的key/value鍵值對(duì),Pod、Service、 Replication Controller可以有多個(gè)label,但是每個(gè)label的key只能對(duì)應(yīng)一個(gè)value。Labels是Service和Replication Controller運(yùn)行的基礎(chǔ),為了將訪(fǎng)問(wèn)Service的請(qǐng)求轉(zhuǎn)發(fā)給后端提供服務(wù)的多個(gè)容器,正是通過(guò)標(biāo)識(shí)容器的labels來(lái)選擇正確的容器。同樣,Replication Controller也使用labels來(lái)管理通過(guò)pod 模板創(chuàng)建的一組容器,這樣Replication Controller可以更加容易,方便地管理多個(gè)容器,無(wú)論有多少容器。
4. Kubernetes構(gòu)件
Kubenetes整體框架如下圖3-1,主要包括kubecfg、Master API Server、Kubelet、Minion(Host)以及Proxy。
圖3-1 Kubernetes High Level構(gòu)件
4.1. Master
Master定義了Kubernetes 集群Master/API Server的主要聲明,包括Pod Registry、Controller Registry、Service Registry、Endpoint Registry、Minion Registry、Binding Registry、RESTStorage以及Client, 是client(Kubecfg)調(diào)用Kubernetes API,管理Kubernetes主要構(gòu)件Pods、Services、Minions、容器的入口。Master由API Server、Scheduler以及Registry等組成。從下圖3-2可知Master的工作流主要分以下步驟:
1) Kubecfg將特定的請(qǐng)求,比如創(chuàng)建Pod,發(fā)送給Kubernetes Client。
2) Kubernetes Client將請(qǐng)求發(fā)送給API server。
3) API Server根據(jù)請(qǐng)求的類(lèi)型,比如創(chuàng)建Pod時(shí)storage類(lèi)型是pods,然后依此選擇何種REST Storage API對(duì)請(qǐng)求作出處理。
4) REST Storage API對(duì)的請(qǐng)求作相應(yīng)的處理。
5) 將處理的結(jié)果存入高可用鍵值存儲(chǔ)系統(tǒng)Etcd中。
6) 在API Server響應(yīng)Kubecfg的請(qǐng)求后,Scheduler會(huì)根據(jù)Kubernetes Client獲取集群中運(yùn)行Pod及Minion信息。
7) 依據(jù)從Kubernetes Client獲取的信息,Scheduler將未分發(fā)的Pod分發(fā)到可用的Minion節(jié)點(diǎn)上。
下面是Master的主要構(gòu)件的詳細(xì)介紹:
圖3-2 Master主要構(gòu)件及工作流
3.1.1. Minion Registry
Minion Registry負(fù)責(zé)跟蹤Kubernetes 集群中有多少M(fèi)inion(Host)。Kubernetes封裝Minion Registry成實(shí)現(xiàn)Kubernetes API Server的RESTful API接口REST,通過(guò)這些API,我們可以對(duì)Minion Registry做Create、Get、List、Delete操作,由于Minon只能被創(chuàng)建或刪除,所以不支持Update操作,并把Minion的相關(guān)配置信息存儲(chǔ)到etcd。除此之外,Scheduler算法根據(jù)Minion的資源容量來(lái)確定是否將新建Pod分發(fā)到該Minion節(jié)點(diǎn)。
3.1.2. Pod Registry
Pod Registry負(fù)責(zé)跟蹤Kubernetes集群中有多少Pod在運(yùn)行,以及這些Pod跟Minion是如何的映射關(guān)系。將Pod Registry和Cloud Provider信息及其他相關(guān)信息封裝成實(shí)現(xiàn)Kubernetes API Server的RESTful API接口REST。通過(guò)這些API,我們可以對(duì)Pod進(jìn)行Create、Get、List、Update、Delete操作,并將Pod的信息存儲(chǔ)到etcd中,而且可以通過(guò)Watch接口監(jiān)視Pod的變化情況,比如一個(gè)Pod被新建、刪除或者更新。
3.1.3. Service Registry
Service Registry負(fù)責(zé)跟蹤Kubernetes集群中運(yùn)行的所有服務(wù)。根據(jù)提供的Cloud Provider及Minion Registry信息把Service Registry封裝成實(shí)現(xiàn)Kubernetes API Server需要的RESTful API接口REST。利用這些接口,我們可以對(duì)Service進(jìn)行Create、Get、List、Update、Delete操作,以及監(jiān)視Service變化情況的watch操作,并把Service信息存儲(chǔ)到etcd。
3.1.4. Controller Registry
Controller Registry負(fù)責(zé)跟蹤Kubernetes集群中所有的Replication Controller,Replication Controller維護(hù)著指定數(shù)量的pod 副本(replicas)拷貝,如果其中的一個(gè)容器死掉,Replication Controller會(huì)自動(dòng)啟動(dòng)一個(gè)新的容器,如果死掉的容器恢復(fù),其會(huì)殺死多出的容器以保證指定的拷貝不變。通過(guò)封裝Controller Registry為實(shí)現(xiàn)Kubernetes API Server的RESTful API接口REST, 利用這些接口,我們可以對(duì)Replication Controller進(jìn)行Create、Get、List、Update、Delete操作,以及監(jiān)視Replication Controller變化情況的watch操作,并把Replication Controller信息存儲(chǔ)到etcd。
3.1.5. Endpoints Registry
Endpoints Registry負(fù)責(zé)收集Service的endpoint,比如Name:"mysql",Endpoints: ["10.10.1.1:1909","10.10.2.2:8834"],同Pod Registry,Controller Registry也實(shí)現(xiàn)了Kubernetes API Server的RESTful API接口,可以做Create、Get、List、Update、Delete以及watch操作。
3.1.6. Binding Registry
Binding包括一個(gè)需要綁定Pod的ID和Pod被綁定的Host,Scheduler寫(xiě)B(tài)inding Registry后,需綁定的Pod被綁定到一個(gè)host。Binding Registry也實(shí)現(xiàn)了Kubernetes API Server的RESTful API接口,但Binding Registry是一個(gè)write-only對(duì)象,所有只有Create操作可以使用, 否則會(huì)引起錯(cuò)誤。
3.1.7. Scheduler
Scheduler收集和分析當(dāng)前Kubernetes集群中所有Minion節(jié)點(diǎn)的資源(內(nèi)存、CPU)負(fù)載情況,然后依此分發(fā)新建的Pod到Kubernetes集群中可用的節(jié)點(diǎn)。由于一旦Minion節(jié)點(diǎn)的資源被分配給Pod,那這些資源就不能再分配給其他Pod, 除非這些Pod被刪除或者退出, 因此,Kubernetes需要分析集群中所有Minion的資源使用情況,保證分發(fā)的工作負(fù)載不會(huì)超出當(dāng)前該Minion節(jié)點(diǎn)的可用資源范圍。具體來(lái)說(shuō),Scheduler做以下工作:
1) 實(shí)時(shí)監(jiān)測(cè)Kubernetes集群中未分發(fā)的Pod。
2) 實(shí)時(shí)監(jiān)測(cè)Kubernetes集群中所有運(yùn)行的Pod,Scheduler需要根據(jù)這些Pod的資源狀況安全地將未分發(fā)的Pod分發(fā)到指定的Minion節(jié)點(diǎn)上。
3) Scheduler也監(jiān)測(cè)Minion節(jié)點(diǎn)信息,由于會(huì)頻繁查找Minion節(jié)點(diǎn),Scheduler會(huì)緩存一份最新的信息在本地。
4) 最后,Scheduler在分發(fā)Pod到指定的Minion節(jié)點(diǎn)后,會(huì)把Pod相關(guān)的信息Binding寫(xiě)回API Server。
4.2. Kubelet
圖3-3 Kubernetes詳細(xì)構(gòu)件
根據(jù)上圖3-3可知Kubelet是Kubernetes集群中每個(gè)Minion和Master API Server的連接點(diǎn),Kubelet運(yùn)行在每個(gè)Minion上,是Master API Server和Minion之間的橋梁,接收Master API Server分配給它的commands和work,與持久性鍵值存儲(chǔ)etcd、file、server和http進(jìn)行交互,讀取配置信息。Kubelet的主要工作是管理Pod和容器的生命周期,其包括Docker Client、Root Directory、Pod Workers、Etcd Client、Cadvisor Client以及Health Checker組件,具體工作如下:
1) 通過(guò)Worker給Pod異步運(yùn)行特定的Action。
2) 設(shè)置容器的環(huán)境變量。
3) 給容器綁定Volume。
4) 給容器綁定Port。
5) 根據(jù)指定的Pod運(yùn)行一個(gè)單一容器。
6) 殺死容器。
7) 給指定的Pod創(chuàng)建network 容器。
8) 刪除Pod的所有容器。
9) 同步Pod的狀態(tài)。
10) 從Cadvisor獲取container info、 pod info、root info、machine info。
11) 檢測(cè)Pod的容器健康狀態(tài)信息。
12) 在容器中運(yùn)行命令。
4.3. Proxy
Proxy是為了解決外部網(wǎng)絡(luò)能夠訪(fǎng)問(wèn)跨機(jī)器集群中容器提供的應(yīng)用服務(wù)而設(shè)計(jì)的,從上圖3-3可知Proxy服務(wù)也運(yùn)行在每個(gè)Minion上。Proxy提供TCP/UDP sockets的proxy,每創(chuàng)建一種Service,Proxy主要從etcd獲取Services和Endpoints的配置信息,或者也可以從file獲取,然后根據(jù)配置信息在Minion上啟動(dòng)一個(gè)Proxy的進(jìn)程并監(jiān)聽(tīng)相應(yīng)的服務(wù)端口,當(dāng)外部請(qǐng)求發(fā)生時(shí),Proxy會(huì)根據(jù)Load Balancer將請(qǐng)求分發(fā)到后端正確的容器處理。
5. 下篇主題
下篇講述在CentOS7上用Kubernetes來(lái)管理容器。
6. 個(gè)人簡(jiǎn)介
楊章顯,現(xiàn)就職于Cisco,主要從事WebEx SaaS服務(wù)運(yùn)維,系統(tǒng)性能分析等工作。特別關(guān)注云計(jì)算,自動(dòng)化運(yùn)維,部署等技術(shù),尤其是Go、OpenvSwitch、Docker及其生態(tài)圈技術(shù),如Kubernetes、Flocker等Docker相關(guān)開(kāi)源項(xiàng)目。Email: yangzhangxian@gmail.com
7. 參考資料
- https://github.com/GoogleCloudPlatform/kubernetes/tree/master/docs
- http://www.slideshare.net/rajdeep
- http://www.docker.com
感謝郭蕾對(duì)本文的策劃和審校。
給InfoQ中文站投稿或者參與內(nèi)容翻譯工作,請(qǐng)郵件至editors@cn.infoq.com。也歡迎大家通過(guò)新浪微博(@InfoQ)或者騰訊微博(@InfoQ)關(guān)注我們,并與我們的編輯和其他讀者朋友交流。