有效的 IP 位址管理對於 Google Kubernetes Engine (GKE) 虛擬私有雲原生叢集的穩定性和擴充性至關重要。問題可能會導致無法調度資源,或造成工作負載失敗,例如 Pod 無法排程。
本文說明如何排解及修正 GKE VPC 原生叢集中,與 IP 位址分配、網路穩定性和進階網路功能相關的問題。
本文主要適用於管理叢集網路基礎架構的平台管理員和操作員。此外,應用程式開發人員也能瞭解基礎網路限制 (例如 IP 位址空間耗盡) 如何影響工作負載。雖然開發人員可能不會直接設定虛擬私有雲,但瞭解這些常見問題有助於他們與平台管理員和操作人員更有效地協作,更快解決問題。如要進一步瞭解 Google Cloud 內容中提及的常見角色和工作範例,請參閱「常見的 GKE 使用者角色和工作」。
診斷 IP 位址耗盡問題
如果叢集中的 IP 位址用盡,節點就無法擴充,工作負載也會中斷。本節說明如何在 GKE 中使用 IP 位址使用率監控功能,偵測及解決潛在的耗盡問題。
GKE 會使用 網路分析器深入分析和其他 GKE 資料來源的資料,計算 IP 位址使用率。這項監控功能適用於所有 VPC 原生叢集。
如要查看叢集的 IP 位址使用率,請按照下列步驟操作:
在 Google Cloud 控制台中,前往「Kubernetes clusters」(Kubernetes 叢集) 頁面。
按一下要檢查的叢集名稱。這項操作會開啟叢集的「Details」(詳細資料) 頁面。
使用下列任一方法前往「IP utilization」(IP 使用率) 頁面:
選取「Observability」(觀測能力) 分頁標籤,然後在觀測能力導覽選單中,按一下「IP utilization」(IP 使用率)。
在「Networking」(網路) 區段中,找出「Cluster Pod IPv4 range (default)」(叢集 Pod IPv4 範圍 (預設)) 列,然後按一下「View IP utilization」(查看 IP 使用率)。
查看「Status of IP allocation」(IP 分配狀態) 欄。這個資料欄會顯示 Pod IP 位址範圍中已分配 IP 位址的百分比。無論個別 IP 位址是否指派給 Pod,GKE 都會將節點指派 CIDR 範圍內的所有 IP 位址視為已分配。這表示百分比反映的是節點的整個 Pod 範圍,而不只是使用中的 IP 位址。如有叢集共用同樣的 IP 位址範圍,使用率百分比會顯示合併總量。
如要查看 IP 位址用量的詳細資料,包括 CIDR 範圍、子網路資訊和建議,請按一下「Show details」(顯示詳細資料)。
如果 IP 位址使用率偏高 (接近 100%),請考慮採用下列解決方案,避免 IP 位址用盡:
- 使用不連續的多 Pod CIDR,新增更多 Pod IPv4 位址範圍。這項功能可讓您為 Pod 新增更多 IPv4 位址,不必重新建立叢集或設定新的子網路。
- 在叢集內加入更多子網路及其他 IPv4 位址範圍。這項功能可讓新的節點集區使用新加入子網路的 IP 位址。
- 建立 Pod 數量上限值較低的新叢集。這種做法會為每個節點保留較少的 IP 位址,有助於管理叢集網路範圍內的整體 IP 位址用量。詳情請參閱「設定個別節點的 Pod 數量上限」。
- 如果 IP 位址範圍或 RFC 1918 位址空間不足,請考慮使用非 RFC 1918 範圍 (包括 E 類位址空間)。
瞭解 GKE Pod CIDR 分配計算方式
常見的混淆來源是 GKE 不會依需求從中央集區動態分配個別 Pod IP 位址。相反地,當新節點加入叢集時,GKE 會從子網路的次要 Pod 範圍中劃分出連續的 CIDR 區塊,並將其專門指派給該節點。
為避免在快速推出 Pod 時發生 IP 回收衝突,GKE 會分配每個節點的區塊大小,其大小等於可容納至少 2 × 每個節點的 Pod 數量上限位址的最小 2 的冪區塊:
Per-node Pod CIDR block size (addresses) = 2^(ceil(log2(2 * max_pods_per_node)))
- 預設設定 (
--max-pods-per-node=110):至少需要 2 × 110 = 220 個位址。最接近的 2 的冪是 256 個位址,這會為每個節點指派/24區塊 (256 個 IP 位址)。 - 對叢集節點容量的影響:無論節點上執行的 Pod 數量為何,每個節點都會耗用
/24區塊 (256 個 Pod IP 位址),因此次要 Pod 範圍支援的節點數量上限,直接取決於您的--max-pods-per-node設定:
| 每個節點的 Pod 數上限 | 分配的各節點區塊 | 每個 /19 Pod 範圍的節點數量上限 (8,192 個 IP 位址) |
每個 /16 Pod 範圍的節點數量上限 (65,536 個 IP 位址) |
|---|---|---|---|
| 110 (預設) | /24 (256 個 IP 位址) |
32 個節點 | 256 個節點 |
| 64 | /25 (128 個 IP 位址) |
64 個節點 | 512 個節點 |
| 32 (Autopilot 預設值) | /26 (64 個 IP 位址) |
128 個節點 | 1,024 個節點 |
| 16 | /27 (32 個 IP 位址) |
256 個節點 | 2,048 個節點 |
| 8 | /28 (16 個 IP 位址) |
512 個節點 | 4,096 個節點 |
排解特定網路問題
下列各節提供解決 VPC 原生叢集相關問題的指引。您也可以查看 GKE IP 位址使用率洞察。
預設網路資源尚未準備就緒
- 問題
您會收到類似下列內容的錯誤訊息:
projects/[PROJECT_NAME]/regions/XXX/subnetworks/default- 可能原因
同一個子網路上有平行作業。例如,正在建立另一個 VPC 原生叢集,或正在子網路上新增或刪除次要範圍。
- 解析度
重試指令。
IPCidrRange 值無效
- 問題
您會收到類似下列內容的錯誤訊息:
resource.secondaryIpRanges[1].ipCidrRange': 'XXX'. Invalid IPCidrRange: XXX conflicts with existing subnetwork 'default' in region 'XXX'- 可能原因
同時有另一個 VPC 原生叢集正在建立,並嘗試在同一個虛擬私有雲網路中分配相同的範圍。
相同次要範圍已新增至相同虛擬私有雲網路中的子網路。
- 解析度
如果您未指定次要範圍,當系統在建立叢集時傳回這個錯誤,請重試叢集建立指令。
Pod 的可用 IP 位址空間不足
- 問題
叢集長時間卡在佈建狀態。
建立叢集時,傳回代管執行個體群組 (MIG) 錯誤。
將一或多個節點新增至叢集時,系統會顯示下列錯誤:
[IP_SPACE_EXHAUSTED] Instance 'INSTANCE_NAME' creation failed: IP space of 'projects/PROJECT_ID/regions/REGION/subnetworks/[SUBNET_NAME]-[SECONDARY_RANGE_NAME]-[HASH_8BYTES]' is exhausted. The secondary range name is in the format of 'gke-[CLUSTER_NAME]-[HASH_8BYTES]'.- 可能原因
節點 IP 位址耗盡:指派給叢集的子網路主要 IP 位址範圍已無可用 IP 位址。這通常發生在擴充節點集區或建立大型叢集時。
縮減節點集區中的初始節點數量偏高:GKE 會根據您建立節點集區時要求的初始容量,為 Pod 保留 IP 位址。如果您建立的節點集區具有較高的
initial_node_count,然後縮減節點數量,GKE 會繼續根據節點集區的initial_node_count或節點集區中目前的節點數量 (以較大者為準) 保留 IP 位址空間。這種情況可能會導致叢集回報 IP 位址耗盡,即使目前的使用中節點數量偏低也一樣。Pod IP 位址用盡:指派給叢集的 Pod CIDR 範圍已滿。當 Pod 數量超過 Pod CIDR 的容量時,就會發生這種情況,特別是每個節點的 Pod 密度偏高或部署作業規模較大時。
特定子網路命名慣例:錯誤訊息中的子網路命名方式,有助於判斷問題是出在節點 IP 位址範圍 (節點本身取得 IP 位址的位置),還是 Pod IP 位址範圍 (Pod 內容器取得 IP 位址的位置)。
次要範圍用盡 (Autopilot):在 Autopilot 叢集中,指派給 Pod IP 位址的次要範圍因資源調度或 Pod 密度過高而用盡。
- 解決方案
收集叢集的下列資訊:名稱、控制層版本、作業模式、相關聯的虛擬私有雲名稱、子網路名稱和 CIDR。此外,請記下預設和任何額外的叢集 Pod IPv4 範圍 (包括名稱和 CIDR)、是否啟用虛擬私有雲原生流量轉送,以及叢集和節點集區層級 (如適用) 的每個節點 Pod 數量上限設定。請記下所有受影響的節點集區,以及其特定的 IPv4 Pod IP 位址範圍和每個節點的 Pod 數量上限設定 (如果與叢集層級設定不同)。此外,請在節點集區設定中,記錄每個節點的 Pod 數量上限預設和自訂 (如有) 設定。
確認 IP 位址耗盡問題
Network Intelligence Center:在 Network Intelligence Center 中,檢查 GKE 叢集的 Pod IP 位址範圍,確認 IP 位址分配率是否偏高。
如果您在 Network Intelligence Center 觀察到 Pod 範圍內的 IP 位址分配率偏高,代表 Pod IP 位址範圍已用盡。
如果 Pod IP 位址範圍顯示正常的分配率,但 IP 位址仍用盡,則可能是節點 IP 位址範圍已用盡。
稽核記錄:檢查
IP_SPACE_EXHAUSTED項目中的resourceName欄位,並與子網路名稱或次要 Pod IP 位址範圍 名稱進行比較。檢查用盡的 IP 位址範圍是節點 IP 位址範圍,還是 Pod IP 位址範圍。
如要確認用盡的 IP 位址範圍是節點 IP 位址範圍或 Pod IP 位址範圍,請檢查
IP_SPACE_EXHAUSTED記錄項目ipSpaceExhausted部分的resourceName值,是否與受影響 GKE 叢集中使用的 Pod 子網路名稱或次要 IPv4 位址範圍名稱相關。如果
resourceName的值格式為「[Subnet_name]」,表示節點 IP 位址範圍已用盡。如果 resourceName 的值格式為「[Subnet_name]-[Name_of_Secondary_IPv4_range_for_pods]-[HASH_8BYTES]」,表示 Pod IP 位址範圍已用盡。
解決 Pod IP 位址耗盡問題:
- 調整現有 Pod CIDR 的大小:擴大目前的 Pod IP 位址範圍。您可以使用不連續的多 Pod CIDR,將 Pod IP 範圍新增至叢集。
- 建立額外的子網路:將具有專屬 Pod CIDR 的子網路新增至叢集。
減少每個節點的 Pod 數量,釋出 IP 位址:
- 建立新的節點集區,並降低每個節點的 Pod 數量上限。
- 將工作負載遷移至該節點集區,然後刪除先前的節點集區。減少每個節點的 Pod 數量上限,即可在固定的 Pod 次要 IP 位址範圍內支援更多節點。如要進一步瞭解相關計算方式,請參閱「Pod 的子網路次要 IP 位址範圍」和「節點限制範圍」。
解決節點 IP 位址耗盡的問題:
- 檢查 IP 位址規劃:確認節點 IP 位址範圍符合擴充需求。
- 建立新叢集 (如有必要):如果節點 IP 位址範圍嚴重受限,請建立替代叢集,並設定適當的 IP 位址範圍大小。請參閱「虛擬私有雲原生叢集的 IP 範圍」和「IP 範圍規劃」。
其他診斷指令和非干擾性解決方案教戰手冊
如要加快疑難排解速度、解決 IP 位址耗盡問題,並盡可能縮短叢集停機時間,請套用下列診斷和作業指南:
1. 使用 Cloud Logging 和 Recommender 進行指令列二分法
如要透過指令列找出 IP 位址耗盡問題,請執行下列工作:
- 查詢 Cloud Logging,找出明確的 IP 位址耗盡事件:
logquery resource.type="k8s_cluster" logName:"logs/container.googleapis.com" ("IP_SPACE_EXHAUSTED" OR "ran out of IPs" OR "wouldn't fit if a new node is added") - 查詢 Recommender API,取得自動化網路分析器洞察資料 (使用率超過 80%):
sh gcloud recommender insights list \ --insight-type=google.networkanalyzer.container.ipAddressInsight \ --project=PROJECT_ID --location=GLOBAL
2. 即時就地擴充主要子網路 (適用於節點主要 IP 位址用盡的情況)
與次要範圍不同,您可以在 Compute Engine 中即時擴充子網路的主要 IP 主機位址範圍,不必重新建立叢集或中斷工作負載:
gcloud compute networks subnets expand-ip-range SUBNET_NAME \
--region=REGION \
--prefix-length=NEW_PREFIX_LENGTH
舉例來說,將主要子網路從 /24 擴充至 /22,可將主要 VM 主機的 IP 位址容量從 252 個 VM 節點增加至 1,020 個。
3. 藍綠節點集區遷移作業手冊 (適用於 Pod IP 位址用盡的情況)
如果現有節點集區鎖定在小型次要範圍,或 --max-pods-per-node=110 預設設定的大型 IP 位址分配,請將工作負載遷移至具有適當大小 CIDR 的新節點集區:
# Step 1: Add a new secondary IPv4 range to your subnet
gcloud compute networks subnets update SUBNET_NAME \
--region=REGION \
--add-secondary-ranges=NEW_SECONDARY_RANGE_NAME=NEW_CIDR
# Step 2: Register the new Pod range with your GKE cluster
gcloud container clusters update CLUSTER_NAME \
--region=REGION \
--additional-pod-ipv4-ranges=NEW_SECONDARY_RANGE_NAME
# Step 3: Launch a replacement node pool with right-sized --max-pods-per-node
gcloud container node-pools create pool-blue-v2 \
--cluster=CLUSTER_NAME \
--region=REGION \
--max-pods-per-node=32 \
--pod-ipv4-range=NEW_SECONDARY_RANGE_NAME \
--enable-autoscaling --min-nodes=2 --max-nodes=60
# Step 4: Gracefully cordon and drain old nodes
kubectl cordon -l cloud.google.com/gke-nodepool=OLD_POOL_NAME
kubectl drain -l cloud.google.com/gke-nodepool=OLD_POOL_NAME --ignore-daemonsets --delete-emptydir-data --force --grace-period=300
# Step 5: Delete old node pool after workloads migrate
gcloud container node-pools delete OLD_POOL_NAME \
--cluster=CLUSTER_NAME \
--region=REGION
4. 採用 IP 偽裝的 E 類 (240.0.0.0/4) 範圍設計
如果企業網路的 RFC 1918 位址空間不足,請將 E 類 (240.0.0.0/4) IPv4 區塊分配給次要 Pod 範圍 (這些區塊提供超過 2.68 億個位址)。啟用 GKE IP 偽裝代理程式,使用節點的主要 RFC 1918 主機位址,偽裝輸出至地端部署資料庫或其他現有網路端點的流量。
使用 gcpdiag 偵錯 IP 位址耗盡問題
gcpdiag 是開放原始碼工具。並非官方支援的 Google Cloud 產品。您可以使用 gcpdiag 工具,找出並修正 Google Cloud專案問題。詳情請參閱 GitHub 上的 gcpdiag 專案。
- 叢集狀態:如果系統回報 IP 位址用盡,則會檢查叢集狀態。
- 網路分析器:查詢 Stackdriver 記錄中的網路分析器記錄,確認 Pod 或節點 IP 位址是否用盡。
- 叢集類型:檢查叢集類型,並根據叢集類型提供相關建議。
Google Cloud 控制台
- 完成並複製下列指令。
- 開啟 Google Cloud 控制台,然後啟用 Cloud Shell。 開啟 Cloud 控制台
- 貼上複製的指令。
- 執行
gcpdiag指令,下載gcpdiagDocker 映像檔,然後執行診斷檢查。如果適用,請按照輸出內容中的指示修正失敗的檢查。
gcpdiag runbook gke/ip-exhaustion \
--parameter project_id=PROJECT_ID \
--parameter name=CLUSTER_NAME \
--parameter location=ZONE|REGION \
--parameter start_time=yyyy-mm-ddThh:mm:ssZ \
--parameter end_time=yyyy-mm-ddThh:mm:ssZ \Docker
您可以
使用包裝函式執行 gcpdiag,在 Docker 容器中啟動 gcpdiag。必須安裝 Docker 或 Podman。
- 複製下列指令,並在本機工作站執行。
curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag && chmod +x gcpdiag
- 執行
gcpdiag指令。./gcpdiag runbook gke/ip-exhaustion \ --parameter project_id=PROJECT_ID \ --parameter name=CLUSTER_NAME \ --parameter location=ZONE|REGION \ --parameter start_time=yyyy-mm-ddThh:mm:ssZ \ --parameter end_time=yyyy-mm-ddThh:mm:ssZ \
查看這個 Runbook 的可用參數。
更改下列內容:
- PROJECT_ID:: 資源所在專案的 ID
- CLUSTER_NAME:專案中目標 GKE 叢集的名稱。
- LOCATION:叢集所在的可用區或區域。
- start_time:問題開始時間。
- end_time:問題結束時間。如果問題仍未解決,請設定目前時間。
實用旗標:
--universe-domain:託管資源的可信任合作夥伴 Sovereign Cloud 網域 (如適用)--parameter或-p:Runbook 參數
如需所有 gcpdiag 工具旗標的清單和說明,請參閱 gcpdiag 使用說明。
確認是否已停用預設 SNAT
使用下列指令檢查預設 SNAT 的狀態:
gcloud container clusters describe CLUSTER_NAME
將 CLUSTER_NAME 替換為叢集名稱。
輸出結果會與下列內容相似:
networkConfig:
disableDefaultSnat: true
network: ...
必須有 --enable-ip-alias 才能使用 --disable-default-snat
這則錯誤訊息和 must disable default sNAT (--disable-default-snat)
before using public IP address privately in the cluster 表示,您在私人叢集中使用公開 IP 位址,因此建立叢集時,應明確設定 --disable-default-snat 旗標。
如果看到 cannot disable default sNAT ... 等錯誤訊息,表示叢集無法停用預設 SNAT。如要解決這個問題,請檢查叢集設定。
在停用預設 SNAT 的情況下對 Cloud NAT 進行偵錯
如果您使用 --disable-default-snat 旗標建立私人叢集,並設定 Cloud NAT 網路連線能力,但未看到來自 Pod 的網際網路流量,請確認 Cloud NAT 設定中包含 Pod 範圍。
如果 Pod 之間的通訊發生問題,請檢查節點上的 iptables 規則,確認 Pod 範圍未遭到 iptables 規則偽裝。
詳情請參閱 GKE IP 偽裝說明文件。
如果您未為叢集設定 IP 偽裝代理程式,GKE 會自動確保 Pod 對 Pod 通訊不會遭到偽裝。不過,如果設定了 IP 偽裝代理程式,則會覆寫預設的 IP 偽裝規則。確認 IP 偽裝代理程式中已設定其他規則,可忽略偽裝 Pod 範圍。
雙堆疊叢集網路通訊無法正常運作
- 可能原因
- GKE 叢集建立的防火牆規則不含分配的 IPv6 位址。
- 解析度
- 如要驗證防火牆規則,請按照下列步驟操作:
驗證防火牆規則內容:
gcloud compute firewall-rules describe FIREWALL_RULE_NAME將
FIREWALL_RULE_NAME替換為防火牆規則名稱。每個雙堆疊叢集都會建立防火牆規則,允許節點和 Pod 彼此通訊。防火牆規則內容類似如下:
allowed: - IPProtocol: esp - IPProtocol: ah - IPProtocol: sctp - IPProtocol: tcp - IPProtocol: udp - IPProtocol: '58' creationTimestamp: '2021-08-16T22:20:14.747-07:00' description: '' direction: INGRESS disabled: false enableLogging: false id: '7326842601032055265' kind: compute#firewall logConfig: enable: false name: gke-ipv6-4-3d8e9c78-ipv6-all network: https://www.googleapis.com/compute/alpha/projects/my-project/global/networks/alphanet priority: 1000 selfLink: https://www.googleapis.com/compute/alpha/projects/my-project/global/firewalls/gke-ipv6-4-3d8e9c78-ipv6-all selfLinkWithId: https://www.googleapis.com/compute/alpha/projects/my-project/global/firewalls/7326842601032055265 sourceRanges: - 2600:1900:4120:fabf::/64 targetTags: - gke-ipv6-4-3d8e9c78-nodesourceRanges值必須與subnetIpv6CidrBlock相同。targetTags值必須與 GKE 節點上的標記相同。如要修正這個問題,請使用叢集ipAllocationPolicy區塊資訊更新防火牆規則。
後續步驟
如需診斷 Kubernetes DNS 問題的一般資訊,請參閱「偵錯 DNS 解析」。
如果您在說明文件中找不到問題的解決方案,請參閱「取得支援」一文,進一步瞭解如何取得協助,包括下列主題的建議:
- 與 Cloud Customer Care 聯絡,建立客服案件。
- 在 StackOverflow 提問,並使用
google-kubernetes-engine標記搜尋類似問題,向社群尋求支援。您也可以加入#kubernetes-engineSlack 頻道,取得更多社群支援。 - 使用公開 Issue Tracker 提出問題或功能要求。