k8s集群StatefulSets的Pod優雅調度問題思考?

k8s集群StatefulSets的Pod優雅調度問題思考

考點之你能解釋一下為什麼k8s的 StatefulSets 需要VolumeClaimTemplate嘛?
考點之簡單描述一下StatefulSets 對Pod的編排調度過程?
考點之針對線上StatefulSet 的Pod縮容故障無法正常縮容的情況,你能灰度分析一下嘛?
考點之聊聊什麼是StatefulSet的分區滾動更新吧?什麼場景需要使用分區更新?
考點之StatefulSet提供優雅穩定的存儲,但是線上告警StatefulSet Pod重新調度後數據丟失?

囧么肥事-胡說八道

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

對於k8s集群來說有狀態的副本集都會用到持久存儲

Deployment中的Pod template里定義的存儲卷,是基於模板配置調度所有副本集共用一個存儲卷,數據是相同的。

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

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

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

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

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

簡單描述一下StatefulSets 對Pod的編排調度過程?

StatefulSets 提供了有序且優雅的部署和擴縮保證

SS是如何優雅部署和擴縮的呢?

對於包含 N 個 副本的 StatefulSet

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

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

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

在 Pod 終止之前,所有的繼任者必須完全關閉

創建或擴容過程,以Nginx舉例

定義副本數replicas=3

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

SS嚴格執行部署或調度順序,按序部署
ng-0 開始部署...
ng-0 進入Running 和 Ready 狀態

SS 檢測 ng-0 部署狀態
確定ng-0,符合Running 和 Ready 狀態

ng-1 開始部署
ng-1 進入Running 和 Ready 狀態

SS 檢測 ng-0 和 ng-1 部署狀態
確定ng-0 和 ng-1 都符合Running 和 Ready 狀態
才會執行 ng-2 部署

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

ng-2 開始部署
ng-2 進入Running 和 Ready 狀態

類似,StatefulSet 進行縮容跟擴容整體規則是一樣的,只不過縮容時,終止順序和創建順序相反

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

注意:如果SS在縮容過程中,有些Pod發生了故障,那麼終止會進入阻塞,等待發生故障的Pod重新調度,進入Running和Ready狀態之後才會繼續執行SS縮容。

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

為什麼縮容無法正常執行?

StatefulSet 執行縮容操作,需要保證管轄範圍內的Pod處於健康狀態。如果某些Pod發生故障,則縮容會陷入阻塞,無法繼續執行。

僅當 StatefulSet 等待到所有 Pod 都處於運Running和 Ready 狀態後才可繼續進行縮容操作。

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

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

Pod 不健康可能是由於永久性故障造成也可能是瞬態故障

永久性故障

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

瞬態故障

瞬態故障可能是節點升級或維護而引起的節點重啟造成的。

如果由於瞬態故障而導致 Pod 不健康,一般情況下,Pod 最終會再次變為可用,但是瞬態錯誤也可能會干擾 你對 StatefulSet 的擴容/縮容操作。

一些分佈式數據庫在同時有節點加入和離開時會遇到問題。

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

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

先說一下StatefulSet的更新策略

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

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

RollingUpdate 更新策略

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

OnDelete更新策略

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

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

滾動更新

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

Kubernetes 控制面會等到被更新的 Pod 進入 Running 和 Ready 狀態,然後再更新其前身Pod。

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

接下來進入主題什麼是分區滾動更新?

分區滾動更新是滾動更新策略中的一個特殊場景,StatefulSet 控制一定範圍內的Pod進行滾動更新,調度為新版本Pod運行,而範圍外的Pod繼續維持老版本運行。

可以理解為,學校16個班級,校長通知說:”今天最後5個班級留下來打掃衛生”

通過聲明 .spec.updateStrategy.rollingUpdate.partition 的方式,RollingUpdate 更新策略可以實現分區。

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

所有序號大於等於該分區序號的 Pod 都會被更新
所有序號小於該分區序號的 Pod 都不會被更新

分區更新,就是進行分段處理

假設原來有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執行滾動更新時
ng-4 更新
ng-3 更新
ng-2 更新
ng-1 不更新
ng-0 不更新

需要注意的是,分區範圍外的Pod,即使他們被刪除或是重新調度,也會依據之前的舊版本進行重建,不會依賴當前最新版本重建。

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

分區更新應用場景?

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

StatefulSet提供優雅穩定的存儲,但是線上告警StatefulSet Pod重新調度後數據丟失?

究竟是什麼情況呢?

我們都知道k8s中當 StatefulSet 或者它管理的 Pod 被刪除時並不會刪除關聯的卷,當重新調度完成後,新Pod應該會掛載原PV,繼續使用上一個Pod的數據。

壞事來了,本應該繼續使用原PV,皆大歡喜,可是線上告警發現PV 持久卷無法使用,導致數據丟失。咦,失聯了???

k8s刪除 StatefulSet 管理的 Pod 並不會刪除關聯的PV卷,這是為了確保你有機會重新調度Pod之後繼續使用原PV卷,或者在刪除卷之前從卷中複製數據,保證數據不會丟失。當一個 Pod 被調度(重新調度)到節點上時,它的 volumeMounts 會掛載與其 PVC相關聯的 PV。

刪除StatefulSet 和Pod雖然不會刪除關聯的PV卷,但是刪除PVC就不一定了,問題就出現在這裡,在 Pod 離開終止狀態後刪除 PVC ,可能會觸發刪除背後的 PV 持久卷,具體觸發策略要取決配置的存儲類和回收策略。

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

警告:⚠️ 刪除 PVC 時要謹慎,因為這可能會導致數據丟失

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