帶著問(wèn)題學(xué)習(xí)Kubernetes第一篇-K8S架構(gòu)是怎樣?

隨著Docker技術(shù)的流行,云原生應(yīng)用和容器調(diào)度管理系統(tǒng)也跟著隨之流行。由于單機(jī)的Docker引擎和單一的容器鏡像只能解決單一服務(wù)的打包和測(cè)試問(wèn)題。而要運(yùn)行生成級(jí)的企業(yè)級(jí)應(yīng)用,就需要容器調(diào)度管理系統(tǒng)。在這里面,Docker技術(shù)就像運(yùn)送系統(tǒng)零件的集裝箱,把云原生應(yīng)用的各個(gè)標(biāo)準(zhǔn)化零件運(yùn)送到各個(gè)企業(yè)的不同碼頭,而容器調(diào)度管理系統(tǒng)就是企業(yè)應(yīng)用的運(yùn)行車間,把不同的零件組裝,運(yùn)行和管理維護(hù)起來(lái)。而這方面的杰出者非Kubernetes莫屬,它是為生成環(huán)境而設(shè)計(jì)的容器調(diào)度管理系統(tǒng),對(duì)于負(fù)載均衡,服務(wù)發(fā)現(xiàn),高可用,滾動(dòng)升級(jí),自動(dòng)收縮等方面都有很好的支持。由于K和S之間有8個(gè)字母,因此常簡(jiǎn)稱為K8S。

在了解一門技術(shù)之前,首先需要了解其架構(gòu),熟悉各個(gè)組件的大致功能,在了解其架構(gòu)的基礎(chǔ)上,然后再去研究各個(gè)功能組件,各個(gè)擊破。這是我學(xué)習(xí)Kubernetes技術(shù)的第一篇文章,由于對(duì)K8S也是小白一枚,也是不斷的學(xué)習(xí),我將把我學(xué)習(xí)的過(guò)程中的一個(gè)一個(gè)總結(jié)成技術(shù)文章,大部分內(nèi)容都是來(lái)自一些經(jīng)典的博客,公眾號(hào)和書(shū)上的內(nèi)容,如有雷同,純屬抄襲,哈哈。

第一個(gè)疑問(wèn):K8S的架構(gòu)是怎樣?

帶著這個(gè)問(wèn)題,看了很多關(guān)于K8S架構(gòu)的文章,發(fā)現(xiàn)Kubernetes的架構(gòu)還真不復(fù)雜,組件也不算多。說(shuō)白了就是一個(gè)資源管理平臺(tái),它管理的資源可能是容器,網(wǎng)絡(luò),虛機(jī)等,而平時(shí)的應(yīng)用軟件可能是一個(gè)個(gè)的業(yè)務(wù)內(nèi)容,比如我們樓宇系統(tǒng)中更多的是設(shè)備,點(diǎn)等概念。下面是我看到的一篇深入淺出的介紹了K8S架構(gòu)的一篇文章,來(lái)自https://segmentfault.com/a/1190000010106778的文章。

問(wèn)題一:主節(jié)點(diǎn)和工作節(jié)點(diǎn)是如何通信的呢?

首先,Master 節(jié)點(diǎn)啟動(dòng)時(shí),會(huì)運(yùn)行一個(gè) kube-apiserver 進(jìn)程,它提供了集群管理的 API 接口,是集群內(nèi)各個(gè)功能模塊之間數(shù)據(jù)交互和通信的中心樞紐,并且它頁(yè)提供了完備的集群安全機(jī)制。

在 Node 節(jié)點(diǎn)上,使用 K8S 中的 kubelet 組件,在每個(gè) Node 節(jié)點(diǎn)上都會(huì)運(yùn)行一個(gè) kubelet 進(jìn)程,它負(fù)責(zé)向 Master 匯報(bào)自身節(jié)點(diǎn)的運(yùn)行情況,如 Node 節(jié)點(diǎn)的注冊(cè)、終止、定時(shí)上報(bào)健康狀況等,以及接收 Master 發(fā)出的命令,創(chuàng)建相應(yīng) Pod。

在 K8S 中,Pod 是最基本的操作單元,它與 docker 的容器有略微的不同,因?yàn)?Pod 可能包含一個(gè)或多個(gè)容器(可以是 docker 容器),這些內(nèi)部的容器是共享網(wǎng)絡(luò)資源的,即可以通過(guò) localhost 進(jìn)行相互訪問(wèn)。

關(guān)于 Pod 內(nèi)是如何做到網(wǎng)絡(luò)共享的,每個(gè) Pod 啟動(dòng),內(nèi)部都會(huì)啟動(dòng)一個(gè) pause 容器(google的一個(gè)鏡像),它使用默認(rèn)的網(wǎng)絡(luò)模式,而其他容器的網(wǎng)絡(luò)都設(shè)置給它,以此來(lái)完成網(wǎng)絡(luò)的共享問(wèn)題。

如圖所示:

問(wèn)題二:Master 是如何將 Pod 調(diào)度到指定的 Node 上的?

該工作由 kube-scheduler 來(lái)完成,整個(gè)調(diào)度過(guò)程通過(guò)執(zhí)行一些列復(fù)雜的算法最終為每個(gè) Pod 計(jì)算出一個(gè)最佳的目標(biāo) Node,該過(guò)程由 kube-scheduler 進(jìn)程自動(dòng)完成。常見(jiàn)的有輪詢調(diào)度(RR)。當(dāng)然也有可能,我們需要將 Pod 調(diào)度到一個(gè)指定的 Node 上,我們可以通過(guò)節(jié)點(diǎn)的標(biāo)簽(Label)和 Pod 的 nodeSelector 屬性的相互匹配,來(lái)達(dá)到指定的效果。

如圖所示:

問(wèn)題三:各節(jié)點(diǎn)、Pod 的信息都是統(tǒng)一維護(hù)在哪里的,由誰(shuí)來(lái)維護(hù)?

從上面的 Pod 調(diào)度的角度看,我們得有一個(gè)存儲(chǔ)中心,用來(lái)存儲(chǔ)各節(jié)點(diǎn)資源使用情況、健康狀態(tài)、以及各 Pod 的基本信息等,這樣 Pod 的調(diào)度來(lái)能正常進(jìn)行。

在 K8S 中,采用 etcd 組件 作為一個(gè)高可用強(qiáng)一致性的存儲(chǔ)倉(cāng)庫(kù),該組件可以內(nèi)置在 K8S 中,也可以外部搭建供 K8S 使用。

集群上的所有配置信息都存儲(chǔ)在了 etcd,為了考慮各個(gè)組件的相對(duì)獨(dú)立,以及整體的維護(hù)性,對(duì)于這些存儲(chǔ)數(shù)據(jù)的增、刪、改、查,統(tǒng)一由 kube-apiserver 來(lái)進(jìn)行調(diào)用,apiserver 也提供了 REST 的支持,不僅對(duì)各個(gè)內(nèi)部組件提供服務(wù)外,還對(duì)集群外部用戶暴露服務(wù)。

外部用戶可以通過(guò) REST 接口,或者 kubectl 命令行工具進(jìn)行集群管理,其內(nèi)在都是與 apiserver 進(jìn)行通信。

如圖所示:

問(wèn)題四:外部用戶如何訪問(wèn)集群內(nèi)運(yùn)行的 Pod ?

前面講了外部用戶如何管理 K8S,而我們更關(guān)心的是內(nèi)部運(yùn)行的 Pod 如何對(duì)外訪問(wèn)。使用過(guò) docker 的同學(xué)應(yīng)該知道,如果使用 bridge 模式,在容器創(chuàng)建時(shí),都會(huì)分配一個(gè)虛擬 IP,該 IP 外部是沒(méi)法訪問(wèn)到的,我們需要做一層端口映射,將容器內(nèi)端口與宿主機(jī)端口進(jìn)行映射綁定,這樣外部通過(guò)訪問(wèn)宿主機(jī)的指定端口,就可以訪問(wèn)到內(nèi)部容器端口了。

那么,K8S 的外部訪問(wèn)是否也是這樣實(shí)現(xiàn)的?答案是否定的,K8S 中情況要復(fù)雜一些。因?yàn)樯厦嬷v的 docker 是單機(jī)模式下的,而且一個(gè)容器對(duì)外就暴露一個(gè)服務(wù)。在分布式集群下,一個(gè)服務(wù)往往由多個(gè) Application 提供,用來(lái)分擔(dān)訪問(wèn)壓力,而且這些 Application 可能會(huì)分布在多個(gè)節(jié)點(diǎn)上,這樣又涉及到了跨主機(jī)的通信。

這里,K8S 引入了 service 的概念,將多個(gè)相同的 Pod 包裝成一個(gè)完整的 service 對(duì)外提供服務(wù),至于獲取到這些相同的 Pod,每個(gè) Pod 啟動(dòng)時(shí)都會(huì)設(shè)置 labels 屬性,在 service 中我們通過(guò)選擇器 selector,選擇具有相同 name 標(biāo)簽屬性的 Pod,作為整體服務(wù),并將服務(wù)信息通過(guò) apiserver 存入 etcd 中,該工作由 Service Controller 來(lái)完成。同時(shí),每個(gè)節(jié)點(diǎn)上會(huì)啟動(dòng)一個(gè) kube-proxy 進(jìn)程,由它來(lái)負(fù)責(zé)服務(wù)地址到 Pod 地址的代理以及負(fù)載均衡等工作。

如圖所示:

問(wèn)題五:Pod 如何動(dòng)態(tài)擴(kuò)容和縮放?

既然知道了服務(wù)是由 Pod 組成的,那么服務(wù)的擴(kuò)容也就意味著 Pod 的擴(kuò)容。通俗點(diǎn)講,就是在需要時(shí)將 Pod 復(fù)制多份,在不需要后,將 Pod 縮減至指定份數(shù)。K8S 中通過(guò) Replication Controller 來(lái)進(jìn)行管理,為每個(gè) Pod 設(shè)置一個(gè)期望的副本數(shù),當(dāng)實(shí)際副本數(shù)與期望不符時(shí),就動(dòng)態(tài)的進(jìn)行數(shù)量調(diào)整,以達(dá)到期望值。期望數(shù)值可以由我們手動(dòng)更新,或自動(dòng)擴(kuò)容代理來(lái)完成。

如圖所示:

問(wèn)題六:各個(gè)組件之間是如何相互協(xié)作的?

最后,講一下 kube-controller-manager 這個(gè)進(jìn)程的作用。我們知道了 ectd 是作為集群數(shù)據(jù)的存儲(chǔ)中心, apiserver 是管理數(shù)據(jù)中心,作為其他進(jìn)程與數(shù)據(jù)中心通信的橋梁。而 Service Controller、Replication Controller 這些統(tǒng)一交由 kube-controller-manager 來(lái)管理,kube-controller-manager 作為一個(gè)守護(hù)進(jìn)程,每個(gè) Controller 都是一個(gè)控制循環(huán),通過(guò) apiserver 監(jiān)視集群的共享狀態(tài),并嘗試將實(shí)際狀態(tài)與期望不符的進(jìn)行改變。關(guān)于 Controller,manager 中還包含了 Node 節(jié)點(diǎn)控制器(Node Controller)、資源配額管控制器(ResourceQuota Controller)、命名空間控制器(Namespace Controller)等。

如圖所示:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容