您好,登錄后才能下訂單哦!
簡述
Kubernetes 是一種用于在一組主機上運行和協(xié)同容器化應用程序的系統(tǒng),提供應用部署、規(guī)劃、更新維護的機制。應用運行在 kubernetes 集群之上,實現(xiàn)服務的擴容、縮容,執(zhí)行滾動更新以及在不同版本的應用程序之間調(diào)度流量以測試功能或回滾有問題的部署。Kubernetes 實現(xiàn)管理服務的各項功能是通過定義各種類型的資源來實現(xiàn)的,如 deployment、pod、service、volume 等。下面通過該文章來簡述 pod 的基礎(chǔ)信息并詳述 pod 的生命周期。
Pod簡介
Pod 是 kubernetes 系統(tǒng)的基礎(chǔ)單元,是由用戶創(chuàng)建或部署的最小組件,也是 kubernetes 系統(tǒng)上運行容器化應用的資源對象。Kubernetes 集群中其他資源對象都是為 pod 這個資源對象做支撐來實現(xiàn) kubernetes 管理應用服務的目的。
Kubernetes 集群組件主要包括主節(jié)點組件API Server、Controller Manager、Scheduler 以及子節(jié)點組件 kubelet、container Runtime(如docker)、kube-proxy 等。從與集群各組件交互角度講述 pod 的創(chuàng)建、運行、銷毀等生命周期,Pod 生命周期中的幾種不同狀態(tài)包括pending、running、succeeded、failed、Unknown。
與API Server交互
API Server 提供了集群與外部交互的接口,通過 kubectl 命令或者其他 API 客戶端提交 pod spec 給 API Server 作為pod創(chuàng)建的起始。
Pod 與 API Server 交互的主要流程如下:
API Server 在接收到創(chuàng)建pod的請求之后,會根據(jù)用戶提交的參數(shù)值來創(chuàng)建一個運行時的pod對象。
根據(jù) API Server 請求的上下文的元數(shù)據(jù)來驗證兩者的 namespace 是否匹配,如果不匹配則創(chuàng)建失敗。
Namespace 匹配成功之后,會向 pod 對象注入一些系統(tǒng)數(shù)據(jù),如果 pod 未提供 pod 的名字,則 API Server 會將 pod 的 uid 作為 pod 的名字。
API Server 接下來會檢查 pod 對象的必需字段是否為空,如果為空,創(chuàng)建失敗。
上述準備工作完成之后會將在 etcd 中持久化這個對象,將異步調(diào)用返回結(jié)果封裝成 restful.response,完成結(jié)果反饋。
至此,API Server 創(chuàng)建過程完成,剩下的由 scheduler 和 kubelet 來完成,此時 pod 處于 pending 狀態(tài)。
與scheduler交互
當提交創(chuàng)建 pod 的請求與 API Server 的交互完成之后,接下來由 scheduler 進行工作,該組件主要是完成 pod 的調(diào)度來決定 pod 具體運行在集群的哪個節(jié)點上。注意,此處聲明一點,API Server 完成任務之后,將信息寫入到 etcd 中,此時 scheduler 通過 watch 機制監(jiān)聽到寫入到 etcd 的信息然后再進行工作。
Scheduler 讀取到寫入到 etcd 中的 pod 信息,然后基于一系列規(guī)則從集群中挑選一個合適的節(jié)點來運行它,調(diào)度時主要通過三步來確定 pod 運行節(jié)點:
節(jié)點預選:基于一系列預選規(guī)則(如 PodFitsResource 和 MatchNode-Selector 等)對每個節(jié)點進行檢查,將不符合的節(jié)點過濾掉從而完成節(jié)點預選。
節(jié)點優(yōu)選:對預選出的節(jié)點進行優(yōu)先級排序,以便選出最適合運行 pod 對象的節(jié)點。
從優(yōu)先級結(jié)果中挑選出優(yōu)先級最高的節(jié)點來運行 pod 對象,當此類節(jié)點多個時則隨機選擇一個。
注:如果有特殊 pod 資源需要運行在特殊節(jié)點上,此時可以通過組合節(jié)點標簽以及 pod 標簽和標簽選擇器等來實現(xiàn)高級調(diào)度,如 MatchInterPodAffinity、MatchNodeSelector 和 PodToleratesNodeTaints 等預選策略,他們?yōu)橛脩籼峁┳远x Pod 親和性或反親和性、節(jié)點親和性以及基于污點及容忍度的調(diào)度機制。
預選策略
預選策略就是節(jié)點過濾器,例如 MathNodeSelector 實現(xiàn)的規(guī)則,以及 PodFitsResources 實現(xiàn)的規(guī)則等。執(zhí)行預選操作時,如果不存在適合的節(jié)點,此時 pod 會一直處于 pending 狀態(tài),直到至少有一個可用節(jié)點。
支持的預選策略列舉一下(1.10版本):
CheckNodeCondition
General
NoDiskConflict
PodToleratesNodeTaintsPodToleratesNodeNoExecuteTaints
CheckServiceAffinity
MaxEBsVolumeCount
MaxGCEPDVolumeCount
MaxAzureDiskVolumeCount
CheckVolumeBinding
NoVolumeZoneConflict
CheckNodeMemoryPressure
CheckNodePIDPressure
CheckNodeDiskPressure
MatchInterPodAffinity
簡單介紹幾種:
CheckNodeCondition:檢查是否可以在節(jié)點報告磁盤、網(wǎng)絡不可用或未準備好的情況下將 pod 對象調(diào)度其上。
NoDiskConflict:檢查 pod 對象請求的存儲卷在此節(jié)點上是否可用,若不存在沖突則通過檢查。
MathNodeSelector:若 pod 對象定義了 spec.NodeSelector 屬性,則檢查節(jié)點標簽是否能匹配此屬性值。
優(yōu)選函數(shù)
常用優(yōu)選函數(shù):
BalancedResourceAllocation?
LeaastRequstedPriority?
NodePreferAvoidPodsPriority?
NodeAffinityPriority?
TaintTolerationPriority?
InterPodAffinityPriority?
SelectorSpreadPriority?
NodeLabelPriority?
MostRequestedPriority?
ImageLoccalityPriority
此外調(diào)度器支持為每個優(yōu)選函數(shù)指定一個簡單的整數(shù)值表示權(quán)重,進行節(jié)點優(yōu)先級分值的計算,計算公式如下:
FinalScoreNode = (weight1 * priorityFunc1) + (weight2 * priorityFunc2)+ ....
列舉說明幾個優(yōu)選函數(shù):
TaintToleraionPriority:基于Pod資源對節(jié)點的污點容忍調(diào)度偏好進行其優(yōu)先級的評估,它將 Pod 對象的 tolerations 列表與節(jié)點的污點進行匹配度檢查,成功匹配的條目越多,則節(jié)點得分越低。
NodeAffinityPriority:基于節(jié)點親和性調(diào)度偏好進行優(yōu)先級評估,它將根據(jù) Pod 資源中的 nodeSelector 對給定節(jié)點進行匹配度計算,成功匹配到的條目越多則節(jié)點得分越高。
對于上述節(jié)點調(diào)度中還包括一些節(jié)點親和度:硬親和度和軟親和性、資源親和調(diào)度。硬親和調(diào)度和軟親和調(diào)度以及反親和調(diào)度、污點容忍度等,都是 pod 調(diào)度的策略,不一一詳述。
當 scheduler 通過一系列策略選定 pod 運行節(jié)點之后將結(jié)果信息更新至 API Server,由 API Server 更新至 etcd 中,并由 API Server 反映調(diào)度結(jié)果,接下來由 kubelet 在所選定的節(jié)點上啟動 pod。
Kubelet組件啟動pod
kubelet 組件的作用不單單是創(chuàng)建 pod,另外還包括節(jié)點管理、cAdvisor 資源監(jiān)控管理、容器健康檢查等功能。
啟動pod流程分析
kubelet 通過 API Server 監(jiān)聽 etcd 目錄,同步 pod 列表。如果發(fā)現(xiàn)有新的 pod 綁定到本節(jié)點,則按照 pod 清單要求創(chuàng)建 pod,如果是發(fā)現(xiàn) pod 被更新,則做出相應更改。
讀取到 pod 的信息之后,如果是創(chuàng)建和修改 pod 的任務,則做如下處理:
為該 pod 創(chuàng)建一個數(shù)據(jù)目錄?
從 API Server 讀取該 pod 清單?
為該 pod 掛載外部卷?
下載 pod 所需的 Secret?
檢查已經(jīng)運行在節(jié)點中 pod,如果該 pod 沒有容器或者 Pause 容器沒有啟動,則先停止pod里所有的容器進程。
使用 pause 鏡像為每個pod創(chuàng)建一個容器,該容器用于接管 Pod 中所有其他容器的網(wǎng)絡。
為 pod 中的每個容器做如下處理:1.為容器計算一個 hash 值,然后用容器的名字去查詢對于 docker 容器的 hash 值。若查找到容器,且兩者的 hash 值不同,則停止 docker 中容器中進程,并停止與之關(guān)聯(lián)的 pause 容器,若相同,則不做處理。若容器被終止了,且容器沒有指定的重啟策略,則不做任何處理調(diào)用 docker client ?下載容器鏡像,并啟動容器。
詳述pod聲明周期中的重要行為
除了創(chuàng)建應用容器(主容器及輔助容器之外,注意,如果集群中部署了 istio,則會在 pod 啟動的時候注入一個新的和 istio 相關(guān)的容器,那是另一個美好故事的開端),還可以為 pod 對象定義其聲明周期中的多種行為,如初始化容器、容器探測以及就緒性探測等。
容器生命周期的幾種行為
初始化容器
初始化容器即 pod 內(nèi)主容器啟動之前要運行的容器,主要是做一些前置工作,初始化容器具有以下特征:
初始化容器必須首先執(zhí)行,若初始化容器運行失敗,集群會一直重啟初始化容器直至完成,注意,如果 pod 的重啟策略為 Never,那初始化容器啟動失敗后就不會重啟。
初始化容器必須按照定義的順序執(zhí)行,初始化容器可以通過 pod 的 spec.initContainers 進行定義。
聲明周期鉤子函數(shù)
Kubernetes 為容器提供了兩種生命周期鉤子:
Poststart:于容器創(chuàng)建完成之后立即運行的鉤子程序。
preStop:容器終止之前立即運行的程序,是以同步方式的進行,因此其完成之前會阻塞 刪除容器的調(diào)用
備注:鉤子程序的執(zhí)行方式有“Exec”和“HTTP”兩種。
容器探測
容器探測分為存活性探測和就緒性探測容器探測是kubelet對容器健康狀態(tài)進行診斷,容器探測的方式主要以下三種:
ExecAction:在容器中執(zhí)行命令,根據(jù)返回的狀態(tài)碼判斷容器健康狀態(tài),返回0即表示成功,否則為失敗。
TCPSocketAction: 通過與容器的某TCP端口嘗試建立連接進行診斷,端口能打開即為表示成功,否則失敗。
HTTPGetAction:向容器指定 URL 發(fā)起 HTTP GET 請求,響應碼為2xx或者是3xx為成功,否則失敗。
Pod終止過程
終止過程主要分為如下幾個步驟:
用戶發(fā)出刪除 pod 命令?
Pod 對象隨著時間的推移更新,在寬限期(默認情況下30秒),pod 被視為“dead”狀態(tài)?
將 pod 標記為“Terminating”狀態(tài)?
第三步同時運行,監(jiān)控到 pod 對象為“Terminating”狀態(tài)的同時啟動 pod 關(guān)閉過程?
第三步同時進行,endpoints 控制器監(jiān)控到 pod 對象關(guān)閉,將pod與service匹配的 endpoints 列表中刪除?
如果 pod 中定義了 preStop 鉤子處理程序,則 pod 被標記為“Terminating”狀態(tài)時以同步的方式啟動執(zhí)行;若寬限期結(jié)束后,preStop 仍未執(zhí)行結(jié)束,第二步會重新執(zhí)行并額外獲得一個2秒的小寬限期
Pod 內(nèi)對象的容器收到 TERM 信號
寬限期結(jié)束之后,若存在任何一個運行的進程,pod 會收到 SIGKILL 信號?
Kubelet 請求 API Server 將此 Pod 資源寬限期設(shè)置為0從而完成刪除操作
此外 kubelet 除了啟動之外,kubelet 中還有 cAdvisor,用于收集容器 CPU、內(nèi)存、文件系統(tǒng)和網(wǎng)絡使用情況等信息,與 prometheus 結(jié)合實現(xiàn)對集群內(nèi) pod 監(jiān)控。
此外,除了上述三個組件在創(chuàng)建 pod 過程中的交互,還有 controller-manager 來保證 pod 處于用戶期望狀態(tài)(即保證 pod 永遠處于存活狀態(tài))等功能以及 proxy 用于集群內(nèi) pod 之間通信等。
本文由博云研究院原創(chuàng)發(fā)表,轉(zhuǎn)載請注明出處。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。