跟k8s工作負(fù)載Deployments的緣起緣滅

跟k8s工作負(fù)載Deployments的緣起緣滅

考點(diǎn)之簡單介紹一下什么是Deployments吧?
考點(diǎn)之怎么查看 Deployment 上線狀態(tài)?
考點(diǎn)之集群中能不能設(shè)置多個Deployments控制器具有重疊的標(biāo)簽選擇器?
考點(diǎn)之可以自定義Pod-template-hash 標(biāo)簽嘛?如果可以,有什么好處?如果不可以,有什么危害?
考點(diǎn)之什么場景下會觸發(fā)Deployments上線動作?
考點(diǎn)之Deployments在更新時會關(guān)閉所有Pod嘛?如果不是,默認(rèn)關(guān)閉最大比例是多少?
考點(diǎn)之你能不能簡單描述一下Deployments更新時RS和Pod是如何滾動更新的?
考點(diǎn)之如何判定Deployment上線過程是否出現(xiàn)停滯?有哪些原因會造成停滯?如何解決配額不足的問題?
考點(diǎn)之保存修訂歷史會消耗 etcd 中的資源,并占用 `kubectl get rs` 的輸出,如果給修訂歷史限制值設(shè)置為0是不是就能有效解決這個問題?
image

囧么肥事-胡說八道

image
image

考點(diǎn)之簡單介紹一下什么是Deployments吧?

Deployments是k8s內(nèi)置的工作負(fù)載之一,主要作用是幫助我們管理無狀態(tài)Pod。

一個 Deployment 為 Pods 和 ReplicaSets 提供了聲明式的更新能力,我們只需要負(fù)責(zé)描述 Deployment 中的RS和Pod需要達(dá)到的目標(biāo)狀態(tài),那么DM就會以一種受控速率去幫助我們更改RS和Pod的實(shí)際狀態(tài), 使其變?yōu)槲覀兤谕霈F(xiàn)的狀態(tài)。

image

Deployment 很適合用來管理你的集群上的無狀態(tài)應(yīng)用Deployment 認(rèn)為所有的 Pod 都是相互等價(jià)的,在需要的時候都是可以替換的。

Deployment: "小Pod 們,都給我聽話"
DM: "你們都不是唯一的"
DM: "不聽話,鬧事的Pod"
DM: "隨時可以讓你走人"
DM: "大把的Pod可以替換你們"

Pods: "是是是,我們一定聽話"

Deployment 是一個實(shí)干主義者,你如果好好工作,不鬧事,那么一切OK,但是如果你有小心思,敢鬧事,那它隨時可以趕你走人,隨時隨地可以招新人。

考點(diǎn)之怎么查看 Deployment 上線狀態(tài)?

Deployment 的生命周期中會有許多狀態(tài)。上線新的 ReplicaSet 期間可能處于Progressing(進(jìn)行中),可能是 Complete(已完成),也可能是Failed(失?。┻M(jìn)入阻塞停滯無法繼續(xù)進(jìn)行。

利用kubectl rollout status 命令可以監(jiān)視 Deployment 的進(jìn)度。

假設(shè)創(chuàng)建了一個Nginx的DM,查看DM進(jìn)度。

kubectl rollout status deployment/nginx-deployment

哪些場景會讓Deployment 進(jìn)入這三種狀態(tài)呢?

為了方便,后續(xù)DM均代表Deployment

進(jìn)行中(Progressing)

當(dāng)Deployment 執(zhí)行下面的任務(wù)期間,Kubernetes 將其標(biāo)記為進(jìn)行中(Progressing)

- DM創(chuàng)建新的 `ReplicaSet`
- DM正在為最新的 `ReplicaSet` 執(zhí)行擴(kuò)容操作
- DM 正在為舊的 `ReplicaSet`執(zhí)行縮容操作
- 新的 Pods 已經(jīng)就緒或者可用(就緒至少持續(xù)了 `MinReadySeconds` 秒)

完成(Complete)

當(dāng) Deployment 具有以下特征時,Kubernetes 將其標(biāo)記為 完成(Complete)

- 與 DM 關(guān)聯(lián)的所有副本都已更新到指定的最新版本,這意味著之前請求的所有更新都已完成。
- 與 DM 關(guān)聯(lián)的所有副本都可用。
- 未運(yùn)行 DM 的舊副本。

失敗的(Failed)

當(dāng)Deployment 在嘗試部署其最新的 ReplicaSet 受挫時,會一直處于未完成狀態(tài)。 造成此情況可能因素如下:

- 配額(Quota)不足
- 就緒探測(Readiness Probe)失敗
- 鏡像拉取錯誤
- 權(quán)限不足
- 限制范圍(Limit Ranges)問題
- 應(yīng)用程序運(yùn)行時的配置錯誤

考點(diǎn)之集群中能不能設(shè)置多個Deployments控制器具有重疊的標(biāo)簽選擇器?

首先答案肯定是不能的。

如果這樣做,后果是什么呢?如果有多個控制器的標(biāo)簽選擇器發(fā)生重疊,則控制器之間會因沖突而無法正常工作。

另一篇已經(jīng)討論類似問題:線上預(yù)警k8s集群循環(huán)創(chuàng)建、刪除Pod副本,一直無法穩(wěn)定指定目標(biāo)副本數(shù)量?如果排除了是Pod內(nèi)部發(fā)生了故障,從RS角度你猜測可能是什么原因?

上一篇主要說明的是多個ReplicaSets 配置了相同的標(biāo)簽選擇符,使用相同的標(biāo)簽選擇器創(chuàng)建多個ReplicaSet,則多個RS無法識別哪個Pod是自己創(chuàng)建的,都會認(rèn)為是歸屬于自己管理的Pod。這樣做的后果就是會造成Pod被競爭接管的情況,導(dǎo)致Pod副本數(shù)量一直無法穩(wěn)定。

我們知道 DeploymentPodsReplicaSets 提供了聲明式的更新能力,主要管控的是RS和Pods。

Kubernetes 不會阻止你去給設(shè)置重疊的標(biāo)簽選擇器,但是既然RS和Pods會出現(xiàn)因?yàn)楦偁幙酥埔l(fā)的管理沖突情況,那么身為他們倆的管理者DM肯定是不能獨(dú)善其身,一定會受到影響的。

那么為了不出現(xiàn)管理沖突,我們應(yīng)該怎么做呢?

必須在 Deployment 中指定適當(dāng)?shù)臉?biāo)簽選擇器和 Pod 模板標(biāo)簽,同時標(biāo)簽或者標(biāo)簽選擇器不要與其他控制器(包括其他 DeploymentStatefulSet)重疊。

image

考點(diǎn)之可以自定義Pod-template-hash 標(biāo)簽嘛?如果可以,有什么好處?如果不可以,有什么危害?

k8s官方說明: 不要更改此標(biāo)簽

k8s官方直接明確的告訴我們,不要自定義Pod-template-hash 標(biāo)簽,那么為什么呢?憑什么就不能自定義?

Deployment 控制器會將自己創(chuàng)建或者管理的每一個ReplicaSet 身上都標(biāo)注Pod-template-hash 標(biāo)簽。

唯一的目的就是利用這個標(biāo)簽確保 Deployment 的子 ReplicaSets 不重疊

注意DeploymentReplicaSet 的名稱始終被格式化[Deployment名稱]-[隨機(jī)字符串]。

其中隨機(jī)字符串是使用 pod-template-hash 作為種子隨機(jī)生成的。

通過對 ReplicaSet 的 PodTemplate 進(jìn)行哈希處理,所生成的哈希值被添加到 ReplicaSet 的標(biāo)簽選擇器、Pod 模板標(biāo)簽,以及RS中的每個Pod身上。

疑問來了,自定義有什么危害呢?

上面說了,這個標(biāo)簽主要是作為名稱隨機(jī),確保不重疊,隨機(jī)到每一個Pod和RS上,可以避免出現(xiàn)多個Deployments控制器具有重疊的標(biāo)簽選擇器。也就是上面說的那個競爭排斥問題。

考點(diǎn)之什么場景下會觸發(fā)Deployments上線動作?

僅當(dāng) Deployment Pod 模板(即 .spec.template)發(fā)生改變時,例如模板的標(biāo)簽或容器鏡像被更新, 才會觸發(fā) Deployment 上線。

其他更新(如對 Deployment 執(zhí)行擴(kuò)縮容的操作)不會觸發(fā)上線動作。

考點(diǎn)之Deployments在更新時會關(guān)閉所有Pod嘛?如果不是,默認(rèn)關(guān)閉最大比例是多少?

Deployment 可確保在更新時僅關(guān)閉一定數(shù)量的 Pod。

默認(rèn)情況下,它確保至少所需 Pods 75% 處于運(yùn)行狀態(tài)(maxUnavailable最大不可用比例為 25%)。

如果有100個Pod,在更新時,最多關(guān)閉25個Pod

DM 保證至少會有75個Pod能正常提供服務(wù)

Deployment 還確保所創(chuàng)建 Pod 數(shù)量只可能比期望 Pods 數(shù)高一點(diǎn)點(diǎn)。

默認(rèn)情況下,它可確保啟動的 Pod 個數(shù)比期望個數(shù)最多多出 25%(最大峰值 25%)。

DM 更新會出現(xiàn)兩種操作
1、銷毀老版本Pod
2、創(chuàng)建新版本Pod

無論是銷毀還是創(chuàng)建
默認(rèn)峰值都是25%

銷毀時,最多同時銷毀25%Pod
保證有75%的Pod可以繼續(xù)提供服務(wù)

創(chuàng)建時,最多運(yùn)行比預(yù)期副本數(shù)多出25%

也就是說如果預(yù)期存活Pod副本是100個
那么最多允許同時在運(yùn)行125個舊版副本+新版副本

考點(diǎn)之你能不能簡單描述一下Deployments更新時RS和Pod是如何滾動更新的?

如果不去更改默認(rèn)的最大不可用比例和最大運(yùn)行峰值比例,那么DM更新時,會創(chuàng)建新版本RS,并將其進(jìn)行擴(kuò)容,控制到Pod副本數(shù)量滿足最大運(yùn)行峰值比例。

達(dá)到比例后,DM會停止新版RS擴(kuò)容,不會再創(chuàng)建新版Pod,直到DM殺死足夠多的舊版Pod

接下來對舊版本RS進(jìn)行縮容操作,控制去除Pod副本數(shù)量滿足最大不可用比例

同樣,達(dá)到比例后,DM會停止舊版RS刪除,不會再繼續(xù)刪除舊版Pod,直到DM創(chuàng)建到足夠多的新版Pod

此為一輪更新,DM不斷的進(jìn)行滾動更新上述操作,直到舊版RS,舊版Pod副本數(shù)為0,新版副本數(shù)穩(wěn)定,停止?jié)L動更新。

考點(diǎn)之如何判定Deployment上線過程是否出現(xiàn)停滯?有哪些原因會造成停滯?如何解決配額不足的問題?

Deployment 可能會在嘗試部署最新的 ReplicaSet 時出現(xiàn)故障,一直處于未完成的停滯狀態(tài)。

造成此情況一些可能因素如下:

- 配額(Quota)不足
- 就緒探測(Readiness Probe)失敗
- 鏡像拉取錯誤
- 權(quán)限不足
- 限制范圍(Limit Ranges)問題
- 應(yīng)用程序運(yùn)行時的配置錯誤

如何判定Deployment上線過程是否出現(xiàn)停滯?

檢測此狀況的一種方法是在 Deployment 規(guī)約中指定截止時間參數(shù).spec.progressDeadlineSeconds。

一旦超過 Deployment 進(jìn)度限期,Kubernetes 將更新DM狀態(tài)和進(jìn)度狀況的原因:

Conditions:
  Type            Status  Reason
  ----            ------  ------
  Available       True    MinimumReplicasAvailable
  Progressing     False   ProgressDeadlineExceeded
  ReplicaFailure  True    FailedCreate

通過 Deployment 狀態(tài),就能知道是否出現(xiàn)停滯。你可以使用 kubectl rollout status 檢查 Deployment 是否未能取得進(jìn)展。 如果 Deployment 已超過進(jìn)度限期,kubectl rollout status 返回非零退出代碼。

判斷停滯,這時候我們可以在上線過程中間安全地暫停 Deployment ,對其進(jìn)行上線修復(fù)。

假設(shè)排查出停滯原因是配額不足,直接在命名空間中增加配額 來解決配額不足的問題。

配額條件滿足,Deployment 控制器完成了 Deployment 上線操作, Deployment 狀態(tài)會更新為成功狀況(Status=True and Reason=NewReplicaSetAvailable

考點(diǎn)之保存修訂歷史會消耗 etcd 中的資源,并占用 kubectl get rs 的輸出,如果給修訂歷史限制值設(shè)置為0是不是就能有效解決這個問題?

.spec.revisionHistoryLimit 是一個可選字段,用來設(shè)定為回滾操作所備份保留的舊 ReplicaSet 數(shù)量。

這些舊 ReplicaSet 會消耗 etcd 中的資源,并占用 kubectl get rs 的輸出。

每個 Deployment 修訂版本的配置都存儲在其 ReplicaSets 中;

因此,一旦刪除了舊的 ReplicaSet將失去回滾到 Deployment 的對應(yīng)修訂版本的能力。

默認(rèn)情況下,系統(tǒng)保留 10 個舊 ReplicaSet,但其理想值取決于新 Deployment 的頻率和穩(wěn)定性。

如果給修訂歷史限制值設(shè)置為0,將導(dǎo)致 Deployment 的所有歷史記錄被清空。沒有了歷史備份,因此 Deployment 將無法回滾,無法撤消新的 Deployment 上線。

總結(jié):雖然可以減少etcd的資源消耗,但是不利于k8s集群實(shí)現(xiàn)故障容錯、高可用。為了節(jié)約一些資源,而放棄容錯,高可用性質(zhì),只能說,非常非常非常,不值得。

image

獲取更多干貨(MySQL、K8S),歡迎關(guān)注微信公眾號:囧么肥事

Kubernetes 推薦學(xué)習(xí)書

Kubernetes權(quán)威指南PDF
鏈接: https://pan.baidu.com/s/11huLHJkCeIPZqSyLEoUEmQ 提取碼:sa88


《Kubernetes-企業(yè)級容器應(yīng)用托管》-持續(xù)胡說八道

第一段:推薦閱讀:【云原生新時代弄潮兒k8s憑什么在容器化方面獨(dú)樹一幟?】

第二段:推薦閱讀:【趁著同事玩游戲偷偷認(rèn)識k8s一家子補(bǔ)補(bǔ)課】

第三段:推薦閱讀:【Kubernetes家族容器小管家Pod在線答疑?】

第四段:推薦閱讀:【同事提出個我從未想過的問題,為什么Kubernetes要"多此一舉"推出靜態(tài)Pod概念?】

第五段:推薦閱讀:【探針配置失誤,線上容器應(yīng)用異常死鎖后,kubernetes集群未及時響應(yīng)自愈重啟容器?】

第六段:推薦閱讀:【kubernetes集群之Pod說能不能讓我體面的消亡呀?】

第七段:推薦閱讀:【k8s家族Pod輔助小能手Init容器認(rèn)知答疑?】

第八段:推薦閱讀:【k8s初面考點(diǎn)ReplicaSet副本集極限9連擊你懂了嗎?】

第九段:推薦閱讀:【生產(chǎn)環(huán)境想要對某個Pod排錯、數(shù)據(jù)恢復(fù)、故障復(fù)盤有什么辦法?】

第十段:推薦閱讀:【跟k8s工作負(fù)載Deployments的緣起緣滅】

后續(xù)未更新?推薦休閑閱讀:【囧么肥事】

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容