OpenKruise 如何实现应用的可用性防护?
作者|趙明山(立衡)
前言
OpenKruise 是阿里云開源的云原生應用自動化管理套件,也是當前托管在 Cloud Native Computing Foundation (CNCF) 下的 Sandbox 項目。它來自阿里巴巴多年來容器化、云原生的技術沉淀,是阿里內部生產環境大規模應用的基于 Kubernetes 之上的標準擴展組件,也是緊貼上游社區標準、適應互聯網規模化場景的技術理念與最佳實踐。
?
OpenKruise 在 2021.9.6 發布了最新的 v0.10.0 版本新增了彈性拓撲管理和應用安全防護等能力,本文將為大家揭曉 OpenKruise 是如何實現應用的可用性防護能力。
背景
在文章開始部分,我想先聊聊到底什么是“應用的可用性防護”。例如,在 Kubernetes 上面部署的 ETCD 服務,時刻要保證可用的實例數不小于 N(受限于 raft 協議的選舉機制)。很多同學都會想到 Deployment 中可以設置 maxUnavailable,那不就行了嗎?再說了,還會有 RS Controller 在做副本控制呢?仔細想想,Deployment 的 MaxUnavailable 是在應用滾動發布的過程中保證最小的 Pod 數量,而 RS Controller 控制器則是盡快讓應用實際的福本數等于預期的副本數,并不能保證應用每時每刻的最小可用副本數。
針對上述場景,Kubernetes 原生提供的 PodDisruptionBudget(PDB)通過限制同時中斷 Pod 的數量,來保證應用的高可用性。但是,當前 PDB 的能力并不全面,它只能防護 Pod Eviction 場景(例如:kubectl drain node 驅逐 node 上面的 Pod)。在如下“并發 Pod 更新/驅逐/刪除”場景中,即便有 PDB 防護依然將會導致業務中斷、服務降級:
- 應用 owner 通過 Deployment 正在進行版本升級,與此同時集群管理員由于機器資源利用率過低正在進行 node 縮容
- 中間件團隊利用 SidecarSet 正在原地升級集群中的sidecar版本(例如:ServiceMesh envoy),同時 HPA 正在對同一批應用進行縮容
- 應用 owner 和中間件團隊利用 CloneSet、SidecarSet 原地升級的能力,正在對同一批 Pod 進行升級
PodUnavailableBudget 提升應用的高可用性
Kubernetes 原生 PDB 為什么只能防護 Pod Eviction 的場景呢?首先,讓我們來看看它的實現原理:PDB 通過 selector 選擇了一批防護的 Pod 列表,minAvailable 則表明最小可用的 Pod 數量,pdb-controller 根據前面兩個值以及線上 Pod 的 ready 狀態,計算出當前時刻最多允許中斷的 Pod 數量 PodDisruptionAllowd。k8s pod evictionRestful API 接口則會根據 pdb PodDisruptionAllowd 來決定接口成功還是返回 400 報錯。到了這里終于真相大白了,pdb 通過 evictionRestful API 接口來實現 pod 的防護能力,所以它只能適用于 Pod Eviction 場景。
OpenKruise PodUnavailableBudget(PUB)安全防護的整體思路與 PDB 其實也大致相同,不過在關鍵的防護路徑上面做了一些調整。Voluntary Disruption(諸如:集群管理員驅逐 Node、并發升級 Pod)主動導致 Pod 不可用的場景其實可以歸納為以下三類:
- Modification Pod.Spec 定義(CloneSet、SidecarSet 原地升級 container)
- Delete Pod(Deployment 等控制器滾動升級 Pod、直接 Delete Pod)
- Eviction API(kubectl drain node 驅逐 Pod)
OpenKruise 基于 Kubernetes Adminssion Webhook 機制添加針對 Pod Update/Delete/Eviction 的 webhook 邏輯,根據 pub 的 PodUnavailableAllowed 來實現更加全面的應用 Pod 安全防護機制,邏輯架構如下:
應用場景
- 無狀態應用:比如想至少有 60% 的副本 Available
-
- 解決辦法:創建 PUB Object,指定 minAvailable 為 60%,或者 maxUnavailable 為 40%
- 有狀態應用:最少可用的實例數不能少于某個數 N(比如受限于 raft 協議類應用的選舉機制)
-
- 解決辦法:設置 maxUnavailable=1 或者 minAvailable=N,分別允許每次只刪除一個實例或每次刪除 workload.replicas - minAvailable 個實例
- 單實例應用:終止這個實例之前必須提前通知客戶并取得同意
-
- 解決辦法:創建 PUB Object,并設置 maxUnavailable 為 0,這樣 OpenKruise 就會阻止這個實例的刪除,然后去通知并征求用戶同意后,再把這個 PUB 刪除從而解除這個阻止,然后再去 recreate
總結
Kubernetes 給用戶帶來極致彈性調度的同時也給應用的高可用性帶來了一定的考驗,PUB 是在 Voluntary Disruption 場景下的一種嘗試,同時配合 OpenKruise 提供的防級聯刪除的能力相信能在一定程度上提升線上應用的穩定性。而針對更加棘手 InVoluntary Disruption(諸如:集群 Node 網絡腦裂、vk 節點異常)導致 Pod 不可用等降低應用可用性的場景,OpenKruise 未來也會有更多的探索。與此同時,我們也歡迎更多的同學參與到 OpenKruise 社區來,共同建設一個場景更加豐富、完善的 K8s 應用管理、交付擴展能力,能夠面向更加規模化、復雜化、極致性能的場景。
Github:https://github.com/openkruise/kruise
Official:https://openkruise.io/
Slack: Channel in Kubernetes Slack
釘釘交流群:搜索群號【23330762】可添加~
戳鏈接(https://github.com/openkruise/kruise),查看 OpenKruise 項目 github 主頁!!
總結
以上是生活随笔為你收集整理的OpenKruise 如何实现应用的可用性防护?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 业界首个机密计算容器运行时—Inclav
- 下一篇: Serverless 工程实践 | Se