本文已發布超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

Borg:Kubernetes 的前身

Google 在生產環境中運行容器化工作負載已超過十年。無論是 Web 前端和有狀態伺服器等服務作業、Bigtable 和 Spanner 等基礎架構系統,還是 MapReduce 和 Millwheel 等批次框架,Google 幾乎所有內容都以容器形式運行。今天,我們揭開了 Borg 的面紗,這是 Google 傳聞已久的內部容器導向叢集管理系統,並在 Eurosys 學術電腦系統會議上發布了詳細資訊。您可以在這裡找到論文。

Kubernetes 的血統可以直接追溯到 Borg。許多在 Google 從事 Kubernetes 開發的工程師以前都是 Borg 專案的開發人員。我們已將 Borg 中最好的想法融入 Kubernetes,並嘗試解決使用者多年來在使用 Borg 時發現的一些痛點。

為了讓您了解,以下是四個來自我們 Borg 經驗的 Kubernetes 功能

  1. Pods。Pod 是 Kubernetes 中的調度單位。它是一個資源封包,其中運行一個或多個容器。屬於同一個 Pod 的容器保證會一起調度到同一部機器上,並且可以透過本機卷共享狀態。

Borg 有一個類似的抽象概念,稱為 alloc(「資源分配」的縮寫)。Borg 中 alloc 的常見用途包括運行一個 Web 伺服器,該伺服器在輕量級日誌收集程序的旁邊產生日誌,該程序將日誌傳送到叢集檔案系統(與 fluentd 或 logstash 類似);運行一個 Web 伺服器,該伺服器從磁碟目錄提供資料,該目錄由一個從叢集檔案系統讀取資料並為 Web 伺服器準備/暫存資料的程序填充(與內容管理系統類似);以及在儲存分片的旁邊運行使用者定義的處理函數。Pod 不僅支援這些用例,它們還提供了一個類似於在單一 VM 中運行多個進程的環境 - Kubernetes 使用者可以在一個 Pod 中部署多個共置、協作的進程,而無需放棄每個容器部署模型一個應用程式的簡單性。

  1. 服務。雖然 Borg 的主要作用是管理任務和機器的生命週期,但在 Borg 上運行的應用程式受益於許多其他叢集服務,包括命名和負載平衡。Kubernetes 使用服務抽象支援命名和負載平衡:服務具有名稱,並映射到由標籤選擇器定義的動態 Pod 集合(請參閱下一節)。叢集中的任何容器都可以使用服務名稱連接到服務。在底層,Kubernetes 會自動在與標籤選擇器匹配的 Pod 之間對服務的連線進行負載平衡,並追蹤 Pod 由於故障而在一段時間內重新調度時的運行位置。

  2. 標籤。Borg 中的容器通常是相同或幾乎相同的容器集合中的一個副本,這些容器對應於網際網路服務的一個層級(例如 Google 地圖的前端)或批次作業的工作人員(例如 MapReduce)。該集合稱為 Job,每個副本稱為 Task。雖然 Job 是一個非常有用的抽象概念,但它可能具有局限性。例如,使用者通常希望將他們的整個服務(由許多 Job 組成)作為單一實體進行管理,或統一管理其服務的幾個相關實例,例如單獨的 Canary 和穩定發行軌道。在另一個極端,使用者經常希望推理和控制 Job 內的任務子集 - 最常見的例子是在滾動更新期間,當 Job 的不同子集需要具有不同的配置時。

Kubernetes 透過使用標籤組織 Pod,支援比 Borg 更靈活的集合,標籤是用戶附加到 Pod(實際上是系統中任何物件)的任意鍵/值對。使用者可以透過在其 Pod 上使用「job:<jobname>」標籤來建立等效於 Borg Job 的群組,但他們也可以使用其他標籤來標記服務名稱、服務實例(生產、預備、測試),以及一般而言,Pod 的任何子集。標籤查詢(稱為「標籤選擇器」)用於選擇應將操作應用於哪個 Pod 集合。標籤和複製控制器結合在一起,允許非常靈活的更新語義,以及跨越等效於 Borg Job 的操作。

  1. 每個 Pod 一個 IP 位址。在 Borg 中,機器上的所有任務都使用該主機的 IP 位址,因此共享主機的埠空間。雖然這意味著 Borg 可以使用原始網路,但它給基礎架構和應用程式開發人員帶來了許多負擔:Borg 必須將埠作為資源進行調度;任務必須預先宣告它們需要多少個埠,並將要使用的埠作為啟動引數;Borglet(節點代理程式)必須強制執行埠隔離;並且命名和 RPC 系統必須處理埠以及 IP 位址。

由於 flannel 等軟體定義的覆蓋網路或內建於 公有雲的覆蓋網路的出現,Kubernetes 能夠為每個 Pod 和服務提供自己的 IP 位址。這消除了管理埠的基礎架構複雜性,並允許開發人員選擇他們想要的任何埠,而不是要求他們的軟體適應基礎架構選擇的埠。後一點對於簡化在 Kubernetes 上運行現成的開源應用程式至關重要 - Pod 可以像 VM 或實體主機一樣對待,可以存取完整的埠空間,而無需注意它們可能與其他 Pod 共享同一部實體機器。

隨著基於容器的微服務架構越來越受歡迎,Google 從內部運行此類系統中學到的經驗教訓已引起外部 DevOps 社群越來越大的興趣。透過揭示我們的叢集管理器 Borg 的一些內部工作原理,並將我們的下一代叢集管理器建構為開源專案 (Kubernetes) 和公開可用的託管服務 (Google Container Engine),我們希望這些經驗教訓能夠使 Google 以外的更廣泛社群受益,並推進容器調度和叢集管理的最先進技術。