打開這篇文章的同學(xué),想必對(duì) Docker 都不會(huì)陌生。Docker 是一種虛擬容器技術(shù),它上手比較簡單,只需在宿主機(jī)上起一個(gè) DockerEngine,然后就能愉快的玩耍了,如:拉鏡像、起容器、掛載數(shù)據(jù)、映射端口等等。相對(duì)于 Kubernetes(K8S)的上手,可謂簡單很多。
那么 K8S 是什么,又為什么上手難度大?K8S 是一個(gè)基于容器技術(shù)的分布式集群管理系統(tǒng),是谷歌幾十年來大規(guī)模應(yīng)用容器技術(shù)的經(jīng)驗(yàn)積累和升華的一個(gè)重要成果。所以為了能夠支持大規(guī)模的集群管理,它承載了很多的組件,而且分布式本身的復(fù)雜度就很高。又因?yàn)?K8S 是谷歌出品的,依賴了很多谷歌自己的鏡像,所以對(duì)于國內(nèi)的同學(xué)環(huán)境搭建的難度又增加了一層。
下面,我們帶著問題,一步步來看 K8S 中到底有哪些東西?
首先,既然是個(gè)分布式系統(tǒng),那勢必有多個(gè) Node 節(jié)點(diǎn)(物理主機(jī)或虛擬機(jī)),它們共同組成一個(gè)分布式集群,并且這些節(jié)點(diǎn)中會(huì)有一個(gè) Master 節(jié)點(diǎn),由它來統(tǒng)一管理 Node 節(jié)點(diǎ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ù)交互和通信的中心樞紐,并且它頁提供了完備的集群安全機(jī)制(后面還會(huì)講到)。
在 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ò)資源的,即可以通過 localhost 進(jì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è)置給它,以此來完成網(wǎng)絡(luò)的共享問題。
如圖所示:
問題二:Master 是如何將 Pod 調(diào)度到指定的 Node 上的?
該工作由 kube-scheduler 來完成,整個(gè)調(diào)度過程通過執(zhí)行一些列復(fù)雜的算法最終為每個(gè) Pod 計(jì)算出一個(gè)最佳的目標(biāo) Node,該過程由 kube-scheduler 進(jìn)程自動(dòng)完成。常見的有輪詢調(diào)度(RR)。當(dāng)然也有可能,我們需要將 Pod 調(diào)度到一個(gè)指定的 Node 上,我們可以通過節(jié)點(diǎn)的標(biāo)簽(Label)和 Pod 的 nodeSelector 屬性的相互匹配,來達(dá)到指定的效果。
如圖所示:
關(guān)于標(biāo)簽(Label)與選擇器(Selector)的概念,后面會(huì)進(jìn)一步介紹
問題三:各節(jié)點(diǎn)、Pod 的信息都是統(tǒng)一維護(hù)在哪里的,由誰來維護(hù)?
從上面的 Pod 調(diào)度的角度看,我們得有一個(gè)存儲(chǔ)中心,用來存儲(chǔ)各節(jié)點(diǎn)資源使用情況、健康狀態(tài)、以及各 Pod 的基本信息等,這樣 Pod 的調(diào)度來能正常進(jìn)行。
在 K8S 中,采用 etcd 組件作為一個(gè)高可用強(qiáng)一致性的存儲(chǔ)倉庫,該組件可以內(nèi)置在 K8S 中,也可以外部搭建供 K8S 使用。
集群上的所有配置信息都存儲(chǔ)在了 etcd,為了考慮各個(gè)組件的相對(duì)獨(dú)立,以及整體的維護(hù)性,對(duì)于這些存儲(chǔ)數(shù)據(jù)的增、刪、改、查,統(tǒng)一由 kube-apiserver 來進(jìn)行調(diào)用,apiserver 也提供了 REST 的支持,不僅對(duì)各個(gè)內(nèi)部組件提供服務(wù)外,還對(duì)集群外部用戶暴露服務(wù)。
外部用戶可以通過 REST 接口,或者 kubectl 命令行工具進(jìn)行集群管理,其內(nèi)在都是與 apiserver 進(jìn)行通信。
如圖所示:
問題四:外部用戶如何訪問集群內(nèi)運(yùn)行的 Pod ?
前面講了外部用戶如何管理 K8S,而我們更關(guān)心的是內(nèi)部運(yùn)行的 Pod 如何對(duì)外訪問。使用過Docker的同學(xué)應(yīng)該知道,如果使用 bridge 模式,在容器創(chuàng)建時(shí),都會(huì)分配一個(gè)虛擬 IP,該 IP 外部是沒法訪問到的,我們需要做一層端口映射,將容器內(nèi)端口與宿主機(jī)端口進(jìn)行映射綁定,這樣外部通過訪問宿主機(jī)的指定端口,就可以訪問到內(nèi)部容器端口了。
那么,K8S 的外部訪問是否也是這樣實(shí)現(xiàn)的?答案是否定的,K8S 中情況要復(fù)雜一些。因?yàn)樯厦嬷v的 Docker是單機(jī)模式下的,而且一個(gè)容器對(duì)外就暴露一個(gè)服務(wù)。在分布式集群下,一個(gè)服務(wù)往往由多個(gè) Application 提供,用來分擔(dā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 中我們通過選擇器 Selector,選擇具有相同 Name 標(biāo)簽屬性的 Pod,作為整體服務(wù),并將服務(wù)信息通過 Apiserver 存入 etcd 中,該工作由 Service Controller 來完成。同時(shí),每個(gè)節(jié)點(diǎn)上會(huì)啟動(dòng)一個(gè) kube-proxy 進(jìn)程,由它來負(fù)責(zé)服務(wù)地址到 Pod 地址的代理以及負(fù)載均衡等工作。
如圖所示:
問題五:Pod 如何動(dòng)態(tài)擴(kuò)容和縮放?
既然知道了服務(wù)是由 Pod 組成的,那么服務(wù)的擴(kuò)容也就意味著 Pod 的擴(kuò)容。通俗點(diǎn)講,就是在需要時(shí)將 Pod 復(fù)制多份,在不需要后,將 Pod 縮減至指定份數(shù)。K8S 中通過 Replication Controller 來進(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ò)容代理來完成。
如圖所示:
問題六:各個(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 來管理,kube-controller-manager 作為一個(gè)守護(hù)進(jìn)程,每個(gè) Controller 都是一個(gè)控制循環(huán),通過 apiserver 監(jiān)視集群的共享狀態(tài),并嘗試將實(shí)際狀態(tài)與期望不符的進(jìn)行改變。關(guān)于 Controller,manager 中還包含了 Node 節(jié)點(diǎn)控制器(Node Controller)、資源配額管控制器(ResourceQuota Controller)、命名空間控制器(Namespace Controller)等。
如圖所示:
總結(jié)
本文通過問答的方式,沒有涉及任何深入的實(shí)現(xiàn)細(xì)節(jié),從整體的角度,概念性的介紹了 K8S 中涉及的基本概念,其中使用相關(guān)的包括有:
Node
Pod
Label
Selector
Replication Controller
Service Controller
ResourceQuota Controller
Namespace Controller
Node Controller
以及運(yùn)行進(jìn)程相關(guān)的有:
kube-apiserver
kube-controller-manager
kube-scheduler
kubelet
kube-proxy
pause
-
谷歌
+關(guān)注
關(guān)注
27文章
6128瀏覽量
104979 -
容器
+關(guān)注
關(guān)注
0文章
492瀏覽量
22028 -
Docker
+關(guān)注
關(guān)注
0文章
454瀏覽量
11798 -
kubernetes
+關(guān)注
關(guān)注
0文章
223瀏覽量
8683
原文標(biāo)題:關(guān)于 Kubernetes 架構(gòu)原理,這是我看過最清晰明了的一篇
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論