kubernetes是什么,為什么上手這么難?
Kubernetes是一個基于容器技術(shù)的分布式集群管理系統(tǒng)。它是谷歌在大規(guī)模應(yīng)用容器技術(shù)方面數(shù)十年經(jīng)驗的實際成果。因此,支持大規(guī)模的集群管理承載著非常多的組件,分布式本身的復(fù)雜度非常高。
Kubernetes到底有什么?
接下來我們一步步來看看Kubernetes到底有什么?
首先,既然是分布式系統(tǒng),那么肯定有多個Node節(jié)點(物理主機或者虛擬機),它們共同構(gòu)成了一個分布式集群,而這些節(jié)點之間會有一個Master節(jié)點,統(tǒng)一管理Node節(jié)點。如圖所示:
問題1:Master節(jié)點和Worker節(jié)點如何通信?
首先,當(dāng)Master節(jié)點啟動時,會運行一個Kube-apiserver進(jìn)程,它提供了集群管理的API接口,是集群中各個功能模塊之間進(jìn)行數(shù)據(jù)交互和通信的中心樞紐,同時也提供了一個完善的集群安全機制。
在Node節(jié)點上,利用Kubernetes中的kubelet組件,每個Node節(jié)點上都會運行一個kubelet進(jìn)程,負(fù)責(zé)向Master匯報本節(jié)點的運行狀態(tài),如Node節(jié)點注冊、終止、定期健康報告等等,并接收來自Master的命令并創(chuàng)建相應(yīng)的Pod。
在Kubernetes中,Pod是最基本的運行單元。它與Docker容器略有不同,因為Pod中可能包含一個或多個容器(可以是Docker容器),這些容器內(nèi)部共享網(wǎng)絡(luò)資源,即可以通過localhost相互訪問。
關(guān)于如何在Pod中實現(xiàn)網(wǎng)絡(luò)共享,每個Pod啟動,內(nèi)部都會啟動一個pause容器(谷歌的image)。它使用默認(rèn)的網(wǎng)絡(luò)模式,其他容器的網(wǎng)絡(luò)設(shè)置為它,完成網(wǎng)絡(luò)共享問題。
如圖所示:
問題2:Master如何將Pod調(diào)度到指定的Node上?
這項工作由Kube-scheduler完成。整個調(diào)度過程通過執(zhí)行一系列復(fù)雜的算法,最終為每個Pod計算出一個最優(yōu)的目標(biāo)Node,這是由Kube-scheduler進(jìn)程自動完成的。
最常見的是循環(huán)調(diào)度(RR)。當(dāng)然也有可能我們需要將Pod調(diào)度到指定的Node上。我們可以通過將節(jié)點的標(biāo)簽(Label)與Pod的節(jié)點選擇器屬性進(jìn)行匹配來達(dá)到指定的效果。
如圖所示:
問題3:各個節(jié)點和Pod的信息統(tǒng)一在哪里維護(hù),誰來維護(hù)?
從上面的Pod調(diào)度來看,我們必須有一個存儲中心來存儲每個節(jié)點的每個Pod的資源使用情況、健康狀態(tài)和基本信息,這樣Pod調(diào)度才能正常進(jìn)行。
在Kubernetes中,etcd組件被用作高可用和一致的存儲庫。該組件可以內(nèi)置在Kubernetes中,也可以外部構(gòu)建供Kubernetes使用。
集群上的所有配置信息都存儲在etcd中。考慮到各個組件的相對獨立性和整體的可維護(hù)性,這些存儲的數(shù)據(jù)的增刪改查都是統(tǒng)一由Kube-apiserver來調(diào)用的,并且apiserver還提供了REST支持,不僅為各個內(nèi)部組件提供服務(wù)但也向集群外的用戶公開服務(wù)。
外部用戶可以通過REST接口或kubectl命令行工具管理集群,該工具內(nèi)部與apiserver通信。
如圖所示:
問題4:外部用戶如何訪問集群中運行的Pod?
前面我們講了外部用戶如何管理Kubernetes,但我們更關(guān)心的是內(nèi)部運行的Pod如何對外訪問。
用過Docker的同學(xué)應(yīng)該都知道,如果使用bridge模式,在創(chuàng)建容器的時候會分配一個虛擬IP,外部無法訪問該IP。我們需要做一層端口映射,將容器中的端口映射到宿主機的端口Map并綁定,這樣外部就可以通過訪問宿主機的指定端口來訪問容器內(nèi)部的端口。
那么,Kubernetes的外部訪問也是這樣實現(xiàn)的嗎?答案是否定的,Kubernetes中的情況更加復(fù)雜。因為上面說的Docker是單機模式,一個容器對外暴露一個服務(wù)。在分布式集群中,服務(wù)往往由多個應(yīng)用提供,以分擔(dān)訪問壓力,而這些應(yīng)用可能分布在多個節(jié)點上,這就涉及到跨主機通信。
這里Kubernetes引入了Service的概念,將多個相同的Pod包裝成一個完整的服務(wù),對外提供服務(wù)。至于獲取這些相同的Pod,每個Pod在啟動時都會設(shè)置labels為attribute。
在服務(wù)中,我們傳遞選擇器Selector,選擇與整體服務(wù)具有相同Name標(biāo)簽屬性的Pod,將服務(wù)信息通過Apiserver存儲到etcd中,由Service Controller完成。同時在每個節(jié)點上啟動一個kube-proxy進(jìn)程,負(fù)責(zé)從服務(wù)地址到Pod地址的代理和負(fù)載均衡。
如圖所示:
問題5:Pod如何動態(tài)擴(kuò)容和伸縮?
既然我們知道服務(wù)是由Pod組成的,那么服務(wù)的擴(kuò)展也意味著Pod的擴(kuò)展。通俗地說,就是在需要的時候?qū)od做多個副本,在不需要的時候?qū)od縮減到指定的副本數(shù)。
在Kubernetes中,使用Replication Controller進(jìn)行管理,為每個Pod設(shè)置一個預(yù)期的副本數(shù)。當(dāng)實際副本數(shù)量不符合預(yù)期時,動態(tài)調(diào)整數(shù)量以達(dá)到預(yù)期值。所需值可以由我們手動更新,也可以由自動縮放代理更新。如圖所示:
問題6:各個組件如何協(xié)同工作?
最后說一下Kube-controller-manager進(jìn)程的作用。我們知道ectd是作為集群數(shù)據(jù)的存儲中心,而apiserver是用來管理數(shù)據(jù)中心,充當(dāng)其他進(jìn)程與數(shù)據(jù)中心通信的橋梁。
Service Controller和Replication Controller由Kube-controller-manager管理。作為一個守護(hù)進(jìn)程,每個Controller都是一個控制回路,通過apiserver監(jiān)控集群的共享狀態(tài),并嘗試將實際狀態(tài)中不符合預(yù)期的變化。關(guān)于Controller,管理器還包括Node Controller、ResourceQuota Controller、Namespace Controller等。
如圖所示:
總結(jié)
本文通過問答的方式不涉及任何深入的實現(xiàn)細(xì)節(jié)。從整體的角度,從概念上介紹了Kubernetes涉及的基本概念。相關(guān)用途包括:
Node
Pod
Label
Selector
Replication Controller
Service Controller
ResourceQuota Controller
Namespace Controller
Node Controller
與運行過程相關(guān)的是:
kube-apiserver
kube-controller-manager
kube-scheduler
kubelet
kube-proxy
pause
編輯:黃飛
?
評論
查看更多