排解虛擬私有雲叢集中的 IP 位址管理問題

有效管理 IP 位址對於 Google Kubernetes Engine (GKE) VPC 原生叢集的穩定性和可擴充性至關重要。問題可能會導致無法擴充,或造成工作負載失敗,例如 Pod 無法排程。

本文將說明如何排解及修正 GKE 虛擬私有雲原生叢集中的 IP 位址分配、網路穩定性及進階網路功能相關問題。

這項資訊主要適用於管理叢集網路基礎架構的平台管理員和作業人員。此外,應用程式開發人員也能瞭解基礎網路限制 (例如 IP 位址空間耗盡) 如何影響工作負載。雖然開發人員可能不會直接設定 VPC,但瞭解這些常見問題有助於他們與平台管理員和營運人員合作,更快解決問題。如要進一步瞭解內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。 Google Cloud

診斷 IP 位址耗盡問題

如果叢集中的 IP 位址用盡,節點就無法擴充,工作負載也會中斷。本節說明如何在 GKE 中使用 IP 位址使用率監控功能,偵測及解決潛在的耗盡問題。

GKE 會使用 網路分析器洞察和其他 GKE 資料來源的資料,計算 IP 位址使用率。這項監控功能適用於所有 VPC 原生叢集。

如要查看叢集的 IP 位址使用率,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Kubernetes clusters」(Kubernetes 叢集) 頁面。

    前往 Kubernetes 叢集

  2. 按一下要檢查的叢集名稱。這項操作會開啟叢集的「詳細資料」頁面。

  3. 使用下列任一方法前往「IP utilization」(IP 使用率) 頁面:

    • 選取「Observability」(觀測能力) 分頁標籤,然後在觀測導覽選單中,按一下「IP utilization」(IP 使用率)。

    • 在「Networking」(網路) 部分,找出「Cluster Pod IPv4 range (default)」(叢集 Pod IPv4 範圍 (預設)) 列,然後按一下「View IP utilization」(查看 IP 使用率)。

  4. 查看「Status of IP allocation」(IP 分配狀態) 欄。這個資料欄會顯示 Pod IP 位址範圍中已分配的 IP 位址百分比。無論個別 IP 位址是否指派給 Pod,GKE 都會將節點指派的 CIDR 範圍內的所有 IP 位址視為已分配。這表示百分比反映的是節點的整個 Pod 範圍,而不只是使用的 IP 位址。如有叢集共用同樣的 IP 位址範圍,使用率百分比會顯示合併總數。

  5. 如要查看 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 類位址空間)。

排解特定網路問題

以下各節提供指南,協助解決 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 密度偏高,導致分配給 Pod IP 位址的次要範圍耗盡。

解決方案

收集叢集的下列資訊:名稱、控制層版本、作業模式、相關聯的虛擬私有雲名稱、子網路名稱和 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 位址範圍耗盡。

  • 稽核記錄:檢查 resourceName 項目中的 IP_SPACE_EXHAUSTED 欄位,並與子網路名稱或次要 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 位址:

解決節點 IP 位址耗盡問題:

  • 檢查 IP 位址規劃:確認節點 IP 位址範圍符合您的擴充需求。
  • 建立新叢集 (如有必要):如果節點 IP 位址範圍受到嚴重限制,請建立替代叢集,並適當調整 IP 位址範圍大小。請參閱「虛擬私有雲原生叢集的 IP 範圍」和「IP 範圍規劃」。

使用 gcpdiag 偵錯 IP 位址耗盡問題

gcpdiag 是開放原始碼工具。這並非官方支援的 Google Cloud 產品。 您可以使用 gcpdiag 工具找出並修正 Google Cloud專案問題。詳情請參閱 GitHub 上的 gcpdiag 專案。

如要檢查 Autopilot 和 Standard GKE 叢集上的 IP 位址耗盡原因,請考慮下列事項:
  • 叢集狀態:如果系統回報 IP 位址用盡,則會檢查叢集狀態。
  • 網路分析器:查詢網路分析器記錄的 Stackdriver 記錄,確認是否有 Pod 或節點 IP 位址耗盡的情況。
  • 叢集類型:檢查叢集類型,並根據叢集類型提供相關建議。

Google Cloud 控制台

  1. 填寫下列指令,然後複製。
  2. 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 \
  3. 開啟 Google Cloud 控制台並啟用 Cloud Shell。
  4. 開啟 Cloud 控制台
  5. 貼上複製的指令。
  6. 執行 gcpdiag 指令,下載 gcpdiag Docker 映像檔,然後執行診斷檢查。如適用,請按照輸出內容中的指示修正檢查失敗的問題。

Docker

您可以使用啟動 Docker 容器中 gcpdiag 的 wrapper 執行 gcpdiag。必須安裝 Docker 或 Podman。

  1. 在工作站複製並執行下列指令。
    curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag && chmod +x gcpdiag
  2. 執行 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:問題結束時間。如果問題仍未解決,請設定目前時間。

實用旗標:

如需所有 gcpdiag 工具標記的清單和說明,請參閱 gcpdiag 使用說明。

確認預設 SNAT 是否已停用

使用下列指令,檢查預設 SNAT 的狀態:

gcloud container clusters describe CLUSTER_NAME

將 CLUSTER_NAME 替換為叢集名稱。

輸出結果會與下列內容相似:

networkConfig:
  disableDefaultSnat: true
  network: ...

如要使用「--disable-default-snat」,必須先啟用「--enable-ip-alias」

這則錯誤訊息和 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 的網際網路繫結流量,請確認 Pod 範圍已納入 Cloud NAT 設定。

如果 Pod 間的通訊發生問題,請檢查節點上的 iptables 規則,確認 iptables 規則不會偽裝 Pod 範圍。

詳情請參閱 GKE IP 偽裝說明文件。

如果您未為叢集設定 IP 偽裝代理程式,GKE 會自動確保 Pod 之間的通訊不會遭到偽裝。不過,如果設定了 IP 偽裝代理程式,系統就會覆寫預設的 IP 偽裝規則。確認 IP 偽裝代理程式中已設定其他規則,忽略偽裝 Pod 範圍。

雙堆疊叢集網路通訊無法正常運作

可能原因
GKE 叢集建立的防火牆規則不包含已分配的 IPv6 位址。
解析度
如要驗證防火牆規則,請按照下列步驟操作:
  1. 驗證防火牆規則內容:

    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-node
    

    sourceRanges 值必須與 subnetIpv6CidrBlock 相同。 targetTags 值必須與 GKE 節點上的標記相同。如要修正這個問題,請使用叢集 ipAllocationPolicy 區塊資訊更新防火牆規則。

後續步驟