AzurePaaS研究サイト

~理解しずらい情報をシンプルにお伝えします~

SNAT ポート枯渇エラーとは(解決方法も紹介)

SNAT ポート枯渇エラーとは

 
Microsoft Azure の有償サポートに、「この時間に 503 エラーが発生してたのですが、Azure 側で何か起きてませんでしたか。」などと問合せをすると、「本事象は SNAT ポート枯渇が原因で発生したと推測されます。」と返事がくることがあります。
 
今回は、「SNAT ポート枯渇とは」「解決方法」について書きます。
 

SNAT ポートを意識するのはどういう場面か

 
"SNAT ポート枯渇" は、アプリケーション開発をされてる皆さまには、馴染みのないワードだと思います。
ですので、まずはAzureプラットフォーム側の目線で、どういうものとして扱われているのかを説明します。
 

SNAT ポートが使用されるタイミングと場所

 
クライアントからリクエストを受信した際、アプリケーションが処理を行いますよね。この Azure で動作しているアプリケーション処理にて、Azure 内のリソース(StorageAccount/SQL Databaseや他の AppService/Functions など)や Azure 以外の外部サービスへリクエストを送る場合がございます。その際に、SNAT ポートが使用されます。
 
 
イメージ
ClientPC <-> (Azure)FrontEnd <-> AppService <-【SNATポート使用】-> Azureリソースや外部サービス
 
 
アプリケーションにアクセスするユーザが、1人か複数人かどうかは関係ありません。
アクセスされているユーザが少なくても、クライアントからのリクエストが1件だけでも、アプリケーション処理で何かしらの要因で多くのループ処理が行われて、同じ宛先に対して多くの外部アクセス通信が発生した場合は、異なる SNAT ポートが使用されて SNAT ポート枯渇の可能性が発生する可能性があります。
 
そのため、お客様のアプリケーションにアクセスされているユーザ様の人数は、SNAT ポートの使用状況に直接関係ありません。
 
 

Azure 内部の仕組みを説明

 
AppServiceは、1 台のインスタンスに対して、SNAT 変換を行うために最低で 128 の SNAT ポートが保証されており、そこまでの SNAT ポートは問題なく確保されます。そして、それを超える SNAT ポートが必要になった場合には、インスタンスが所属するスケール ユニット (スタンプ) から、余剰な SNAT ポートが動的に割り当てられます。
 
この際、1 つのスタンプでは、総計で 64,000 の SNAT ポートを確保できますが、スタンプ全体でそれを超えた SNAT ポートが要求された場合には、SNAT ポートの枯渇が発生することになるのです。
 
SNAT ポートの枯渇について、同一スタンプ内の他ユーザー様でポートの使用量が増加した、といったようなことがあった場合に、スタンプ全体でのポート使用量が増加し、最低保証数以上のポート確保ができなくなる可能性があります。
他ユーザのポート使用状況については、把握することが困難なものとなります。  
 
以下の公式ドキュメントに、トラブルシューティング ガイドが書いてあります。
 
送信プロキシの Azure Load Balancer > ポートの枯渇

アウトバウンド接続の送信元ネットワーク アドレス変換 (SNAT) - Azure Load Balancer | Microsoft Docs

===== 抜粋 ここから =====
ポートの枯渇が発生すると、宛先 IP への新しい送信接続は失敗します。 ポートが使用可能になると、接続は成功します。 この枯渇は、IP アドレスからの 64,000 個のポートが多数のバックエンド インスタンスにわたってまばらに分散されている場合に発生します。 SNAT ポートの枯渇を軽減するためのガイダンスについては、トラブルシューティング ガイドのページを参照してください。
===== 抜粋 ここまで =====
 

解決方法

 
SNAT ポート枯渇が発生しないように、アプリケーションプログラムを改良、または Azure 上の設定を変更などしていく必要があります。
 
具体的な方法を紹介していきます。
 

SNAT ポート枯渇の解決方法
アプリケーションのプログラムコードを改良
スケールアウトでインスタンス数を増やす
仮想ネットワーク・Vnet統合を構築する
ASE(AppServiceEnvironment)を構築

アプリケーションのプログラムコードを改良

 
以下の公式ドキュメントに、App Service における送受信接続エラーの解決策について書かれています。
 
Azure App Service での断続的な送信接続エラーのトラブルシューティング > 問題の回避

docs.microsoft.com

===== 抜粋 ここから =====
可能な場合は、接続プールを使用するようにコードを改良し、すべての状況を改善します。
必ずしも、この状況を軽減するのに十分な時間をかけてコードを変更できるとは限りません。
時間内にコードを変更できない場合は、他の解決策を利用してください。
問題を解決する最善策として、すべての解決策を可能な限り組み合わせることをお勧めします。
Azure サービスにはサービス エンドポイントとプライベート エンドポイントを、それ以外には NAT Gateway を使用してみてください。
===== 抜粋 ここまで =====
 
 
その他にもプログラムコードについて書かれている参考サイトを貼っておきます。
 

qiita.com
blog.nnasaki.com

===== 抜粋 ここから =====
こうすることで HttpClient を自分のアプリケーションと SDK で共有できるので、より効率的に SNAT を利用できることができます。
まとめ
.NET Core 2.1 以降 であれば HttpClient を直接使うより、 HttpClientFactory を利用したほうがよりメリットを享受できると感じました。
===== 抜粋 ここまで =====

 

スケールアウトでインスタンス数を増やす

なぜスケールアウトで解決するのか説明

 
AppService では、1 台のインスタンスに対して、SNAT 変換を行うために最低で 128 の SNAT ポートが保証されており、そこまでの SNAT ポートは問題なく確保されます。
 
そして、それを超える SNAT ポートが必要になった場合には、インスタンスが所属するスケール ユニット (スタンプ) から、余剰な SNAT ポートが動的に割り当てられます。
この際、1 つのスタンプでは、総計で 64,000 の SNAT ポートを確保できるが、スタンプ全体でそれを超えた SNAT ポートが要求された場合には、SNAT ポートの枯渇が発生することになります。
 
SNAT ポートの枯渇について、同一スタンプ内の他ユーザーでポートの使用量が増加した、といったようなことがあった場合に、スタンプ全体でのポート使用量が増加し、最低保証数以上のポート確保ができなくなる可能性もあります。(※他ユーザのポート使用状況については確認することはできない)
 

保証される SNAT ポート数

 
インスタンス数を増加すると、保証される SNAT ポート数が増えます。
 
インスタンス台数ごとの保証される SNAT ポート数

インスタンス台数 保証 SNAT ポート数
1台 128ポート
2台 256ポート
3台 384ポート

注意点

インスタンス数を増やして、保証される SNAT ポート数を増やしたとしても、一時的にそれ以上の SNAT ポート数が必要になってしまった場合は、また SNAT ポート枯渇エラーが発生してしまう可能性があります。なので、スケールアウトは手軽にできる一時的な解決方法ですが、手軽な分 SNAT ポート枯渇が発生してしまう可能性は残りますので、ご理解ください。

仮想ネットワーク・Vnet統合を構築する

なぜ解決方法になるのか

仮想ネットワーク内のリソース同士が通信する場合は、SNAT ポートは使用されないので、スケールアウトと違って SNAT ポート枯渇が発生する可能性はなくせます。

注意点

SNAT ポート枯渇が発生する可能性がなくなるのは良いのですが、そもそも仮想ネットワーク・Vnet統合は、本来より高いセキュリティを確保したい場合に構築するものなので、SNAT ポート枯渇の発生をさせなくするために使用するのは少し違うのではないかと思いますので、推奨はしておりません。
 

ASE(AppServiceEnvironment)を構築する

ASE を使用すると、1台のサーバで使える数万の SNAT ポートをすべて使えるので、SNAT ポート枯渇は発生しなくなります。
 
ただ・・・ASE も本来セキュリティの確保やカスタマイズが柔軟にできるなどの目的で使用するものなので、SNAT ポート枯渇を発生させなくするために使用するのは推奨しません。1ヶ月の課金額が数十万円跳ね上がりますからね。
 

参考サイト

Microsoft 公式ドキュメント

SNAT ポートの枯渇に関する公式ドキュメントを貼っておきます。
 
送信プロキシの Azure Load Balancer > ポートの枯渇

docs.microsoft.com

===== 抜粋 ここから =====
ポートの枯渇が発生すると、宛先 IP への新しい送信接続は失敗します。 ポートが使用可能になると、接続は成功します。 この枯渇は、IP アドレスからの 64,000 個のポートが多数のバックエンド インスタンスにわたってまばらに分散されている場合に発生します。 SNAT ポートの枯渇を軽減するためのガイダンスについては、トラブルシューティング ガイドのページを参照してください。
===== 抜粋 ここまで =====

参考になる海外サイト

4lowtherabbit.github.io

Microsoft 社員の方の記事

qiita.com

 
 
以上です。
 

ご意見・ご要望はこちらへ