<-- mermaid -->

APIが遅いと思っていたら、GCPのCloudNATでパケロスしていた話

導入

こんにちは、Product Team SREのkterui9019です。 今回はGCPのCloudNATについての調査結果を共有したいと思います。CloudNATを利用している中で気づかないうちに実はパケットロスが発生していたので、詳細をご紹介します。

問題の発覚

私たちはお客様からの問い合わせを受けて、GKEにデプロイされている特定のマイクロサービスの「遅いエンドポイント」について調査を行っていました。 Datadogのトレースを追っていく中で、GCPのVPC外へのAPIアクセスがタイムアウトしていることが判明しました。しかし、VPC外のAPI自体は数ミリ秒でレスポンスを返していたのです。

APIのレスポンスが終わっているのに呼び出し元の関数が異常に長いスパンになっていた

この問題はネットワークに関連する可能性が高いと予測し、CloudNATのモニタリング指標を調査してみると、「OUT_OF_RESOURCES」というエラーが散発的に発生していることに気づきました。公式ドキュメントによれば、このエラーはNAT IPアドレスまたはポートが不足している場合に発生するとされています。

動的ポート割り当ての落とし穴

私たちはCloudNATの動的ポート割り当て機能をオンにしていたため、最初は最小ポート数についてあまり注意を払っていませんでした(デフォルトの最小ポート数は32)。なお動的ポート割り当ては、CloudNATが割り当てられるポートを使い切ると、割り当て可能ポート数を2倍に増やしてくれる機能です。

しかし、ドキュメントを読み進めると、ポートを使い切り、CloudNATが割り当て可能ポートを増やしている間はパケットがドロップされる可能性があることがわかりました。コード上同一のVPC外エンドポイントに対して複数のリクエストを並列に送信する実装になっていたため、最小割り当て可能ポートを超える並列数でリクエストを送信し、ポートが増える間パケットが捨てられていた可能性が高いと推測できます。(なお並列数はユーザーの持っているデータ量次第で増加します)。

解決方法としましては、上記の通り最小ポート数以上のリクエストが発生するとパケットがドロップする可能性があるため最小ポート数を余裕を持った数値の1024に設定変更し、OUT_OF_RESOURCESエラーを抑制することができました。

監視とアラート

最後に、この「OUT_OF_RESOURCES」エラーはCloudMonitoringで監視できるため、アラートを設定しておくことをおすすめします。具体的には、「nat/dropped_sent_packets_count」というメトリクスを利用することができます。


以上が、私たちのCloudNATに関する調査結果とパフォーマンスチューニングのポイントです。パケットロスに悩んでいる場合は、最小ポート数の設定と同時並列リクエスト数に注意してみてください。円滑なネットワーク接続を実現することができるはずです。

それでは次回のブログ記事でもお会いしましょう。

Page top