我們將 GitLab.com 遷移到 Kubernetes 一年的發現

筆記。 翻譯。:GitLab 採用 Kubernetes 被認為是促進公司發展的兩個主要因素之一。 然而,直到最近,GitLab.com線上服務的基礎設施還是建立在虛擬機器上的,大約一年前才開始遷移到K8s,但目前還沒有完成。 我們很高興提供 GitLab SRE 工程師最近發表的一篇文章的翻譯,介紹了這種情況是如何發生的以及參與專案的工程師得出的結論。

我們將 GitLab.com 遷移到 Kubernetes 一年的發現

大約一年來,我們的基礎設施部門一直在將 GitLab.com 上運行的所有服務遷移到 Kubernetes。 在此期間,我們遇到的挑戰不僅涉及將服務遷移到 Kubernetes,還涉及在過渡期間管理混合部署。 我們將在本文中討論我們學到的寶貴經驗教訓。

從 GitLab.com 一開始,它的伺服器就在雲端的虛擬機器上運作。 這些虛擬機器由 Chef 管理並使用我們的安裝 官方Linux包. 部署策略 如果需要更新應用程序,只需使用 CI 管道以協調、順序的方式更新伺服器群組。 這個方法——雖然慢而且有點 無聊的 - 確保 GitLab.com 使用與離線使用者相同的安裝和設定實踐 (自我管理) 為此,使用我們的 Linux 軟體包進行 GitLab 安裝。

我們使用這種方法是因為體驗社群普通成員在安裝和設定 GitLab 副本時所經歷的所有悲歡離合器是極其重要的。 這種方法在一段時間內效果很好,但當 GitLab 上的專案數量超過 10 萬時,我們意識到它不再滿足我們擴展和部署的需求。

Kubernetes 和雲端原生 GitLab 的第一步

該專案創建於2017年 亞搏體育appGitLab圖表 準備 GitLab 進行雲端部署,並使使用者能夠在 Kubernetes 叢集上安裝 GitLab。 當時我們就知道,將 GitLab 遷移到 Kubernetes 將提高 SaaS 平台的可擴展性、簡化部署並提高運算資源的效率。 同時,我們應用程式的許多功能都依賴掛載的 NFS 分區,這減慢了從虛擬機器的過渡速度。

雲端原生和 Kubernetes 的推動使我們的工程師能夠計劃逐步過渡,在此期間我們放棄了應用程式對網路儲存的一些依賴,同時繼續開發新功能。 自從我們在 2019 年夏天開始計劃遷移以來,許多限制已經得到解決,將 GitLab.com 遷移到 Kubernetes 的過程現在正在順利進行中!

Kubernetes 中 GitLab.com 的功能

對於 GitLab.com,我們使用單一區域 GKE 叢集來處理所有應用程式流量。 為了最大限度地降低(已經很棘手的)遷移的複雜性,我們專注於不依賴本地儲存或 NFS 的服務。 GitLab.com 主要使用單一的 Rails 程式碼庫,我們根據工作負載特徵將流量路由到隔離到各自節點池中的不同端點。

就前端而言,這些類型分為對 Web、API、Git SSH/HTTPS 和登錄機碼的請求。 在後端的情況下,我們根據不同的特徵來拆分佇列中的作業,這取決於 預定義的資源邊界,這使我們能夠為各種工作負載設定服務等級目標 (SLO)。

所有這些 GitLab.com 服務都是使用未經修改的 GitLab Helm 圖表進行設定的。 配置是在子圖中進行的,隨著我們逐步將服務遷移到叢集中,可以選擇性地啟用子圖。 儘管我們決定不在遷移中包含一些有狀態服務,例如 Redis、Postgres、GitLab Pages 和 Gitaly,但使用 Kubernetes 使我們能夠從根本上減少 Chef 目前管理的虛擬機器數量。

Kubernetes 設定可見性與管理

所有設定均由 GitLab 本身管理。 為此,使用了三個基於 Terraform 和 Helm 的配置項目。 我們嘗試盡可能使用 GitLab 本身來運行 GitLab,但對於操作任務,我們有單獨的 GitLab 安裝。 這是為了確保您在執行 GitLab.com 部署和更新時不依賴 GitLab.com 的可用性。

儘管我們的 Kubernetes 叢集管道在單獨的 GitLab 安裝上運行,但程式碼儲存庫的鏡像可在以下位址公開取得:

  • k8s-工作負載/gitlab-com — GitLab Helm 圖表的 GitLab.com 設定架構;
  • k8s-工作負載/gitlab-helmfiles - 包含與 GitLab 應用程式不直接關聯的服務的配置。 其中包括日誌記錄和叢集監控的配置,以及 PlantUML 等整合工具;
  • Gitlab-com-基礎設施 — Kubernetes 和舊 VM 基礎架構的 Terraform 配置。 您可以在此處設定執行叢集所需的所有資源,包括叢集本身、節點池、服務帳戶和 IP 位址預留。

我們將 GitLab.com 遷移到 Kubernetes 一年的發現
進行變更時會顯示公共視圖。 簡短的摘要 包含指向 SRE 在對集群進行更改之前分析的詳細差異的連結。

對於 SRE,該連結會導致 GitLab 安裝中的詳細差異,該安裝用於生產且存取受到限制。 這使得員工和社區無需訪問營運項目(僅對 SRE 開放)即可查看建議的配置變更。 透過將程式碼的公共 GitLab 實例與 CI 管道的私有實例結合,我們維護了單一工作流程,同時確保配置更新獨立於 GitLab.com。

我們在遷移過程中發現了什麼

在遷移過程中,我們獲得了應用於 Kubernetes 中新遷移和部署的經驗。

1. 可用區之間的流量導致成本增加

我們將 GitLab.com 遷移到 Kubernetes 一年的發現
GitLab.com 上 Git 儲存庫群的每日出口統計資料(每天位元組數)

谷歌將其網路劃分為多個區域。 這些又被劃分為可訪問區域 (AZ)。 Git託管與大量資料相關,因此控製網路出口對我們來說很重要。 對於內部流量,只有在同一可用區域內,出口才是免費的。 截至撰寫本文時,我們在一個典型工作日中提供約 100 TB 的資料(這僅適用於 Git 儲存庫)。 在基於 VM 的舊拓撲中,駐留在同一虛擬機器中的服務現在在不同的 Kubernetes Pod 中運作。 這意味著先前位於虛擬機器本地的一些流量可能會傳輸到可用區域之外。

區域 GKE 叢集可讓您跨越多個可用區以實現冗餘。 我們正在考慮可能性 將區域 GKE 集群拆分為單專區集群 用於產生大量流量的服務。 這將降低出口成本,同時保持叢集級冗餘。

2. 限制、資源請求與擴展

我們將 GitLab.com 遷移到 Kubernetes 一年的發現
在registry.gitlab.com 上處理生產流量的副本數量。 世界標準時間 (UTC) 左右的流量高峰期為 15:00。

我們的遷移故事始於 2019 年 XNUMX 月,當時我們將第一個服務 GitLab 容器註冊表遷移到 Kubernetes。 這種關鍵任務、高流量的服務是第一次遷移的不錯選擇,因為它是一個無狀態應用程序,幾乎沒有外部依賴項。 我們遇到的第一個問題是由於節點記憶體不足而導致大量 pod 被驅逐。 因此,我們必須更改請求和限制。

人們發現,在記憶體消耗隨時間增加的應用程式的情況下,請求的低值(為每個 Pod 保留記憶體)加上「慷慨」的使用硬限制會導致飽和 (飽和) 節點和高水準的驅逐。 為了解決這個問題, 決定增加請求並降低限制。 這減輕了節點的壓力,並確保 Pod 的生命週期不會對節點造成太大的壓力。 現在,我們以慷慨(且幾乎相同)的請求和限制值開始遷移,並根據需要進行調整。

3. 指標和日誌

我們將 GitLab.com 遷移到 Kubernetes 一年的發現
基礎設施部門專注於延遲、錯誤率和已安裝的飽和度 服務水準目標 (SLO) 連結到 我們系統的普遍可用性.

在過去的一年裡,基礎設施部門的關鍵事件之一是監控和與 SLO 合作的改進。 SLO 使我們能夠為遷移過程中密切監控的各個服務設定目標。 但即使可觀察性提高,也並非總是能夠使用指標和警報立即發現問題。 例如,透過專注於延遲和錯誤率,我們並沒有完全涵蓋正在遷移的服務的所有用例。

在將一些工作負載遷移到叢集後幾乎立即發現了這個問題。 當我們必須檢查請求數量很少但具有非常特定的配置依賴性的函數時,它變得尤其尖銳。 遷移的主要教訓之一是不僅需要在監控時考慮指標,還需要考慮日誌和“長尾” (這是關於 這樣他們的分佈 在圖表上 - 大約。 譯) 錯誤。 現在,對於每次遷移,我們都包含詳細的日誌查詢列表 (日誌查詢) 並規劃明確的回溯程序,如果出現問題,可以從一個班次轉移到下一個班次。

在舊的虛擬機器基礎架構和新的基於 Kubernetes 的基礎架構上並行服務相同的請求提出了獨特的挑戰。 與直接遷移不同 (將應用程式「按原樣」快速轉移到新的基礎設施;可以閱讀更多詳細信息,例如, 這裡 - 大約。 譯),「舊」虛擬機器和 Kubernetes 上的並行工作要求監控工具與這兩種環境相容,並且能夠將指標組合到一個視圖中。 重要的是,我們使用相同的儀表板和日誌查詢來在過渡期間實現一致的可觀察性。

4. 將流量切換到新集群

對於 GitLab.com,部分伺服器專用於 金絲雀階段。 Canary Park 服務我們的內部項目,也可以 由使用者啟用。 但它的主要目的是測試對基礎設施和應用程式所做的更改。 第一個遷移的服務首先接受有限數量的內部流量,我們繼續使用此方法來確保在將所有流量傳送到叢集之前滿足 SLO。

在遷移的情況下,這意味著對內部專案的請求首先發送到 Kubernetes,然後我們透過 HAProxy 更改後端的權重來逐漸將其餘流量切換到叢集。 在從虛擬機器遷移到 Kubernetes 的過程中,很明顯,有一種簡單的方法可以在新舊基礎設施之間重定向流量,從而使舊基礎設施在遷移後的最初幾天內做好回滾的準備。

5. Pod 的儲備容量及其使用

幾乎立即發現了以下問題:Registry 服務的 pod 啟動很快,但啟動 Sidekiq 的 pod 需要花費 XNUMX分鐘。 當我們開始將需要快速處理作業和快速擴展的工作負載遷移到 Kubernetes 時,Sidekiq Pod 的啟動時間過長就成為了一個問題。

在這個案例中,我們得到的教訓是,雖然Kubernetes 的Horizo​​ntal Pod Autoscaler (HPA) 可以很好地處理流量成長,但考慮工作負載的特徵並向Pod 分配備用容量(特別是當需求分佈不均勻時)也很重要。 在我們的例子中,作業突然激增,導致快速擴展,導致 CPU 資源在我們有時間擴展節點池之前就已經飽和。

總有一種誘惑是從叢集中擠出盡可能多的資源,但是,在最初遇到效能問題後,我們現在開始提供慷慨的 pod 預算,然後再減少,密切關注 SLO。 Sidekiq 服務的 pod 啟動速度顯著加快,現在平均需要約 40 秒。 減少吊艙的啟動時間 贏得了 GitLab.com 和我們使用官方 GitLab Helm 圖表進行自我管理安裝的用戶。

結論

遷移每個服務後,我們對在生產中使用 Kubernetes 的好處感到高興:更快、更安全的應用程式部署、擴展和更有效率的資源分配。 此外,遷移的優勢不僅限於 GitLab.com 服務。 官方 Helm 圖表的每項改進都會讓用戶受益。

我希望您喜歡我們的 Kubernetes 遷移冒險故事。 我們繼續將所有新服務遷移到叢集。 更多資訊可在以下出版物中找到:

譯者PS

另請閱讀我們的博客:

來源: www.habr.com

添加評論