k8s集群StatefulSets的Pod優(yōu)雅調(diào)度問題思考?

k8s集群StatefulSets的Pod優(yōu)雅調(diào)度問題思考?

考點之你能解釋一下為什么k8s的 StatefulSets 需要VolumeClaimTemplate嘛?
考點之簡單描述一下StatefulSets 對Pod的編排調(diào)度過程?
考點之針對線上StatefulSet 的Pod縮容故障無法正常縮容的情況,你能灰度分析一下嘛?
考點之聊聊什么是StatefulSet的分區(qū)滾動更新吧?什么場景需要使用分區(qū)更新?
考點之StatefulSet提供優(yōu)雅穩(wěn)定的存儲,但是線上告警StatefulSet Pod重新調(diào)度后數(shù)據(jù)丟失?
image

囧么肥事-胡說八道

image
image
image

你能解釋一下為什么k8s的 StatefulSets 需要VolumeClaimTemplate嘛?

對于k8s集群來說有狀態(tài)的副本集都會用到持久存儲

Deployment中的Pod template里定義的存儲卷,是基于模板配置調(diào)度,所有副本集共用一個存儲卷,數(shù)據(jù)是相同的。

StatefulSet職責是管理有狀態(tài)應用,所以它管理的每個Pod都要自已的專有存儲卷,它的存儲卷就不能再用Pod模板來創(chuàng)建。

所以 StatefulSets 需要一種新方式來為管轄的Pod分配存儲卷。

就這樣VolumeClaimTemplate來了,k8sStatefulSets 設置了VolumeClaimTemplate,也就是卷申請模板。

說了為什么需要它,那么VCT到底是什么呢?

VolumeClaimTemplate:基于靜態(tài)或動態(tài)地PV供給方式為Pod資源提供專有且固定的存儲,它會為每個Pod都生成不同的PVC,并且綁定PV,實現(xiàn)每個Pod都有自己獨立專用的存儲卷。

簡單描述一下StatefulSets 對Pod的編排調(diào)度過程?

StatefulSets 提供了有序且優(yōu)雅的部署和擴縮保證

SS是如何優(yōu)雅部署和擴縮的呢?

對于包含 N 個 副本的 StatefulSet

當部署 Pod 時,它們是依次創(chuàng)建的,順序為 `0..N-1`。

當刪除 Pod 時,它們是逆序終止的,順序為 `N-1..0`。

在將縮放操作應用到 Pod 之前,它前面的所有 Pod 必須是 Running 和 Ready 狀態(tài)。

在 Pod 終止之前,所有的繼任者必須完全關(guān)閉

創(chuàng)建或擴容過程,以Nginx舉例

定義副本數(shù)replicas=3

SS會創(chuàng)建3個Pod
分配有序序號
ng-0, ng-1, ng-2

SS嚴格執(zhí)行部署或調(diào)度順序,按序部署
ng-0 開始部署...
ng-0 進入Running 和 Ready 狀態(tài)

SS 檢測 ng-0 部署狀態(tài)
確定ng-0,符合Running 和 Ready 狀態(tài)

ng-1 開始部署
ng-1 進入Running 和 Ready 狀態(tài)

SS 檢測 ng-0 和 ng-1 部署狀態(tài)
確定ng-0 和 ng-1 都符合Running 和 Ready 狀態(tài)
才會執(zhí)行 ng-2 部署

假設此時 ng-0 發(fā)生故障
那么ng-2 會阻塞,等待 ng-0 重新部署完成

ng-2 開始部署
ng-2 進入Running 和 Ready 狀態(tài)

類似,StatefulSet 進行縮容跟擴容整體規(guī)則是一樣的,只不過縮容時,終止順序和創(chuàng)建順序相反。

按照 ng-2, ng-1, ng-0 的順序進行縮容操作。ng-2沒有完全停止和刪除前,ng-1不會進行終止操作。

注意:如果SS在縮容過程中,有些Pod發(fā)生了故障,那么終止會進入阻塞,等待發(fā)生故障的Pod重新調(diào)度,進入Running和Ready狀態(tài)之后才會繼續(xù)執(zhí)行SS縮容。

針對線上StatefulSet 的Pod縮容故障無法正常縮容的情況,你能灰度分析一下嘛?

為什么縮容無法正常執(zhí)行?

StatefulSet 執(zhí)行縮容操作,需要保證管轄范圍內(nèi)的Pod處于健康狀態(tài)。如果某些Pod發(fā)生故障,則縮容會陷入阻塞,無法繼續(xù)執(zhí)行。

僅當 StatefulSet 等待到所有 Pod 都處于運Running和 Ready 狀態(tài)后才可繼續(xù)進行縮容操作。

了解完為什么縮容無法執(zhí)行,那么再聊聊可能導致無法正常縮容原因都有哪些?

如果 spec.replicas 大于 1,Pod副本數(shù)量大于1 ,Kubernetes 無法直接判定 Pod 不健康的原因。

Pod 不健康可能是由于永久性故障造成也可能是瞬態(tài)故障。

永久性故障

如果該 Pod 不健康是由于永久性故障導致,則在不糾正該故障的情況下進行縮容可能會導致 StatefulSet 成員 Pod 數(shù)量低于應正常運行的副本數(shù)。這種狀態(tài)也許會導致 StatefulSet 不可用。

瞬態(tài)故障

瞬態(tài)故障可能是節(jié)點升級或維護而引起的節(jié)點重啟造成的。

如果由于瞬態(tài)故障而導致 Pod 不健康,一般情況下,Pod 最終會再次變?yōu)榭捎?/strong>,但是瞬態(tài)錯誤也可能會干擾 你對 StatefulSet 的擴容/縮容操作。

一些分布式數(shù)據(jù)庫在同時有節(jié)點加入和離開時會遇到問題。

在這些情況下,最好是在應用級別進行分析擴縮操作的狀態(tài),并且只有在確保 Stateful 應用的集群是完全健康時才執(zhí)行擴縮操作。

image

聊聊什么是StatefulSet的分區(qū)滾動更新吧?什么場景可以使用分區(qū)更新?什么情況分區(qū)更新會失效?

先說一下StatefulSet的更新策略

StatefulSet.spec.updateStrategy 字段可以配置和禁用掉自動滾動更新 Pod 的容器、標簽、資源請求或限制、以及注解。

spec.updateStrategy 有兩個允許的值:RollingUpdateOnDelete

RollingUpdate 更新策略

對 StatefulSet 中的 Pod 執(zhí)行自動的滾動更新。這是默認的更新策略

OnDelete更新策略

StatefulSet 將不會自動更新 StatefulSet 中的 Pod

當StatefulSet 的 .spec.template 設置出現(xiàn)變動
用戶必須手動刪除 Pod 以便讓控制器創(chuàng)建新的 Pod

滾動更新

StatefulSet.spec.updateStrategy.type 被設置為 RollingUpdate 時, 屬于默認滾動更新策略,這個時候如果template發(fā)生變化,StatefulSet 控制器會自動發(fā)起調(diào)度,進行刪除和重建 StatefulSet 中的每個 Pod。 它將按照與 Pod 終止相同的順序(從最大序號到最小序號)進行,每次更新一個 Pod。

Kubernetes 控制面會等到被更新的 Pod 進入 Running 和 Ready 狀態(tài),然后再更新其前身Pod。

如果你設置了 .spec.minReadySeconds(最短就緒秒數(shù)),控制面在 Pod 就緒后會額外等待一定的時間再執(zhí)行下一步。

接下來進入主題什么是分區(qū)滾動更新?

分區(qū)滾動更新是滾動更新策略中的一個特殊場景,StatefulSet 控制一定范圍內(nèi)的Pod進行滾動更新,調(diào)度為新版本Pod運行,而范圍外的Pod繼續(xù)維持老版本運行。

可以理解為,學校16個班級,校長通知說:"今天最后5個班級留下來打掃衛(wèi)生"

通過聲明 .spec.updateStrategy.rollingUpdate.partition 的方式,RollingUpdate 更新策略可以實現(xiàn)分區(qū)。

如果聲明了一個分區(qū),當 StatefulSet 的 .spec.template 被更新時

所有序號大于等于該分區(qū)序號的 Pod 都會被更新
所有序號小于該分區(qū)序號的 Pod 都不會被更新

分區(qū)更新,就是進行分段處理。

假設原來有5個Pod
ng-0
ng-1
ng-2
ng-3
ng-4

SS滾動更新
ng-4 更新
ng-3 更新
ng-2 更新
ng-1 更新
ng-0 更新

如果指定 partition=2
那么SS執(zhí)行滾動更新時
ng-4 更新
ng-3 更新
ng-2 更新
ng-1 不更新
ng-0 不更新

需要注意的是,分區(qū)范圍外的Pod,即使他們被刪除或是重新調(diào)度,也會依據(jù)之前的舊版本進行重建,不會依賴當前最新版本重建。

此外,如果 StatefulSet 的 .spec.updateStrategy.rollingUpdate.partition 大于它的 .spec.replicas,對它的 .spec.template 的更新將不會傳遞到它的 Pod,此時所謂分區(qū)更新將失去意義。

分區(qū)更新應用場景?

在大多數(shù)情況下,你不需要使用分區(qū),但如果你希望進行階段式更新、執(zhí)行金絲雀或執(zhí)行分階段上線,則分區(qū)更新會非常有用。

StatefulSet提供優(yōu)雅穩(wěn)定的存儲,但是線上告警StatefulSet Pod重新調(diào)度后數(shù)據(jù)丟失?

究竟是什么情況呢?

我們都知道k8s中當 StatefulSet 或者它管理的 Pod 被刪除時并不會刪除關(guān)聯(lián)的卷,當重新調(diào)度完成后,新Pod應該會掛載原PV,繼續(xù)使用上一個Pod的數(shù)據(jù)。

壞事來了,本應該繼續(xù)使用原PV,皆大歡喜,可是線上告警發(fā)現(xiàn)PV 持久卷無法使用,導致數(shù)據(jù)丟失。咦,失聯(lián)了???

k8s刪除 StatefulSet 管理的 Pod 并不會刪除關(guān)聯(lián)的PV卷,這是為了確保你有機會重新調(diào)度Pod之后繼續(xù)使用原PV卷,或者在刪除卷之前從卷中復制數(shù)據(jù),保證數(shù)據(jù)不會丟失。當一個 Pod 被調(diào)度(重新調(diào)度)到節(jié)點上時,它的 volumeMounts 會掛載與其 PVC相關(guān)聯(lián)的 PV。

刪除StatefulSet 和Pod雖然不會刪除關(guān)聯(lián)的PV卷,但是刪除PVC就不一定了,問題就出現(xiàn)在這里,在 Pod 離開終止狀態(tài)后刪除 PVC ,可能會觸發(fā)刪除背后的 PV 持久卷,具體觸發(fā)策略要取決配置的存儲類和回收策略。

警告:?? 永遠不要假定在 PVC 刪除后仍然能夠訪問卷

警告:?? 刪除 PVC 時要謹慎,因為這可能會導致數(shù)據(jù)丟失

image

Kubernetes 推薦學習書

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

k8s系列所有問題更新記錄:GitHub

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

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

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