排解叢集 Cloud NAT 封包遺失問題


本頁說明如何解決啟用私人節點的 VPC 原生 Google Kubernetes Engine (GKE) 叢集,發生 Cloud NAT 封包遺失的問題。

在具有私人節點的虛擬私有雲原生 GKE 叢集中,節點 VM 沒有外部 IP 位址。也就是說,網際網路上的用戶端無法連線至節點的 IP 位址。您可以使用 Cloud NAT 分配外部 IP 位址和連接埠,讓具有私人節點的叢集建立公開連線。

如果節點 VM 用盡 Cloud NAT 分配的外部通訊埠和 IP 位址,封包就會遭到捨棄。如要避免這種情況,可以降低輸出封包速率,或是增加可用的 Cloud NAT 來源 IP 位址和通訊埠分配量。下列各節說明如何診斷及排解 GKE 叢集 (含私人節點) 中,因 Cloud NAT 造成的封包遺失問題。

診斷封包遺失情形

以下各節說明如何使用 Cloud Logging 記錄捨棄的封包,以及如何使用 Cloud Monitoring 診斷封包捨棄的原因。

記錄遭捨棄的封包

您可以在 Cloud Logging 中使用下列查詢,記錄遭捨棄的封包:

resource.type="nat_gateway"
resource.labels.region=REGION
resource.labels.gateway_name=GATEWAY_NAME
jsonPayload.allocation_status="DROPPED"

更改下列內容:

  • REGION:叢集所在的區域名稱。
  • GATEWAY_NAME:Cloud NAT 閘道的名稱。

這項指令會傳回 Cloud NAT 閘道捨棄的所有封包清單,但不會指出原因。

監控封包遺失的原因

如要找出封包遺失的原因,請在 Cloud Monitoring 中查詢指標觀察器。封包遭到捨棄的原因有三種:

  • OUT_OF_RESOURCES
  • ENDPOINT_INDEPENDENT_CONFLICT
  • NAT_ALLOCATION_FAILED

如要找出因 OUT_OF_RESOURCESENDPOINT_ALLOCATION_FAILED 錯誤碼而捨棄的封包,請使用下列查詢:

fetch nat_gateway
  metric 'router.googleapis.com/nat/dropped_sent_packets_count'
  filter (resource.gateway_name == GATEWAY_NAME)
  align rate(1m)
  every 1m
  group_by [metric.reason],
    [value_dropped_sent_packets_count_aggregate:
       aggregate(value.dropped_sent_packets_count)]

如果發現封包因這些原因而遭捨棄,請參閱「Packets dropped with reason: out of resources」和「Packets dropped with reason: endpoint independent conflict」一文,瞭解疑難排解建議。

如要找出因 NAT_ALLOCATION_FAILED 錯誤碼而捨棄的封包,請使用下列查詢:

fetch nat_gateway
  metric 'router.googleapis.com/nat/nat_allocation_failed'
  group_by 1m,
    [value_nat_allocation_failed_count_true:
       count_true(value.nat_allocation_failed)]
  every 1m

如果發現封包因這個原因而遭到捨棄,請參閱「需要分配更多 IP 位址」。

調查 Cloud NAT 設定

如果先前的查詢傳回空白結果,且 GKE Pod 無法與外部 IP 位址通訊,請參閱下表,排解設定問題:

設定 疑難排解
Cloud NAT 設定為僅適用於子網路的主要 IP 位址範圍。 如果只為子網路的主要 IP 位址範圍設定 Cloud NAT,從叢集傳送至外部 IP 位址的封包就必須具備來源節點 IP 位址。在這個 Cloud NAT 設定中:
  • 如果外部 IP 位址目的地受到 IP 位址偽裝限制,Pod 就能將封包傳送到這些外部 IP 位址。部署 ip-masq-agent 時,請確認 nonMasqueradeCIDRs 清單不含目的地 IP 位址和通訊埠。傳送至這些目的地的封包會先轉換為來源節點 IP 位址,再由 Cloud NAT 處理。
  • 如要允許 Pod 透過這項 Cloud NAT 設定連線至所有外部 IP 位址,請確認已部署 ip-masq-agent,且 nonMasqueradeCIDRs 清單只包含叢集的節點和 Pod IP 位址範圍。傳送至叢集外部目的地的封包,會先轉換為來源節點 IP 位址,再由 Cloud NAT 處理。
  • 如要防止 Pod 將封包傳送至某些外部 IP 位址,您必須明確封鎖這些位址,以免遭到偽裝。部署 ip-masq-agent 後,請將要封鎖的外部 IP 位址新增至 nonMasqueradeCIDRs 清單。傳送至這些目的地的封包會離開節點,並保留原始的 Pod IP 位址來源。Pod IP 位址來自叢集子網路的次要 IP 位址範圍。在這個設定中,Cloud NAT 不會對該次要範圍運作。
設定 Cloud NAT,只套用至用於 Pod IP 的子網路次要 IP 位址範圍。

如果 Cloud NAT 僅針對叢集 Pod IP 使用的子網路次要 IP 位址範圍設定,則從叢集傳送至外部 IP 位址的封包必須具有來源 Pod IP 位址。在這個 Cloud NAT 設定中:

  • 使用 IP 偽裝代理程式會導致封包在 Cloud NAT 處理時遺失來源 Pod IP 位址。如要保留來源 Pod IP 位址,請在 nonMasqueradeCIDRs 清單中指定目的地 IP 位址範圍。部署 ip-masq-agent 後,傳送至 nonMasqueradeCIDRs 清單上目的地的任何封包,都會在 Cloud NAT 處理前保留來源 Pod IP 位址。
  • 如要允許 Pod 透過這項 Cloud NAT 設定連線至所有外部 IP 位址,請確保已部署 ip-masq-agent,且 nonMasqueradeCIDRs 清單盡可能擴大 (0.0.0.0/0 會指定所有 IP 位址目的地)。傳送至所有目的地的封包,在 Cloud NAT 處理前會保留來源 Pod IP 位址。

減少封包遺失

診斷出封包遺失的原因後,請考慮採用下列建議,降低日後再次發生問題的機率:

  • 將 Cloud NAT 閘道設定為使用動態通訊埠分配,並提高每個 VM 的通訊埠數量上限

  • 如果使用靜態通訊埠分配,請增加每個 VM 的通訊埠數量下限

  • 降低應用程式的輸出封包速率。如果應用程式對相同的目的地 IP 位址和通訊埠建立多個輸出連線,可能會快速耗盡 Cloud NAT 可對該目的地建立的所有連線,因為這類連線會使用已分配的 NAT 來源位址和來源通訊埠元組數量。

    如要進一步瞭解 Cloud NAT 如何使用 NAT 來源位址和來源通訊埠建立連線,包括連線至目的地的並行連線數量限制,請參閱「通訊埠和連線」。

    如要降低應用程式的出站連線率,請重複使用開啟的連線。重複使用連線的常見方法包括連線共用、使用 HTTP/2 等通訊協定多工處理連線,或是建立可重複用於多項要求的持續性連線。詳情請參閱「通訊埠和連線」。

後續步驟