AzurePaaS研究サイト

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

SNAT ポート枯渇エラーとは? 解決方法を説明します。

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

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

SNAT ポート枯渇エラーとは

 
"SNAT ポート枯渇" は、アプリケーション開発をされてる皆さまには、馴染みのないワードだと思います。
ですので、まずはAzureプラットフォーム側の目線で、どういうものとして扱われているのかを説明します。
 
App Service は、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 ポート枯渇が発生しないよう、何かしらを修正していく必要があります。
 

SNAT ポート枯渇の解決方法
プログラムコード修正
スケールアウト
仮想ネットワーク・Vnetを構築
ASEを構築

 

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

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

docs.microsoft.com

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

qiita.com

 

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

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

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を構築する

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

参考サイト

公開情報

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

docs.microsoft.com

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

海外サイト

4lowtherabbit.github.io

Microsoft の方の記事

qiita.com

 
 
以上です。
 

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