【Kubernetes詳解】(七)k8s 之 Pod 詳解二

一、Init Container(初始化容器)

在很多應用場景中,應用在啓動之前都需要進行如下初始化操作:

  • 等待其他關聯組件正確運行(例如數據庫或某個後臺服務)。
  • 基於環境變量或配置模板生成配置文件。
  • 從遠程數據庫獲取本地所需配置,或者將自身註冊到某個中央數據庫中。
  • 下載相關依賴包,或者對系統進行一些預配置操作。

Kubernetes 1.3引入了一個Alpha版本的新特性init container(初始化容器,在Kubernetes 1.5時被更新爲Beta版本),用於在啓動應用容器 (app container)之前啓動一個或多個初始化容器,完成應用容器所需的預置條件。init container與應用容器在本質上是一樣的,但它們是僅運行一次就結束的任務,並且必須在成功執行完成後, 系統才能繼續執行下一個容器。根據Pod的重啓策略(RestartPolicy), 當init container執行失敗,而且設置了RestartPolicy=Never時,Pod將會啓動失敗;而設置RestartPolicy=Always時,Pod將會被系統自動重啓。

二、Pod的升級和回滾

當集羣中的某個服務需要升級時,我們需要停止目前與該服務相關 的所有Pod,然後下載新版本鏡像並創建新的Pod。如果集羣規模比較 大,則這個工作變成了一個挑戰,而且先全部停止然後逐步升級的方式 會導致較長時間的服務不可用。Kubernetes提供了滾動升級功能來解決 上述問題。
如果Pod是通過Deployment創建的,則用戶可以在運行時修改 Deployment的Pod定義(spec.template)或鏡像名稱,並應用到 Deployment對象上,系統即可完成Deployment的自動更新操作。如果在 更新過程中發生了錯誤,則還可以通過回滾操作恢復Pod的版本。

2.1、滾動升級

# 第1種升級鏡像版本方式
$ kubectl set image deployment/<deployment-name> <image-name>=<image-version>

# 第二種升級鏡像版本方式
$ kubectl edit deployemtn <deployment-name>

# 在升級過程中,查看滾動升級狀態
$ kubectl rollout status

Deployment是如何完成Pod更新的呢?
我們可以使用kubectl describe deployments/nginx-deployment命令仔 細觀察Deployment的更新過程。初始創建Deployment時,系統創建了一 個ReplicaSet(nginx-deployment-4087004473),並按用戶的需求創建了 3個Pod副本。當更新Deployment時,系統創建了一個新的 ReplicaSet(nginx-deployment-3599678771),並將其副本數量擴展到 1,然後將舊的ReplicaSet縮減爲2。之後,系統繼續按照相同的更新策 略對新舊兩個ReplicaSet進行逐個調整。最後,新的ReplicaSet運行了3個 新版本Pod副本,舊的ReplicaSet副本數量則縮減爲0。如下圖:
在這裏插入圖片描述
對更新策略的說明如下:
在Deployment的定義中,可以通過spec.strategy指定Pod更新的策 略,目前支持兩種策略:Recreate(重建)和RollingUpdate(滾動更 新),默認值爲RollingUpdate。在前面的例子中使用的就是 RollingUpdate策略。

  • Recreate:設置spec.strategy.type=Recreate,表示Deployment在 更新Pod時,會先殺掉所有正在運行的Pod,然後創建新的Pod。
  • RollingUpdate:設置spec.strategy.type=RollingUpdate,表示 Deployment會以滾動更新的方式來逐個更新Pod。同時,可以通過設置 spec.strategy.rollingUpdate下的兩個參數(maxUnavailable和maxSurge) 來控制滾動更新的過程。

2.2、Deployment的回滾

有時(例如新的Deployment不穩定時)我們可能需要將Deployment 回滾到舊版本。在默認情況下,所有Deployment的發佈歷史記錄都被保 留在系統中,以便於我們隨時進行回滾(可以配置歷史記錄數量)。

2.3、暫停和恢復Deployment的部署操作

對於一次複雜的Deployment配置修改,爲了避免頻繁觸發 Deployment的更新操作,可以先暫停Deployment的更新操作,然後進行 配置修改,再恢復Deployment,一次性觸發完整的更新操作,就可以避 免不必要的Deployment更新操作了。

# 暫停Deployment的更新操作
$ kubectl rollout pause deployment/<deployment-name>

# 對Deployment做任意次修改,都不會導致鏡像部署

# 恢復Deployment的更新操作

$ kubectl rollout resume deployment/<deployment-name>

2.4、使用kubectl rolling-update命令完成RC的 滾動升級

對於RC的滾動升級,Kubernetes還提供了一個kubectl rolling-update 命令進行實現。該命令創建了一個新的RC,然後自動控制舊的RC中的 Pod副本數量逐漸減少到0,同時新的RC中的Pod副本數量從0逐步增加 到目標值,來完成Pod的升級。需要注意的是,系統要求新的RC與舊的 RC都在相同的命名空間內。

方法一操作步驟:

  • 需要新寫一個yaml文件用於滾動升級
  • 新的RC的名字(name)不能與舊RC的名字相同
  • 在selector中應至少有一個Label與舊RC的Label不同,以標識其爲新RC。
$ kubectl rolling-update <old-deployment-name> -f <yaml-name>

方法二:

$ kubectl rolling-update <old-deployment-name> --image=<image-name>:<version>

與使用配置文件的方式不同,執行的結果是舊RC被刪除,新RC仍 將使用舊RC的名稱。

三、Pod的擴縮容

在實際生產系統中,我們經常會遇到某個服務需要擴容的場景,也 可能會遇到由於資源緊張或者工作負載降低而需要減少服務實例數量的 場景。此時可以利用Deployment/RC的Scale機制來完成這些工作。
Kubernetes對Pod的擴縮容操作提供了手動和自動兩種模式,手動模 式通過執行kubectl scale命令或通過RESTful API對一個Deployment/RC進 行Pod副本數量的設置,即可一鍵完成。自動模式則需要用戶根據某個 性能指標或者自定義業務指標,並指定Pod副本數量的範圍,系統將自 動在這個範圍內根據性能指標的變化進行調整。

3.1、手動擴縮容機制

命令:

$ kubectl scale deployment <deployment-name> --replicas <number>

3.2、自動擴縮容機制

Kubernetes從1.1版本開始,新增了名爲Horizontal Pod Autoscaler(HPA)的控制器,用於實現基於CPU使用率進行自動Pod擴 縮容的功能。HPA控制器基於Master的kube-controller-manager服務啓動 參數–horizontal-pod-autoscaler-sync-period定義的探測週期(默認值爲 15s),週期性地監測目標Pod的資源性能指標,並與HPA資源對象中的 擴縮容條件進行對比,在滿足條件時對Pod副本數量進行調整。

3.2.1、HPA的工作原理

Kubernetes中的某個Metrics Server(Heapster或自定義Metrics Server)持續採集所有Pod副本的指標數據。HPA控制器通過Metrics Server的API(Heapster的API或聚合API)獲取這些數據,基於用戶定義 的擴縮容規則進行計算,得到目標Pod副本數量。當目標Pod副本數量與 當前副本數量不同時,HPA控制器就向Pod的副本控制器 (Deployment、RC或ReplicaSet)發起scale操作,調整Pod的副本數量, 完成擴縮容操作。下圖描述了HPA體系中的關鍵組件和工作流程:
在這裏插入圖片描述

3.2.2、指標的類型

Master的kube-controller-manager服務持續監測目標Pod的某種性能 指標,以計算是否需要調整副本數量。目前Kubernetes支持的指標類型 如下。

  • Pod資源使用率:Pod級別的性能指標,通常是一個比率值,例如:CPU使用率。
  • Pod自定義指標:Pod級別的性能指標,通常是一個數值,例如:接收的請求數量。
  • Object自定義指標或外部自定義指標:通常是一個數值,需要容器應用以某種方式提供,例如通過HTTP URL“/metrics”提供,或者使 用外部服務提供的指標採集URL。

3.2.3、擴縮容算法詳解

Autoscaler控制器從聚合API獲取到Pod性能指標數據之後,基於下 面的算法計算出目標Pod副本數量,與當前運行的Pod副本數量進行對 比,決定是否需要進行擴縮容操作:
在這裏插入圖片描述
即當前副本數×(當前指標值/期望的指標值),將結果向上取整。

當計算結果與1非常接近時,可以設置一個容忍度讓系統不做擴縮 容操作。容忍度通過kube-controller-manager服務的啓動參數–horizontal- pod-autoscaler-tolerance進行設置,默認值爲0.1(即10%),表示基於上 述算法得到的結果在[-10%-+10%]區間內,即[0.9-1.1],控制器都不會進行擴縮容操作。
也可以將期望指標值(desiredMetricV alue)設置爲指標的平均值類 型,例如targetAverageValue或targetAverageUtilization,此時當前指標值 (currentMetricV alue)的算法爲所有Pod副本當前指標值的總和除以Pod 副本數量得到的平均值。
此外,存在幾種Pod異常的情況,如下所述:

  • Pod正在被刪除(設置了刪除時間戳):將不會計入目標Pod副本數量。
  • Pod的當前指標值無法獲得:本次探測不會將這個Pod納入目標Pod副本數量,後續的探測會被重新納入計算範圍。
  • 如果指標類型是CPU使用率,則對於正在啓動但是還未達到 Ready狀態的Pod,也暫時不會納入目標副本數量範圍。可以通過kube- controller-manager服務的啓動參數–horizontal-pod-autoscaler-initial- readiness-delay設置首次探測Pod是否Ready的延時時間,默認值爲30s。 另一個啓動參數–horizontal-pod-autoscaler-cpuinitialization-period設置首次採集Pod的CPU使用率的延時時間。

如果在HorizontalPodAutoscaler中設置了多個指標,系統就會對每個 指標都執行上面的算法,在全部結果中以期望副本數的最大值爲最終結 果。如果這些指標中的任意一個都無法轉換爲期望的副本數(例如無法 獲取指標的值),系統就會跳過擴縮容操作。

3.2.4、HorizontalPodAutoscaler配置詳解

Kubernetes將HorizontalPodAutoscaler資源對象提供給用戶來定義擴縮容的規則。
HorizontalPodAutoscaler資源對象處於Kubernetes的API 組“autoscaling”中,目前包括v1和v2兩個版本。其中autoscaling/v1僅支 持基於CPU使用率的自動擴縮容,autoscaling/v2則用於支持基於任意指 標的自動擴縮容配置,包括基於資源使用率、Pod指標、其他指標等類 型的指標數據,當前版本爲autoscaling/v2beta2。
可以根據CPU、Mem、QPS等的值來對Pod進行擴縮容,前提是需要有指標採集服務

常見指標示例

自定義指標

基於自定義指標進行自動擴縮容時,需要預先部署自定義Metrics Server,目前可以使用基於Prometheus、Microsoft Azure、DatadogCluster等系統的Adapter實現自定義Metrics Server,未來還將提供基於Google Stackdriver的實現自定義Metrics Server。
基於Prometheus的HPA架構圖如下:
在這裏插入圖片描述
關鍵組件包括如下。

  • Prometheus:定期採集各Pod的性能指標數據。
  • Custom Metrics Server:自定義Metrics Server,用Prometheus Adapter進行具體實現。它從Prometheus服務採集性能指標數據,通過 Kubernetes的Metrics Aggregation層將自定義指標API註冊到Master的API Server中,以/apis/custom.metrics.k8s.io路徑提供指標數據。
  • HPA Controller:Kubernetes的HPA控制器,基於用戶定義的 HorizontalPodAutoscaler進行自動擴縮容操作。

四、使用StatefulSet

這個是有狀態的Pod,一般用於:MongDB集羣、Mysql集羣等的搭建

參考

《Kubernetes權威指南: 第四版》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章