背景
了解一個新的技術(shù),必須要了解的它的歷史,它為啥會出現(xiàn)?解決了什么樣的問題?

image.png
我們知道現(xiàn)在應(yīng)用部署的發(fā)展史可以分成3個階段,傳統(tǒng)部署->虛擬化部署->容器化部署,那么這3個階段都解決了什么樣的問題,帶來了哪些方面的提升呢?
- 傳統(tǒng)部署:一臺物理主機部署多個應(yīng)用,多個應(yīng)用之間會相互搶占資源,不好控制資源分配的問題,也沒有辦法做到不同的應(yīng)用之間資源隔離。
- 虛擬化部署:為了解決資源隔離和資源分配的問題,引入了虛擬化的技術(shù),在一臺機器上虛擬多臺虛擬機,虛擬機之間資源隔離,互不干擾;虛擬化技術(shù)是一項重量級的技術(shù),需要重新虛擬化硬件設(shè)備,非常耗資源。
- 容器化部署:相比虛擬化,容器化是一項輕量級的技術(shù),各個容器需要遵循CRI的規(guī)范創(chuàng)建鏡像,然后通過Container Runtime來統(tǒng)一運行和分配資源;容器是輕量級,所有的容器共享操作系統(tǒng)資源,通過Container Runtime調(diào)用OCI來做硬件資源和系統(tǒng)資源隔離。
通過上述這些內(nèi)容我們了解了應(yīng)用部署的一個發(fā)展史,所有的這些技術(shù)都是為了更合理的利用機器的資源;K8S只是為了管理容器化后的應(yīng)用(POD)所產(chǎn)生的一套技術(shù)規(guī)范,比如:POD需要部署在哪一個node節(jié)點上是如果被調(diào)度?pod中的鏡像是如何啟動的?POD如何回收?POD的存儲怎么解決?POD的網(wǎng)絡(luò)如何處理?POD資源如何分配隔離等等?
架構(gòu)圖

image.png
上圖是K8S的官網(wǎng)架構(gòu)圖,下面來分析各個組件的作用:
- API-server:提供了控制面訪問node上的應(yīng)用的統(tǒng)一入口,就跟我們java應(yīng)用網(wǎng)關(guān)一樣是后端集群的統(tǒng)一入口一樣。
- Controller-manager:負責運行控制器的進程

image.png
- Cloud controller manager:不同的云產(chǎn)商通過k8s調(diào)用云產(chǎn)商的不同的產(chǎn)品來實現(xiàn)自己的產(chǎn)品和k8s的整合,例如,sevice 的type=loadbancer的,阿里云是通過SLB來實現(xiàn)的,還有一些SLS日志庫的操作都是通過CCM來實現(xiàn)的。

image.png
- etcd:持久化存儲的數(shù)據(jù)庫,用于存儲集群的持久化的數(shù)據(jù)。
- kubelet:node節(jié)點上的管理員,單一個pod被調(diào)度到一個node上的時候,kubelet就會調(diào)用相應(yīng)的Container Runtime來啟動pod中的鏡像,管理pod的健康狀態(tài)。
- kube-proxy:node節(jié)點上的網(wǎng)絡(luò)管理員,實現(xiàn)了Service中的部分概念,例如:通過服務(wù)名路由到可供選擇的pod上去。
- scheduler:集群調(diào)度器,用于POD調(diào)度哪個node上,怎么進行選擇,親和性和污點;也用于調(diào)度定時任務(wù)。
- node:用于部署K8S控制面組件和業(yè)務(wù)自己的pod,可分為master和worker節(jié)點,master主要用于部署K8S相關(guān)的組件,worker節(jié)點用于部署業(yè)務(wù)相關(guān)的POD。
pod啟動流程
schduler調(diào)度pod

image.png
- 當一個pod的yml文件通過kubectl提交,需要通過K8S的控制面的kube-scheduler的進行調(diào)度。
- 一個pod需要調(diào)度到合適的node節(jié)點上執(zhí)行,需要符合相應(yīng)的調(diào)度規(guī)則。
- 親和性:表示pod通過標簽優(yōu)先掛載到哪個node上。
- 污點度:跟親和性的功能作用不一樣,親和性是優(yōu)先部署,污點度是排他性的。
- scheduler通過親和性和污點度的一個調(diào)度規(guī)則來把pod調(diào)度到合適的work 的node節(jié)點上。
kubelet啟動pod

image.png
- 當一個pod被調(diào)度到一個node上的時候。
- kubelet通過pod判斷是否有指定Runtime Class ,如果沒有使用默認的,如果有使用指定的Container Runtime。
- kubelet通過gRPC協(xié)議調(diào)用符合CRI接口的Container Runtime啟動POD的容器,然后調(diào)用相應(yīng)OCI的實現(xiàn)來做硬件隔離和資源隔離。
pod狀態(tài)流轉(zhuǎn)圖

image.png
- Pending:Pod 已被 Kubernetes 系統(tǒng)接受,但有一個或者多個容器尚未創(chuàng)建亦未運行。此階段包括等待 Pod 被調(diào)度的時間和通過網(wǎng)絡(luò)下載鏡像的時間。
- Running:Pod 已經(jīng)綁定到了某個節(jié)點,Pod 中所有的容器都已被創(chuàng)建。至少有一個容器仍在運行,或者正處于啟動或重啟狀態(tài)。
- Succeeded:pod中的所有容器都已經(jīng)成功終止,并且不會重新啟動。
- Failed:Pod 中的所有容器都已終止,并且至少有一個容器是因為失敗終止。也就是說,容器以非 0 狀態(tài)退出或者被系統(tǒng)終止。
- Unknown:因為某些原因無法取得 Pod 的狀態(tài)。這種情況通常是因為與 Pod 所在主機通信失敗。
- Terminating:終止的臨時狀態(tài),需要被調(diào)度進行終止,并不是最終的狀態(tài)。
容器狀態(tài)

image.png
- Waiting:如果容器并不處在 Running 或 Terminated 狀態(tài)之一,它就處在 Waiting 狀態(tài)。 處于 Waiting 狀態(tài)的容器仍在運行它完成啟動所需要的操作:例如, 從某個容器鏡像倉庫拉取容器鏡像,或者向容器應(yīng)用 Secret 數(shù)據(jù)等等。 當你使用 kubectl 來查詢包含 Waiting 狀態(tài)的容器的 Pod 時,你也會看到一個 Reason 字段,其中給出了容器處于等待狀態(tài)的原因。
- Running: Running 狀態(tài)表明容器正在執(zhí)行狀態(tài)并且沒有問題發(fā)生。 如果配置了 postStart 回調(diào),那么該回調(diào)已經(jīng)執(zhí)行且已完成。 如果你使用 kubectl 來查詢包含 Running 狀態(tài)的容器的 Pod 時, 你也會看到關(guān)于容器進入 Running 狀態(tài)的信息。
- Terminated:處于 Terminated 狀態(tài)的容器已經(jīng)開始執(zhí)行并且或者正常結(jié)束或者因為某些原因失敗。 如果你使用 kubectl 來查詢包含 Terminated 狀態(tài)的容器的 Pod 時, 你會看到容器進入此狀態(tài)的原因、退出代碼以及容器執(zhí)行期間的起止時間。