クラスタからの Cloud NAT パケットロスをトラブルシューティングする。


このページでは、VPC ネイティブの Google Kubernetes Engine(GKE)限定公開クラスタからの Cloud NAT パケットが損失する問題の解決方法について説明します。

VPC ネイティブの 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 の指標オブザーバーにクエリを実行します。いずれかでパケットがドロップする原因としては、次の 3 つの理由が考えられます。

  • 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)]

これらの理由でドロップされたパケットを特定した場合は、リソース不足によってパケットがドロップされるエンドポイントに依存しない競合によってパケットがドロップされるでトラブルシューティングのアドバイスをご覧ください。

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 アドレスと通信できない場合は、次の表を使用して構成のトラブルシューティングを行います。

構成 トラブルシューティング
サブネットのプライマリ IP アドレス範囲にのみ適用されるように構成された Cloud NAT。 Cloud NAT がサブネットのプライマリ IP アドレス範囲にのみ構成されている場合、クラスタから外部 IP アドレスに送信されるパケットに送信元ノードの IP アドレスが必要です。この Cloud NAT 構成では、次のことが発生します。
  • 外部 IP アドレスの宛先が IP マスカレードの対象である場合、Pod は外部 IP アドレスにパケットを送信できます。ip-masq-agent をデプロイするときに、nonMasqueradeCIDRs リストに宛先 IP アドレスとポートが含まれていないことを確認します。これらの宛先に送信されたパケットは、まず送信元ノードの IP アドレスに変換されてから、Cloud NAT によって処理されます。
  • この Cloud NAT 構成を使用して Pod がすべての外部 IP アドレスに接続できるようにするには、ip-masq-agent がデプロイされ、nonMasqueradeCIDRs リストにクラスタのノードと Pod IP アドレス範囲のみが含まれていることを確認します。クラスタ外の宛先に送信されたパケットは、まず送信元ノードの IP アドレスに変換されてから、Cloud NAT によって処理されます。
  • Pod が一部の外部 IP アドレスにパケットを送信しないようにするには、これらのアドレスを明示的にブロックして、マスカレードされないようにする必要があります。ip-masq-agent がデプロイされたら、ブロックする外部 IP アドレスを nonMasqueradeCIDRs リストに追加します。これらの宛先に送信されたパケットは、元の Pod IP アドレスの送信元とともにノードから送信されます。Pod の IP アドレスは、クラスタのサブネットのセカンダリ IP アドレス範囲から取得されます。この構成では、Cloud NAT はそのセカンダリ範囲で動作しません。
Pod IP に使用されるサブネットのセカンダリ IP アドレス範囲にのみ適用されるように構成された Cloud NAT。

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 アドレスを保持します。
  • この Cloud NAT 構成を使用して Pod がすべての外部 IP アドレスに接続できるようにするには、ip-masq-agent がデプロイされ、nonMasqueradeCIDRs リストが可能な限り大きくなっていることを確認します(0.0.0.0/0 に、すべての IP アドレスの宛先を指定します)。すべての宛先に送信されたパケットは、Cloud NAT によって処理される前に送信元 Pod IP アドレスを保持します。

パケットロスを減らす

パケットロスの原因を診断したら、次の推奨事項を使用して、問題が再発する可能性を低減することを検討してください。

  • 動的ポート割り当てを使用するように Cloud NAT ゲートウェイを構成し、VM あたりの最大ポート数を増やす

  • 静的ポートの割り当てを使用している場合は、VM あたりの最小ポート数を増やす

  • アプリケーションのアウトバウンド パケットレートを減らす。アプリケーションが同じ宛先 IP アドレスとポートに対して複数のアウトバウンド接続を行う場合、割り当てられた NAT 送信元アドレスと送信元ポートのタプルの数を使用して、Cloud NAT がその宛先に対して確立できるすべての接続がすぐに消費される可能性があります。

    宛先への同時接続数の制限など、Cloud NAT が NAT の送信元アドレスと送信元ポートを使用して接続を確立する方法については、ポートと接続をご覧ください。

    アプリケーションからのアウトバウンド接続のレートを下げるには、開いている接続を再利用します。接続を再利用する一般的な方法としては、接続プーリング、HTTP/2 などのプロトコルを使用した接続の多重化、複数のリクエストで再利用される永続的な接続の確立、などがあります。詳細については、ポートと接続をご覧ください。

次のステップ

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。