本頁面說明建構可擴充 GKE 叢集的一般最佳做法。您可以對所有叢集和工作負載套用這些建議,以達到最佳效能。如果您打算大幅擴充叢集,就更需要遵循這些建議。最佳做法適用於負責佈建基礎架構的管理員,以及準備 Kubernetes 元件和工作負載的開發人員。
如要查看所有 GKE 最佳做法的整合總覽,請參閱「GKE 最佳做法」。什麼是擴充性?
在 Kubernetes 叢集中,可擴充性是指叢集在成長時,仍能維持在服務水準目標 (SLO) 範圍內的能力。Kubernetes 也有一套專屬的 SLO,
Kubernetes 是一個複雜的系統,其擴充能力取決於多種因素。其中一些因素包括節點集區中的節點類型與數量、節點集區的類型與數量、可用的 Pod 數量、將資源分配給 Pod 的方式,以及 Service 或 Service 後端的數量。
供應情形最佳做法
選擇地區或區域控制層
由於架構上的差異,地區叢集更適合高可用性。區域叢集在一個區域的多個運算可用區中有多個控制層,而可用區叢集在單一運算可用區中只有一個控制層。
如果升級區域叢集,控制層 VM 會在升級期間停機,Kubernetes API 也無法使用,直到升級完成為止。
在區域叢集中,控制層在叢集維護期間 (例如輪替 IP、升級控制層 VM,或調整叢集或節點集區大小) 仍可使用。升級區域叢集時,多個控制層 VM 中至少有一個會在滾動升級期間持續運作,因此 Kubernetes API 仍可使用。同樣地,單一區域服務中斷並不會導致地區控制層中發生任何停機狀況。
不過,高可用性區域叢集會帶來一些取捨:
叢集設定變更需要較長時間,因為變更必須在區域叢集的所有控制層中傳播,而非在可用區叢集的單一控制層中傳播。
您可能無法像可用區叢集一樣,頻繁地建立或升級區域叢集。如果其中一個可用區無法建立 VM (可能是容量不足或其他暫時性問題),就無法建立或升級叢集。
由於必須做出這些取捨,區域與地區叢集會有不同的用途:
- 如果可用性不是主要考量,可以使用可用區叢集快速建立或升級叢集。
- 如果可用性比靈活性更重要,請使用區域叢集。
建立叢集時,請謹慎選取叢集類型,因為建立叢集後即無法變更叢集類型。您必須建立新叢集,然後將流量遷移至該叢集。您可以在叢集之間遷移實際工作環境流量,但要大規模遷移就比較困難。
選擇多可用區或單一可用區節點集區
為了實現高可用性的目標,Kubernetes 控制層及其節點需要分佈到不同的區域。GKE 提供兩種節點集區:單一可用區和多可用區。
如要部署高可用性應用程式,請使用多可用區節點集區,將節點平均分配至區域內的多個可用區,藉此將工作負載分配至區域內的多個運算可用區。
如果所有節點都位於同一個可用區,當該可用區無法連線時,您就無法排定 Pod。使用多可用區節點集區時,需要考量以下幾點:
GPU 僅適用於特定可用區。可能無法在該區域的所有可用區取得。
單一區域內不同可用區之間的來回延遲時間,可能高於單一可用區內資源之間的延遲時間。對大多數工作負載而言,差異應該微不足道。
如要瞭解相同區域內不同可用區之間的輸出流量價格,請參閱 Compute Engine 定價頁面。
選擇 AI 可用區
AI 可用區是專門用於 AI/機器學習訓練和推論工作負載的可用區。這些可用區提供大量機器學習加速器容量。詳情請參閱「AI 可用區」一文。
在本文件和 GKE 說明文件中,「標準可用區」或「可用區」是指 Google Cloud 區域內的非 AI 可用區。
在 GKE 中使用 AI 可用區前,請先考量下列特性:
- AI 可用區與標準可用區在實體上是分開的,可提供額外的儲存空間和電力。這種區隔可能會導致延遲時間增加,但 AI/機器學習工作負載通常可以容忍這種情況。
- AI 可用區的後置字串會加上
ai標記。舉例來說,us-central1區域中的 AI 可用區名稱為us-central1-ai1a。 - 目前僅支援 TPU VM。
- 叢集的控制層會在與 AI 可用區相同的區域內,於一或多個標準可用區中執行。
如要在 AI 區域中執行未附加 TPU 的 VM,必須符合下列條件:
- 您已在同一可用區中執行其他使用 TPU VM 的工作負載。
- 非 TPU VM 可以是 Spot VM、與預留項目綁定,或是節點集區的一部分,且具有特定的加速器與一般用途 VM 比例。
在同一區域中,AI 可用區與具有相同後置字元的標準可用區共用元件,例如網路連線和軟體推出。如要處理高可用性工作負載,建議使用不同區域。舉例來說,請避免同時使用
us-central1-ai1a和us-central1-a來確保高可用性。
根據預設,GKE 不會在 AI 區域部署工作負載。如要使用 AI 區域,請務必設定下列其中一個選項:
- (建議) ComputeClasses:將最高優先順序設為在 AI 區域中要求隨選 TPU。ComputeClass 可協助您定義工作負載的硬體設定優先順序清單。如需範例,請參閱「關於 ComputeClasses」。
- 自動佈建節點:在 Pod 規格中使用
nodeSelector或nodeAffinity,指示自動佈建節點功能在 AI 可用區中建立節點集區。如果工作負載未明確指定 AI 可用區,節點自動佈建功能只會考慮標準可用區或--autoprovisioning-locations中的可用區,建立新的節點集區。這項設定可確保未執行 AI/機器學習模型的工作負載會留在標準可用區,除非您明確設定其他可用區。如需使用nodeSelector的資訊清單範例,請參閱「設定自動建立節點的預設可用區」。 - GKE Standard:如果您直接管理節點集區,請在建立節點集區時,使用
--node-locations旗標中的 AI 可用區。如需範例,請參閱「在 GKE Standard 部署 TPU 工作負載」。
大規模實行最佳做法
基礎架構
Kubernetes 工作負載需要網路、運算和儲存空間。您需要提供足夠的 CPU 與記憶體才能執行 Pod。不過,目前已有越來越多的基礎架構可能會影響 GKE 叢集的效能與擴充性。
叢集網路
使用 VPC 原生叢集是預設的網路設定,也是設定新 GKE 叢集的建議選項。VPC 原生叢集可處理較大的工作負載、容納更多節點,並提供其他優勢。
在這個模式中,虛擬私有雲網路會為所有 Pod IP 位址提供次要範圍。然後,系統會為每個節點指派次要範圍的切片,做為節點本身的 Pod IP 位址。這可讓虛擬私有雲網路原生瞭解如何將流量轉送至 Pod,而不需依賴自訂路徑。單一虛擬私有雲網路最多可有 15,000 個 VM。
另一種做法是使用「使用路由的叢集」,但這種做法已淘汰,最多只能支援 1,500 個節點。使用路由的叢集不適合大型工作負載。這會耗用虛擬私有雲路由配額,且缺少虛擬私有雲原生網路的其他優點。做法是在每個新節點的虛擬私有雲網路中,將新的自訂路徑新增至路由表。
叢集大小
GKE Standard 叢集最多可擴充至 65,000 個節點。視目標節點數量而定,基礎架構有特定需求,您可能需要與 Cloud Customer Care 聯絡。詳情請參閱「叢集大小限制和規定」。
叢集負載平衡
GKE Ingress 和 Cloud Load Balancing 會設定及部署負載平衡器,將 Kubernetes 工作負載公開至叢集外部和公開網際網路。GKE Ingress 和 Service 控制器會代表 GKE 工作負載部署物件,例如轉送規則、網址對應、後端服務、網路端點群組等。每項資源都有固有的配額和限制,這些限制也適用於 GKE。如果任何 Cloud Load Balancing 資源達到配額上限,系統將無法正確部署特定 Ingress 或 Service,且資源事件中會顯示錯誤。
下表說明使用 GKE Ingress 和服務時的擴充限制:
| 負載平衡器 | 每個叢集的節點數量上限 |
|---|---|
| 內部直通式網路負載平衡器 |
|
| 區域性外部直通式網路負載平衡器 | 每個可用區 1,000 個節點 |
| 外部應用程式負載平衡器 |
|
| 內部應用程式負載平衡器 | 沒有節點限制 |
如需進一步擴充,請洽詢 Google Cloud 銷售團隊,提高這項限制。
DNS
GKE 的服務探索功能是透過 kube-dns 提供,這項集中式資源可為叢集內執行的 Pod 提供 DNS 解析。如果叢集非常大,或工作負載的要求負載很高,這可能會成為瓶頸。GKE 會根據叢集大小自動調整 kube-dns 的規模,以增加容量。如果這個容量仍不足,GKE 會在每個節點上提供 DNS 查詢的本機分散式解析功能,也就是 NodeLocal DNSCache。這會在每個 GKE 節點上提供本機 DNS 快取,在本機回答查詢、分散負載,並加快回應速度。
管理 VPC 原生叢集中的 IP 位址
VPC 原生叢集會使用三個 IP 位址範圍:
- 節點子網路的主要範圍:預設為 /20 (4092 個 IP 位址)。
- Pod 子網路的次要範圍:預設為 /14 (262,144 個 IP 位址)。不過,您可以設定 Pod 子網路。
- 服務子網路的次要範圍:預設為 /20 (4096 個位址)。不過,建立這項服務子網路後,您就無法變更這個範圍。
詳情請參閱「VPC 原生叢集的 IP 位址範圍」。
IP 位址限制和建議:
- 節點限制:節點限制取決於每個節點的主要和 Pod IP 位址。節點和 Pod IP 位址範圍內必須有足夠的位址,才能佈建新節點。根據預設,由於 Pod IP 位址限制,您只能建立 1024 個節點。
- 每個節點的 Pod 數量上限:根據預設,每個節點的 Pod 數量上限為 110 個。不過,您可以設定較小的 Pod CIDR,以便有效率地使用每個節點的較少 Pod。
- 擴充超出 RFC 1918 範圍:如果您需要的 IP 位址數量超出 RFC 1918 定義的私人空間,建議使用非 RFC 1918 私人位址或 PUPI,以獲得更多彈性。
- Service 和 Pod 的次要 IP 位址範圍:預設最多可設定 4096 個 Service。不過,您可以選擇服務子網路範圍,設定更多服務。建立次要範圍後,您就無法修改。建立叢集時,請務必選擇足夠大的範圍,以因應預期的成長。不過,您之後可以使用不連續多 Pod CIDR,為 Pod 新增更多 IP 位址。
如要瞭解詳情,請參考下列資源:
設定節點以提高效能
GKE 節點是一般的 Google Cloud 虛擬機器。部分參數 (例如核心數量或磁碟大小) 可能會影響 GKE 叢集的效能。
縮短 Pod 初始化時間
您可以透過映像檔串流功能,在工作負載要求時,從符合資格的容器映像檔串流資料,進而縮短初始化時間。
輸出流量
在 Google Cloud中,執行個體的網路容量取決於機型和分配的核心數量。傳出頻寬上限為 1 到 32 Gbps,而預設 e2-medium-2 機器的傳出頻寬上限為 2 Gbps。如要進一步瞭解頻寬限制,請參閱「共用核心機型」。
IOPS 與磁碟總處理量
在 Google Cloud中,永久磁碟的大小會決定磁碟的 IOPS 和處理量。GKE 通常會將永久磁碟做為開機磁碟,並備份 Kubernetes 的 PersistentVolume。增加磁碟大小可提高 IOPS 和處理量,但會受到特定限制。
每項 Persistent Disk 寫入作業都會計入虛擬機器執行個體的累計網路輸出上限。因此,磁碟 (尤其是 SSD) 的 IOPS 效能除了取決於磁碟大小,也與執行個體中的 vCPU 數量有關。由於寫入總處理量的網路輸出限制,核心較少的 VM 寫入 IOPS 限制較低。
如果虛擬機器執行個體的 CPU 不足,應用程式就無法接近 IOPS 限制。一般來說,預期流量每增加 2000 到 2500 IOPS,您就應該增加一個可用的 CPU。
如果工作負載需要高容量或大量磁碟,請務必考量單一 VM 可連接的永久磁碟數量限制。一般 VM 的限制為 128 個磁碟,總大小為 64 TB,而共用核心 VM 的限制為 16 個 PD,總大小為 3 TB。 Google Cloud 會強制執行這項限制,而非 Kubernetes。
監控控制層指標
使用可用的控制層指標設定監控資訊主頁。您可以使用控制層指標觀察叢集健康狀態、叢集設定變更結果 (例如部署其他工作負載或第三方元件),或是在疑難排解問題時使用。
Kubernetes API 的延遲時間是最重要的監控指標之一。延遲時間增加表示系統超載。請注意,傳輸大量資料的 LIST 呼叫預期會比小型要求延遲時間長得多。
第三方許可 Webhook 回應速度緩慢,也可能導致 Kubernetes API 延遲時間增加。您可以使用指標評估 Webhook 的延遲時間,偵測這類常見問題。
單一資源呼叫 (例如 GET、POST 或 PATCH) 的建議上限為一秒。建議命名空間範圍和叢集範圍 LIST 呼叫的上限為 30 秒。上限期望值是由開放原始碼 Kubernetes 社群定義的 SLO 所設定。詳情請參閱「API 呼叫延遲 SLI/SLO 詳細資料」。
Kubernetes 開發人員的最佳做法
使用清單和監控模式,而非定期列出
身為 Kubernetes 開發人員,您可能需要建立符合下列需求的元件:
- 您的元件需要定期擷取某些 Kubernetes 物件的清單。
- 您的元件需要在多個執行個體中執行 (如果是 DaemonSet,甚至需要在每個節點上執行)。
即使定期擷取的物件狀態未變更,這類元件仍可能在 kube-apiserver 上產生負載高峰。
最簡單的方法是使用定期 LIST 呼叫。不過,這種做法對呼叫端和伺服器來說效率不彰且成本高昂,因為每次都必須將所有物件載入記憶體、序列化並傳輸。過度使用 LIST 要求可能會導致控制層超載,或對這類要求產生大量節流。
您可以在 LIST 呼叫中設定 resourceVersion=0 參數,改善元件。這可讓 kube-apiserver 使用記憶體內物件快取,並減少 Kubernetes API 伺服器與 etcd API 互動的頻率,進而減少任何相關處理作業。
強烈建議您避免重複發出 LIST 呼叫,並改用清單和監看模式。先列出物件,然後使用 Watch API 取得狀態的增量變更。與定期 LIST 呼叫相比,這種做法可縮短處理時間,並盡量減少流量。如果物件未變更,就不會產生額外負載。
如果您使用 Go 語言,請查看 SharedInformer 和 SharedInformerFactory,瞭解實作這個模式的 Go 套件。
限制監控和清單產生的不必要流量
Kubernetes 會在內部使用監控,傳送物件更新通知。即使手錶所需的資源遠少於定期 LIST 呼叫,在大型叢集中處理手錶仍會佔用大量叢集資源,進而影響叢集效能。如果建立的監看項目會從多個位置觀察經常變更的物件,就會產生最大的負面影響。舉例來說,您可以觀察在所有節點上執行的元件,取得所有 Pod 的資料。如果您在叢集上安裝第三方程式碼或擴充功能,這些程式碼或擴充功能可能會在幕後建立這類監控。
建議採行下列最佳做法:
- 減少手錶和 LIST 呼叫產生的不必要處理作業和流量。
- 請避免建立監控項,從多個位置 (例如 DaemonSet) 觀察經常變更的物件。
- (強烈建議) 建立中央控制器,監控及處理單一節點上的必要資料。
- 僅監控部分物件,例如每個節點上的 kubelet 只會監控排定在相同節點上的 Pod。
- 避免部署第三方元件或擴充功能,以免因大量監控或 LIST 呼叫而影響叢集效能。
使用 DaemonSet 進行滾動式更新,避免流量突然增加
在叢集中建立 DaemonSet 時,系統會立即在每個節點中排定新的 Pod。如果所有新 Pod 都連線至相同的網路端點,這些要求就會同時發生,導致目標主機負載過高。為避免發生這種情況,請使用滾動式更新設定 DaemonSet,並限制 maxSurge Pod。
限制 Kubernetes 物件資訊清單大小
如果您需要快速執行作業 (例如調整大小或更新大型工作負載),且這些作業需要高 Pod 處理量,請務必將 Pod 資訊清單大小降至最低,最好小於 10 KiB。
Kubernetes 會將資源資訊清單儲存在鍵/值儲存庫的資料庫中。每次擷取資源時,系統都會傳送整個資訊清單,包括使用清單和觀看模式時。
資訊清單大小有下列限制:
- 每個物件資訊清單的大小上限:約 1.5 MiB。
- 叢集中所有 Kubernetes API 物件的總配額:預先設定的配額大小為 6 GiB。包括變更記錄,其中列出叢集記錄最近 150 秒內所有物件的所有更新。
- 高流量期間的控制層效能:資訊清單越大,API 伺服器的負載就越高。
如果是單一且很少處理的物件,只要資訊清單小於 1.5 MiB,通常就不會有大小問題。不過,如果經常處理大量物件 (例如超大型工作負載中的 Pod),且資訊清單大小超過 10 KiB,可能會導致 API 呼叫延遲時間增加,整體效能也會降低。尤其是清單和手錶,可能會受到大型資訊清單大小的顯著影響。您也可能遇到叢集狀態資料庫的配額問題,因為在 API 伺服器流量較高的期間,過去 150 秒內修訂版本的數量可能會快速累積。
如要縮減 Pod 的資訊清單大小,可以利用 Kubernetes ConfigMap 儲存部分設定,特別是叢集中多個 Pod 共用的部分。舉例來說,工作負載中的所有 Pod 通常會共用環境變數。
請注意,如果 ConfigMap 物件的數量、大小和處理頻率與 Pod 相同,也可能發生類似問題。如果擷取部分設定可減少整體流量,這項功能就非常實用。
停用預設服務帳戶的自動掛接功能
如果 Pod 中執行的邏輯不需要存取 Kubernetes API,請停用預設的服務帳戶自動掛接功能,以免建立相關 Secret 和監控。
建立 Pod 時,如果沒有指定服務帳戶,Kubernetes 會自動執行下列動作:
- 將預設服務帳戶指派給 Pod。
- 將服務帳戶憑證掛接為 Pod 的 Secret。
- 針對每個已掛接的 Secret,kubelet 會建立監控機制,觀察每個節點上該 Secret 的變更。
在大型叢集中,這些動作代表數千個不必要的監控作業,可能會對 kube-apiserver 造成重大負載。
使用通訊協定緩衝區而非 JSON 進行 API 要求
實作高度可擴充的元件時,請使用通訊協定緩衝區,如「Kubernetes API 概念」所述。
Kubernetes REST API 支援 JSON 和通訊協定緩衝區,做為物件的序列化格式。系統預設使用 JSON,但通訊協定緩衝區更有效率,因為這類緩衝區需要較少的 CPU 密集處理作業,且透過網路傳送的資料較少,因此可大規模提升效能。處理 JSON 相關的額外負荷可能會導致列出大型資料時發生逾時。