Kubernetes 中的 Pod 優先權如何導致 Grafana Labs 停機

筆記。 翻譯。:我們向您提供有關 Grafana 創建者維護的雲端服務最近停機原因的技術詳細資訊。 這是一個典型的例子,說明了一個旨在提高基礎設施品質的看似極其有用的新功能...如果您不考慮其在生產現實中的應用程式的眾多細微差別,可能會造成損害。 當這樣的材料出現時,讓你不僅可以從錯誤中學習,真是太好了。 詳細資訊請參閱 Grafana Labs 產品副總裁翻譯的本文。

Kubernetes 中的 Pod 優先權如何導致 Grafana Labs 停機

19 月 30 日星期五,Grafana Cloud 中的託管 Prometheus 服務停止運作約 XNUMX 分鐘。 我向所有受停電影響的客戶致歉。 我們的工作是提供您所需的監控工具,我們知道,如果沒有這些工具,您的生活會變得更加困難。 我們非常嚴肅地對待這件事。 本說明解釋了發生的情況、我們如何應對以及我們正在採取哪些措施來確保類似情況不再發生。

Grafana Cloud Hosted Prometheus 服務基於 皮質 — CNCF 專案創建水平可擴展、高度可用、多租戶的 Prometheus 服務。 Cortex 架構由一組單獨的微服務組成,每個微服務執行自己的功能:複製、儲存、查詢等。 Cortex 正在積極開發中,並不斷添加新功能並提高效能。 我們定期將新的 Cortex 版本部署到集群,以便客戶可以利用這些功能 - 幸運的是,Cortex 可以在不停機的情況下進行更新。

為了實現無縫更新,Ingester Cortex 服務在更新過程中需要額外的 Ingester 副本。 (筆記。 翻譯。: 攝取者 - 皮質的基本組成部分。 它的工作是收集源源不斷的樣本流,將它們分組為 Prometheus 區塊,並將它們儲存在 DynamoDB、BigTable 或 Cassandra 等資料庫中。) 這允許舊的 Ingester 將目前資料轉送到新的 Ingester。 值得注意的是,Ingesters 需要資源。 為了讓它們工作,每個 pod 需要 4 個核心和 15 GB 內存,即在我們的 Kubernetes 叢集中,基礎機器的處理能力和記憶體為 25%。 一般來說,叢集中的未使用資源通常多於 4 個核心和 15 GB 內存,因此我們可以在升級期間輕鬆啟動這些額外的接收器。

然而,在正常操作期間,經常會發生這樣的情況:沒有一台機器擁有這 25% 的未使用資源。 是的,我們甚至不努力:CPU 和記憶體始終對其他進程有用。 為了解決這個問題,我們決定使用 Kubernetes Pod 優先權。 這個想法是給予 Ingesters 比其他(無狀態)微服務更高的優先順序。 當我們需要執行額外的 (N+1) 個 Ingester 時,我們會暫時取代其他較小的 Pod。 這些 Pod 被轉移到其他機器上的免費資源,留下足夠大的「洞」來運行額外的 Ingester。

18 月 XNUMX 日星期四,我們為集群推出了四個新的優先事項: 批判的, , 平均 и 。 他們在一個沒有客戶端流量的內部叢集上進行了大約一週的測試。 預設情況下,接收沒有指定優先順序的 Pod 平均 優先級,為攝取器設定了類別 高的 優先事項。 危急 保留用於監控(Prometheus、Alertmanager、node-exporter、kube-state-metrics 等)。 我們的config已經開放了,你可以查看PR 這裡.

事故

19 月 XNUMX 日星期五,一位工程師為一家大客戶推出了一個新的專用 Cortex 叢集。 此叢集的配置不包括新的 pod 優先權,因此所有新 pod 都被指派了預設優先權 - 平均.

Kubernetes 叢集沒有足夠的資源用於新的 Cortex 集群,並且現有的生產 Cortex 叢集沒有更新(Ingesters 沒有更新) 高的 優先事項)。 由於新叢集的 Ingesters 預設有 平均 優先級,且生產中的現有 Pod 完全沒有優先權,新叢集的 Ingester 取代了現有 Cortex 生產叢集中的 Ingesters。

生產集群中被驅逐的 Ingester 的 ReplicaSet 檢測到被驅逐的 pod 並創建了一個新的 pod 來維護指定數量的副本。 預設分配新的 Pod 平均 優先級,生產中的另一個“舊”Ingester 失去了資源。 結果是 雪崩過程,這導致 Cortex 生產叢集中的所有 Pod 都從 Ingester 中轉移。

攝取器是有狀態的並儲存過去 12 小時的資料。 這使我們能夠在將它們寫入長期儲存之前更有效地壓縮它們。 為了實現這一目標,Cortex 使用分散式雜湊表 (DHT) 對系列中的資料進行分片,並使用 Dynamo 風格的仲裁一致性在三個 Ingester 之間複製每個系列。 Cortex 不會將資料寫入已停用的 Ingester。 因此,當大量 Ingester 離開 DHT 時,Cortex 無法提供足夠的條目複製,並且它們會崩潰。

檢測和修復

基於「錯誤預算」的新 Prometheus 通知(基於誤差預算 — 詳細資訊將在以後的文章中出現)在關閉開始 4 分鐘後開始拉響警報。 在接下來的五分鐘左右的時間裡,我們運行了一些診斷並擴展了底層 Kubernetes 叢集以託管新的和現有的生產叢集。

又過了五分鐘,舊的 Ingester 成功寫入數據,新的 Ingester 啟動,Cortex 叢集再次可用。

另外 10 分鐘用於診斷和修正位於 Cortex 前面的身份驗證反向代理的記憶體不足 (OOM) 錯誤。 OOM 錯誤是由 QPS 增加十倍引起的(我們認為是由於客戶端 Prometheus 伺服器發出過於激進的請求)。

後果

總停機時間為 26 分鐘。 沒有資料遺失。 攝取器已成功將所有記憶體資料載入到長期儲存中。 在關閉期間,Prometheus 伺服器的客戶端緩衝區被刪除 (偏僻的) 錄音使用 新 API 遠端寫入 基於WAL(作者: 卡勒姆·斯蒂恩 來自 Grafana Labs)並在崩潰後重複失敗的寫入。

Kubernetes 中的 Pod 優先權如何導致 Grafana Labs 停機
生產集群寫入操作

發現

重要的是要從這一事件中汲取教訓,並採取必要措施避免類似事件再次發生。

事後看來,我們不應該設定預設值 平均 優先級,直到生產中的所有 Ingesters 都收到 優先權。 此外,還需要提前照顧好他們 高的 優先事項。 現在一切都已確定。 我們希望我們的經驗能幫助其他考慮在 Kubernetes 中使用 pod 優先順序的組織。

我們將對任何其他物件的部署添加額外的控制級別,這些物件的配置對於叢集來說是全域的。 從現在開始,此類變更將由о更多的人。 此外,導致崩潰的修改對於單獨的專案文件來說被認為太小了——它僅在 GitHub 問題中進行了討論。 從現在開始,所有此類配置變更都將附有適當的專案文件。

最後,我們將自動調整身份驗證反向代理的大小,以防止我們目睹的過載 OOM,並將審查與回退和擴展相關的 Prometheus 預設設置,以防止將來出現類似問題。

這次失敗也產生了一些正面的後果:在收到必要的資源後,皮質會自動恢復,無需額外幹預。 我們也獲得了寶貴的合作經驗 格拉法娜·洛基 - 我們的新日誌聚合系統 - 這有助於確保所有 Ingester 在故障期間和故障後正常運作。

譯者PS

另請閱讀我們的博客:

來源: www.habr.com

添加評論