Tinder 過渡到 Kubernetes

筆記。 翻譯。:世界著名的 Tinder 服務的員工最近分享了一些將其基礎設施遷移到 Kubernetes 的技術細節。 這個過程花了近兩年的時間,最終在 K8s 上推出了一個非常大規模的平台,由託管在 200 個容器上的 48 項服務組成。 Tinder 工程師遇到了哪些有趣的困難以及他們取得了哪些成果?請閱讀此翻譯。

Tinder 過渡到 Kubernetes

為什麼呢?

大約兩年前,Tinder 決定將其平台遷移到 Kubernetes。 Kubernetes 將允許 Tinder 團隊透過不可變部署以最少的努力進行容器化並轉移到生產環境 (不可變部署)。 在這種情況下,應用程式的組裝、它們的部署以及基礎設施本身將由程式碼唯一定義。

我們也在尋找可擴展性和穩定性問題的解決方案。 當擴充功能變得至關重要時,我們通常必須等待幾分鐘才能讓新的 EC2 執行個體啟動。 啟動容器並在幾秒鐘而不是幾分鐘內開始提供流量的想法對我們來說非常有吸引力。

結果證明這個過程很困難。 在 2019 年初的遷移過程中,Kubernetes 叢集達到了臨界量,我們開始遇到由於流量、叢集大小和 DNS 等方面的各種問題。 在這個過程中,我們解決了許多有趣的問題,涉及遷移 200 個服務和維護由 1000 個節點、15000 個 Pod 和 48000 個正在運行的容器組成的 Kubernetes 叢集。

怎麼樣?

自2018年XNUMX月以來,我們經歷了遷移的各個階段。 我們首先將所有服務容器化並將其部署到 Kubernetes 測試雲端環境。 從 XNUMX 月開始,我們開始有條不紊地將所有現有服務遷移到 Kubernetes。 到第二年 XNUMX 月,我們完成了遷移,現在 Tinder 平台僅在 Kubernetes 上運行。

為 Kubernetes 建立鏡像

我們有超過 30 個用於在 Kubernetes 叢集上運行的微服務的原始碼儲存庫。 這些儲存庫中的程式碼是用不同的語言(例如 Node.js、Java、Scala、Go)編寫的,具有相同語言的多個執行環境。

建置系統旨在為每個微服務提供完全可自訂的「建置上下文」。 它通常由 Dockerfile 和 shell 命令列表組成。 它們的內容是完全可自訂的,同時,所有這些建構上下文都是按照標準化格式編寫的。 標準化建構上下文允許一個建置系統處理所有微服務。

Tinder 過渡到 Kubernetes
圖 1-1。 透過 Builder 容器標準化建置流程

實現運行時之間的最大一致性 (運行時環境) 開發和測試期間使用相同的建置流程。 我們面臨一個非常有趣的挑戰:我們必須開發一種方法來確保在整個平台上建構環境的一致性。 為了實現這一目標,所有組裝過程都在特殊容器內進行。 平台.

他的容器實現需要先進的 Docker 技術。 Builder 繼承存取私人 Tinder 儲存庫所需的本機使用者 ID 和機密(例如 SSH 金鑰、AWS 憑證等)。 它掛載包含來源的本機目錄以自然地儲存建置工件。 這種方法提高了效能,因為它消除了在 Builder 容器和主機之間複製建置工件的需求。 儲存的建置工件可以重複使用,無需額外配置。

對於某些服務,我們必須建立另一個容器來將編譯環境對應到執行環境(例如,Node.js bcrypt 函式庫在安裝過程中產生特定於平台的二進位工件)。 在編譯過程中,不同服務的要求可能會有所不同,最終的 Dockerfile 是動態編譯的。

Kubernetes叢集架構與遷移

叢集規模管理

我們決定使用 kube-aws 用於 Amazon EC2 執行個體上的自動化叢集部署。 一開始,一切都在一個公共節點池中運作。 我們很快意識到需要按大小和實例類型分離工作負載,以更有效地利用資源。 其邏輯是,運行多個已載入的多執行緒 Pod 在效能方面比與大量單執行緒 Pod 共存更具可預測性。

最終我們決定:

  • m5.4x大 — 用於監控(普羅米修斯);
  • c5.4xlarge - 用於 Node.js 工作負載(單執行緒工作負載);
  • c5.2xlarge - 適用於 Java 和 Go(多執行緒工作負載);
  • c5.4xlarge — 用於控制面板(3 個節點)。

遷移

從舊基礎設施遷移到 Kubernetes 的準備步驟之一是將服務之間現有的直接通訊重新導向到新的負載平衡器(彈性負載平衡器(ELB))。 它們是在 Virtual Private Cloud (VPC) 的特定子網路上建立的。 該子網路已連接到 Kubernetes VPC。 這使我們能夠逐步遷移模組,而無需考慮服務依賴關係的具體順序。

這些端點是使用 DNS 記錄的加權集建立的,這些記錄的 CNAME 指向每個新的 ELB。 為了進行切換,我們新增了一個新條目,指向 Kubernetes 服務的新 ELB,權重為 0。然後,我們將條目的生存時間 (TTL) 設為 0。之後,新舊權重分別為:慢慢調整,最終100 %的負載被傳送到新的伺服器。 切換完成後,TTL值恢復到比較合適的水平。

我們擁有的 Java 模組可以處理低 TTL DNS,但 Node 應用程式不能。 一位工程師重寫了部分連接池代碼,並將其包裝在一個管理器中,該管理器每 60 秒更新一次池。 所選的方法效果非常好,並且沒有任何明顯的性能下降。

Уроки

網路結構的局限性

8年2019月XNUMX日凌晨,Tinder平台意外崩潰。 為了回應當天早上早些時候平台延遲的無關增加,叢集中的 Pod 和節點數量增加了。 這導致我們所有節點上的 ARP 快取耗盡。

Linux 有 XNUMX 個與 ARP 快取相關的選項:

Tinder 過渡到 Kubernetes
()

GC_thresh3 - 這是一個硬限制。 日誌中出現「鄰居表溢位」條目意味著即使在同步垃圾收集(GC)之後,ARP 快取中也沒有足夠的空間來儲存鄰居條目。 在這種情況下,核心只是完全丟棄該資料包。

我們用 絨布 作為 Kubernetes 中的網路結構。 報文透過VXLAN傳輸。 VXLAN 是建立在 L2 網路之上的 L3 隧道。 該技術採用MAC-in-UDP(MAC位址在用戶資料封包協定)封裝,並允許擴展第2層網段。 實體資料中心網路的傳輸協定是IP+UDP。

Tinder 過渡到 Kubernetes
圖 2-1。 法蘭絨圖()

Tinder 過渡到 Kubernetes
圖 2-2。 VXLAN 套件()

每個 Kubernetes 工作節點從較大的 /24 區塊中分配一個具有 /9 遮罩的虛擬位址空間。 對於每個節點,這是 手段 路由表中的一項、ARP 表中的一項(在 flannel.1 介面上)以及交換錶 (FDB) 中的一項。 它們在第一次啟動工作節點或每次發現新節點時都會新增。

此外,節點-pod(或pod-pod)通訊最終通過介面 eth0 (如上面的法蘭絨圖所示)。 這會在 ARP 表中為每個對應的來源主機和目標主機產生一個附加條目。

在我們的環境中,這種類型的通訊非常常見。 對於 Kubernetes 中的服務對象,會建立一個 ELB,並且 Kubernetes 將每個節點註冊到 ELB。 ELB 對 Pod 一無所知,所選節點可能不是資料包的最終目的地。 重點是,當節點從 ELB 收到封包時,它會考慮規則 iptables的 對於特定服務並隨機選擇另一個節點上的 Pod。

故障發生時,叢集中有 605 個節點。 由於上述原因,這足以克服其重要性 GC_thresh3,這是預設值。 當這種情況發生時,不僅資料包開始被丟棄,而且帶有 /24 遮罩的整個 Flannel 虛擬位址空間也會從 ARP 表中消失。 節點-pod 通訊和 DNS 查詢中斷(DNS 託管在叢集中;請閱讀本文後面的內容以了解詳細資訊)。

要解決這個問題,需要增加價值 GC_thresh1, GC_thresh2 и GC_thresh3 並重新啟動 Flannel 以重新註冊遺失的網路。

意外的 DNS 擴展

在遷移過程中,我們積極使用DNS來管理流量,並逐步將服務從舊基礎設施轉移到Kubernetes。 我們在Route53中為關聯的RecordSet設定了相對較低的TTL值。 當舊基礎架構在 EC2 執行個體上執行時,我們的解析器配置指向 Amazon DNS。 我們認為這是理所當然的,低 TTL 對我們的服務和 Amazon 服務(例如 DynamoDB)的影響基本上沒有被注意到。

當我們將服務遷移到 Kubernetes 時,我們發現 DNS 每秒處理 250 萬個請求。 結果,應用程式開始遇到持續且嚴重的 DNS 查詢逾時問題​​。 儘管付出了令人難以置信的努力來優化 DNS 提供者並將其切換為 CoreDNS(在峰值負載下達到了在 1000 個核心上運行的 120 個 Pod),但這種情況還是發生了。

在研究其他可能的原因和解決方案時,我們發現 一篇文章,描述影響資料包過濾框架的競爭條件 網絡過濾器 在Linux中。 我們觀察到的超時以及不斷增加的計數器 插入失敗 Flannel 介面中的內容與文章的研究結果一致。

問題發生在來源和目標網路位址轉換(SNAT 和 DNAT)以及隨後進入表格的階段 跟踪。 內部討論和社群建議的解決方法之一是將 DNS 移至工作節點本身。 在這種情況下:

  • 不需要 SNAT,因為流量保留在節點內部。 不需要透過介面路由 eth0.
  • 不需要 DNAT,因為目標 IP 是節點本地的,而不是根據規則隨機選擇的 pod iptables的.

我們決定堅持這種方法。 CoreDNS 在 Kubernetes 中部署為 DaemonSet,我們在 配置文件 每個 pod 通過設定一個標誌 --叢集 DNS 命令 庫貝萊 。 事實證明,該解決方案對於 DNS 逾時非常有效。

然而,我們仍然看到資料包丟失和計數器增加 插入失敗 在法蘭絨界面中。 在實施解決方法後,這種情況仍在繼續,因為我們能夠僅消除 DNS 流量的 SNAT 和/或 DNAT。 為其他類型的流量保留了競爭條件。 幸運的是,我們的大多數資料包都是 TCP,如果出現問題,它們只需重新傳輸即可。 我們仍在努力尋找適合所有類型流量的解決方案。

使用 Envoy 實現更好的負載平衡

當我們將後端服務遷移到 Kubernetes 時,我們開始遇到 Pod 之間負載不平衡的問題。 我們發現 HTTP Keepalive 導致 ELB 連線在每個部署的第一個就緒 Pod 上掛起。 因此,大部分流量透過一小部分可用 Pod。 我們測試的第一個解決方案是將新部署上的 MaxSurge 設定為 100%,以應對最壞的情況。 事實證明,對於更大規模的部署來說,效果是微不足道的,而且沒有希望。

我們使用的另一個解決方案是人為地增加關鍵服務的資源請求。 在這種情況下,與其他重型吊艙相比,放置在附近的吊艙將有更多的操作空間。 從長遠來看,這也是行不通的,因為這會浪費資源。 此外,我們的 Node 應用程式是單執行緒的,因此只能使用一個核心。 唯一真正的解決方案是使用更好的負載平衡。

我們很早就想充分欣賞 使者。 目前的情況允許我們以非常有限的方式部署它並立即獲得結果。 Envoy 是一款高效能、開源、第 XNUMX 層代理,專為大型 SOA 應用程式設計。 它可以實現先進的負載平衡技術,包括自動重試、斷路器和全域速率限制。 (筆記。 翻譯。:您可以閱讀更多相關內容 這篇文章 關於 Istio,它基於 Envoy。)

我們提出了以下配置:為每個 pod 提供一個 Envoy sidecar 和一條路由,並透過連接埠將叢集本地連接到容器。 為了最大限度地減少潛在的級聯並保持較小的命中半徑,我們使用了一組 Envoy 前端代理 Pod,每個服務的每個可用區 (AZ) 一個。 他們依賴我們的工程師編寫的簡單服務發現引擎,該引擎只是返回給定服務的每個可用區域中的 Pod 清單。

然後,服務前端特使將這種服務發現機制與一個上游叢集和路由結合使用。 我們設置了足夠的超時,增加了所有斷路器設置,並添加了最小重試配置,以幫助解決單一故障並確保順利部署。 我們在每個服務前端 Envoy 前面放置了一個 TCP ELB。 即使我們主代理層的 keepalive 被困在某些 Envoy Pod 上,它們仍然能夠更好地處理負載,並配置為透過後端的 less_request 進行平衡。

對於部署,我們在應用程式 pod 和 sidecar pod 上使用了 preStop 掛鉤。 此鉤子在檢查位於 sidecar 容器上的管理端點的狀態時觸發了錯誤,並進入休眠狀態一段時間以允許終止活動連線。

我們能夠如此迅速地採取行動的原因之一是我們能夠輕鬆地將詳細指標整合到典型的 Prometheus 安裝中。 這使我們能夠準確地看到在調整配置參數和重新分配流量時發生的情況。

結果立竿見影、顯而易見。 我們從最不平衡的服務開始,目前它運行在叢集中 12 個最重要的服務之前。 今年,我們計劃過渡到具有更先進的服務發現、熔斷、異常檢測、速率限制和追蹤的完整服務網格。

Tinder 過渡到 Kubernetes
圖 3-1。 過渡到 Envoy 期間一項服務的 CPU 融合

Tinder 過渡到 Kubernetes

Tinder 過渡到 Kubernetes

最後結果

透過這些經驗和額外的研究,我們建立了一支強大的基礎設施團隊,在設計、部署和營運大型 Kubernetes 叢集方面擁有強大的技能。 所有 Tinder 工程師現在都具備打包容器並將應用程式部署到 Kubernetes 的知識和經驗。

當舊基礎設施需要額外容量時,我們必須等待幾分鐘才能啟動新的 EC2 執行個體。 現在,容器開始運行並在幾秒鐘(而不是幾分鐘)內開始處理流量。 在單一 EC2 執行個體上調度多個容器還可以提高水平集中度。 因此,我們預計 2019 年 EC2 成本將比去年大幅下降。

遷移花了近兩年的時間,但我們在 2019 年 200 月完成了。 目前,Tinder 平台僅在 Kubernetes 叢集上運行,該叢集由 1000 個服務、15 個節點、000 個 Pod 和 48 個正在運行的容器組成。 基礎設施不再是營運團隊的唯一領域。 我們所有的工程師都共同承擔這項責任,並僅使用程式碼來控制建置和部署應用程式的過程。

譯者PS

另請閱讀我們部落格上的一系列文章:

來源: www.habr.com

添加評論