1. 程式人生 > >【微服務】Kubernetes物件之Deployment(重要)

【微服務】Kubernetes物件之Deployment(重要)

Kubernetes Deployment:

Deployment為Pod和Replica Set(升級版的 Replication Controller)提供宣告式更新。
只需要在 Deployment 中描述您想要的目標狀態是什麼,Deployment controller 就會幫您將 Pod 和ReplicaSet 的實際狀態改變到您的目標狀態。
可以定義一個全新的 Deployment 來建立 ReplicaSet 或者刪除已有的 Deployment 並建立一個新的來替換。
 

Deployment 物件中已經覆蓋了所有的用例:

使用Deployment來建立ReplicaSet。ReplicaSet在後臺建立pod。檢查啟動狀態,看它是成功還是失敗。
然後,通過更新Deployment的PodTemplateSpec欄位來宣告Pod的新狀態。這會建立一個新的ReplicaSet,Deployment會按照控制的速率將pod從舊的ReplicaSet移動到新的ReplicaSet中。
如果當前狀態不穩定,回滾到之前的Deployment revision。每次回滾都會更新Deployment的revision。
擴容Deployment以滿足更高的負載。
暫停Deployment來應用PodTemplateSpec的多個修復,然後恢復上線。
根據Deployment 的狀態判斷上線是否hang住了。
清除舊的不必要的 ReplicaSet。
 

建立 Deployment:

您必須在 Deployment 中的 selector 指定正確的 pod template label
Kubernetes 本身並不會阻止您任意指定 pod template label ,但是如果您真的這麼做了,這些 controller 之間會相互打架,並可能導致不正確的行為。
 

Pod-template-hash label:

這個 label 不是使用者指定的!
當 Deployment 建立或者接管 ReplicaSet 時,Deployment controller 會自動為 Pod 新增 pod-template-hash label。
防止 Deployment 的子ReplicaSet 的 pod 名字重複。
通過將 ReplicaSet 的 PodTemplate 進行雜湊雜湊,使用生成的雜湊值作為 label 的值,並新增到 ReplicaSet selector 裡、 pod template label 和 ReplicaSet 管理中的 Pod 上。
 

更新Deployment:

Deployment 的 rollout 當且僅當 Deployment 的 pod template(例如.spec.template)中的label更新或者映象更改時被觸發。
其他更新,例如擴容Deployment不會觸發 rollout。
 

Rollover(多個rollout並行):

每當 Deployment controller 觀測到有新的 deployment 被建立時,如果沒有已存在的 ReplicaSet 來建立期望個數的 Pod 的話,就會創建出一個新的 ReplicaSet 來做這件事。
已存在的 ReplicaSet 控制 label 與.spec.selector匹配但是 template 跟.spec.template不匹配的 Pod 縮容。
新的 ReplicaSet 將會擴容出.spec.replicas指定數目的 Pod,舊的 ReplicaSet 會縮容到0。
 

Label selector 更新:

不鼓勵更新 label selector,我們建議實現規劃好您的 selector。
想要執行 label selector 的更新,請一定要謹慎並確認您已經預料到所有可能因此導致的後果。
增添 selector 需要同時在 Deployment 的 spec 中更新新的 label,否則將返回校驗錯誤。
更新 selector,即更改 selector key 的當前值,將導致跟增添 selector 同樣的後果。
刪除 selector,即刪除 Deployment selector 中的已有的 key,不需要對 Pod template label 做任何更改,現有的 ReplicaSet 也不會成為孤兒,刪除的 label 仍然存在於現有的 Pod 和 ReplicaSet 中。
 

回退Deployment:

預設情況下,kubernetes 會在系統中儲存前兩次的 Deployment 的 rollout 歷史記錄,以便您可以隨時回退。
 

檢查 Deployment 升級的歷史記錄:

首先,檢查下 Deployment 的 revision
檢視單個revision 的詳細資訊
 

回退到歷史版本:

使用 --revision引數指定某個歷史版本
 

清理 Policy:

通過設定.spec.revisonHistoryLimit項來指定 deployment 最多保留多少 revision 歷史記錄。
預設的會保留所有的 revision
 

Deployment 擴容:

使用以下命令擴容 Deployment:
kubectl scale deployment nginx-deployment --replicas 10 deployment "nginx-deployment" scaled
叢集中啟用了horizontal pod autoscaling,您可以給 Deployment 設定一個 autoscaler,基於當前 Pod的 CPU 利用率選擇最少和最多的 Pod 數。
 

比例擴容:

RollingUpdate Deployment 支援同時執行一個應用的多個版本。
Deployment controller 將會平衡已存在的活動中的 ReplicaSet(有 Pod 的 ReplicaSet)和新加入的 replica。這被稱為比例擴容。
 

暫停和恢復Deployment:

發出一次或多次更新前暫停一個 Deployment,然後再恢復它。這樣您就能多次暫停和恢復 Deployment,在此期間進行一些修復工作,而不會發出不必要的 rollout。
Deployment 暫停前的初始狀態將繼續它的功能,而不會對 Deployment 的更新產生任何影響,只要 Deployment是暫停的。
在恢復 Deployment 之前您無法回退一個已經暫停的 Deployment。
 

Deployment 狀態:

Deployment 在生命週期中有多種狀態。
在建立一個新的 ReplicaSet 的時候它可以是 progressing 狀態, complete 狀態,或者 fail to progress 狀態。
 

進行中的 Deployment:

Kubernetes 將執行過下列任務之一的 Deployment 標記為 progressing 狀態:
Deployment 正在建立新的ReplicaSet過程中。
Deployment 正在擴容一個已有的 ReplicaSet。
Deployment 正在縮容一個已有的 ReplicaSet。
有新的可用的 pod 出現。
 

完成的 Deployment:

Kubernetes 將包括以下特性的 Deployment 標記為 complete 狀態:
Deployment 最小可用。最小可用意味著 Deployment 的可用 replica 個數等於或者超過 Deployment 策略中的期望個數。
所有與該 Deployment 相關的replica都被更新到了您指定版本,也就說更新完成。
該 Deployment 中沒有舊的 Pod 存在。
您可以用kubectl rollout status命令檢視 Deployment 是否完成。
 

失敗的 Deployment:

您的 Deployment 在嘗試部署新的 ReplicaSet 的時候可能卡住,用於也不會完成。
這可能是因為以下幾個因素引起的:

  1. 無效的引用
  2. 不可讀的 probe failure
  3. 映象拉取錯誤
  4. 許可權不夠
  5. 範圍限制
  6. 程式執行時配置錯誤

探測這種情況的一種方式是,在您的 Deployment spec 中指定spec.progressDeadlineSeconds。spec.progressDeadlineSeconds 表示 Deployment controller 等待多少秒才能確定(通過 Deployment status)Deployment程序是卡住的。
當超過截止時間後,Deployment controller 會在 Deployment 的 status.conditions中增加一條DeploymentCondition,它包括如下屬性:
Type=Progressing
Status=False
Reason=ProgressDeadlineExceeded


kubernetes除了報告Reason=ProgressDeadlineExceeded狀態資訊外不會對卡住的 Deployment 做任何操作。
如果您暫停了一個 Deployment,在暫停的這段時間內kubernetnes不會檢查您指定的 deadline。
您可能在使用 Deployment 的時候遇到一些短暫的錯誤,這些可能是由於您設定了太短的 timeout,也有可能是因為各種其他錯誤導致的短暫錯誤。
 

操作失敗的 Deployment:

所有對完成的 Deployment 的操作都適用於失敗的 Deployment。
您可以對它擴/縮容,回退到歷史版本,您甚至可以多次暫停它來應用 Deployment pod template。
 

清理Policy:

設定 Deployment 中的 .spec.revisionHistoryLimit 項來指定保留多少舊的 ReplicaSet。 
 

編寫 Deployment Spec:

所有的 Kubernetes 配置中,Deployment 也需要apiVersion,kind和metadata這些配置項。
 

Pod Template:

.spec.template 是 .spec中唯一要求的欄位。
.spec.template 是 pod template. 它跟 Pod有一模一樣的schema,除了它是巢狀的並且不需要apiVersion 和 kind欄位。
另外為了劃分Pod的範圍,Deployment中的pod template必須指定適當的label和適當的重啟策略。
.spec.template.spec.restartPolicy 可以設定為 Always , 如果不指定的話這就是預設配置。
Replicas:
.spec.replicas 是可以選欄位,指定期望的pod數量,預設是1。
Selector:
.spec.selector是可選欄位,用來指定 label selector ,圈定Deployment管理的pod範圍。
策略:
.spec.strategy 指定新的Pod替換舊的Pod的策略。
.spec.strategy.type 可以是"Recreate"或者是 "RollingUpdate"。"RollingUpdate"是預設值。
Recreate Deployment:
.spec.strategy.type==Recreate時,在創建出新的Pod之前會先殺掉所有已存在的Pod。
Rolling Update Deployment:
.spec.strategy.type = RollingUpdate時,Deployment使用rolling update 的方式更新Pod 
您可以指定maxUnavailable 和 maxSurge 來控制 rolling update 程序。
MAX UNAVAILABLE:
.spec.strategy.rollingUpdate.maxUnavailable 是可選配置項,用來指定在升級過程中不可用Pod的最大數量。
該值可以是一個絕對值(例如5),也可以是期望Pod數量的百分比(例如10%)。通過計算百分比的絕對值向下取整。
MAX SURGE:
.spec.strategy.rollingUpdate.maxSurge 是可選配置項,用來指定可以超過期望的Pod數量的最大個數。
該值可以是一個絕對值(例如5)或者是期望的Pod數量的百分比(例如10%)。
Progress Deadline Seconds:
.spec.progressDeadlineSeconds 是可選配置項,用來指定在系統報告Deployment的failed progressing
表現為resource的狀態中type=Progressing、Status=False、 Reason=ProgressDeadlineExceeded前可以等待的Deployment進行的秒數。
Deployment controller會繼續重試該Deployment。
在實現了自動回滾後, deployment controller在觀察到這種狀態時就會自動回滾。
該值必須大於 .spec.minReadySeconds。
Min Ready Seconds:
.spec.minReadySeconds是一個可選配置項,用來指定沒有任何容器crash的Pod並被認為是可用狀態的最小秒數。
Rollback To:
.spec.rollbackTo 是一個可以選配置項,用來配置Deployment回退的配置。
設定該引數將觸發回退操作,每次回退完成後,該值就會被清除。
Revision:
.spec.rollbackTo.revision是一個可選配置項,用來指定回退到的revision。
預設是0,意味著回退到歷史中最老的revision。
Revision History Limit:
Deployment revision history儲存在它控制的ReplicaSets中。
.spec.revisionHistoryLimit 是一個可選配置項,用來指定可以保留的舊的ReplicaSet數量。
該理想值取決於心Deployment的頻率和穩定性。
預設所有舊的Replicaset或會被保留,將資源儲存在etcd中,是用kubectl get rs檢視輸出。
每個Deployment的該配置都儲存在ReplicaSet中,然而,一旦您刪除的舊的RepelicaSet,您的Deployment就無法再回退到那個revison了。
Paused:
.spec.paused是可以可選配置項,boolean值。
用來指定暫停和恢復Deployment。Paused和沒有paused的Deployment之間的唯一區別就是,所有對paused deployment中的PodTemplateSpec的修改都不會觸發新的rollout。

Deployment 的替代選擇:

kubectl rolling update:
Kubectl rolling update 雖然使用類似的方式更新Pod和ReplicationController。

推薦使用Deployment,因為它是宣告式的,客戶端側,具有附加特性,例如即使滾動升級結束後也可以回滾到任何歷史版本。

內容整理自Kubernetes中文社群:https://www.kubernetes.org.cn/