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

在VPC 原生 Google Kubernetes Engine (GKE) 叢集中,沒有外部 IP 位址的節點可提升安全性。這些節點會使用 Cloud NAT 建立對外網際網路連線。如果節點 VM 用盡分配到的 Cloud NAT 通訊埠和 IP 位址,就可能發生封包遺失,這通常是在傳出負載過高時發生,會中斷輸出流量。

本文說明如何記錄及監控丟棄的封包、調查 Cloud NAT 設定,以及採取措施減少日後封包遺失的情況。

如果平台管理員、操作員和網路管理員管理的 GKE 叢集節點沒有網路連線能力,且須仰賴 Cloud NAT 建立外部連線,則這項資訊非常重要。如要進一步瞭解Google Cloud 內容中提及的常見角色和工作範例,請參閱「常見的 GKE 使用者角色和工作」。

診斷封包遺失問題

以下各節說明如何使用 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_RESOURCES 或 ENDPOINT_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-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 時,只適用於子網路的次要 IP 位址範圍 (用於 Pod IP)。

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

  • 使用 IP 偽裝代理程式會導致封包在 Cloud NAT 處理時遺失來源 Pod IP 位址。如要保留來源 Pod IP 位址,請在 nonMasqueradeCIDRs 清單中指定目的地 IP 位址範圍。部署 ip-masq-agent 後,傳送至 nonMasqueradeCIDRs 清單上目的地的任何封包,都會保留來源 Pod IP 位址,再由 Cloud NAT 處理。
  • 如要允許 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 等通訊協定多工處理連線,或是建立可重複用於多項要求的持續性連線。詳情請參閱「通訊埠和連線」。

後續步驟