2020/2/19 更新
Azure にて Virtual Network NAT というサービスがパブリックプレビューになり、AWS や GCP と同等の構成を行うことが可能になりました。
Azure では Virtual Network NAT を使うという選択肢が増えたとお考え下さい。
この記事は Azure Advent Calendar 2019 の 11 日目です。 qiita.com
Microsoft Azure では Private IP から Public IP への通信は基本的に自動で NAT 変換が行われます。 Microsoft のドキュメントでは NAT ではなく、 SNAT と明記されることが多いようです。
SNAT とは?
Source NAT, 送信元 NAT と呼ばれます。
SNATとは、2つのTCP/IPネットワークの境界にある機器が双方のIPアドレスを自動的に変換するNAT(Network Address Translation)のうち、送信元アドレスを書き換える方式。
(中略)
SNATは組織内のLANなどでプライベートアドレス(ローカルアドレス)しか持たないパソコンなどが、ネットワーク境界の機器が持つグローバルアドレス(インターネット上のアドレス)を使って外部と通信するためによく用いられる。
具体的な例では Public IP を持たない VM がインターネットにアクセスしようとするときに SNAT 変換が行われます。
AWS, GCP, Azure で SNAT できる構成はどんなの?
私が調べた限りですと、 Azure だけちょっと特殊に見えました。それぞれ具体的に見ていきましょう。
AWS
VPC を使用して、 Public IP を持たない EC2 インスタンスがインターネットにアクセスするためには、 NAT Instance と呼ばれる EC2 を別途作成するか、またはマネージドな NAT Gateway を使用します。
2019年12月現在、 NAT Instance を積極的に採用する理由はあまりなさそうに思えたので、 NAT Gateway を利用した場合のイメージを作成しました。正確に書くと Router が入るようですが、説明を簡素化するため省略しました。
このとき、NAT Gateway と Elastic IP が課金されます。
GCP
GCP の場合も AWS とほぼ同様に見受けられました。
こちらの情報が大変参考になりました。
料金は AWS とほぼ同様のようです。
- NAT ゲートウェイの 1 時間あたりの料金(NAT ゲートウェイにつき 1 時間あ- たり $0.045 から)
- ゲートウェイによって処理された上りトラフィックと下りトラフィックの 1 GB あたりの料金
- VM からトラフィックをネットワーク外に送信するための下り料金は変更なし
Azure
Azure の場合は NAT Gateway を用意しなくても SNAT 変換されます。
公式ドキュメント のシナリオ3相当になるのですが、宇田さんの記事がよりわかりやすいです。
以下のように Azure の NAT は3種類のパターンに分かれます。
- VM に Public IP がある場合: VM (NIC) に紐づいた Public IP で SNAT
- VM に Public IP がなく、外部 LB に紐づいている場合: LB の Public IP で SNAT
- VM に Public IP も外部 LB にも紐づいていない場合: 当該リージョンの任意の Public IP で SNAT
Azure の良い特徴でもあり、悪いところかもしれません。ほかのクラウドを使っていた人からするとちょっと戸惑うと思います。
明示的に SNAT Gateway のような機能を用意しなくても暗黙的に SNAT がされます。料金はかかりません。
他のクラウドのように SNAT Gateway のようなものを作りたければ、先の2のパターンになり、外部 LB が NAT Gateway 兼 Load Balancer のように動作します。
SNAT 変換ができなくなると何が起こる?
SNAT ができる数は限られていまして、枯渇すると単純に通信ができなくなります。数年前の自宅用ルーターではわりとよく起きていたと思います。
クラウドにおいても、当然利用できるポートは限られています。
AWS
- NAT ゲートウェイ - Amazon Virtual Private Cloud
- NAT ゲートウェイは送信先別に最大 55,000 の同時接続をサポートできます。
GCP
- Quotas | Cloud NAT | Google Cloud
- For Cloud NAT, this limit is reduced to a total of 64k connections per VM for all supported protocols combined.
- VM ごとに 64k に制限されるというように読み取れます
Azure
外部 LBを立てた場合です。
- アウトバウンド規則 - Azure Load Balancer | Microsoft Docs
- フロントエンドのパブリック IP アドレスごとに、SNAT ポートとして使用する最大 64,000 個のエフェメラル ポートが提供されます。
- ただし、初期設定では最初の 50 VM インスタンスは 1024 ポート、51 から 100 の VM インスタンスは、512 ポートのみ使えるようになっています。1 VM に 10,000 ポートを割り当てたい場合は手動構成が必要。
SNAT をうまくやりくりするには?
アプリ上でプログラミングを工夫することで SNAT の消費を避けることができます。以前書いた記事を参照してください。
しかしながら、個人的に懸念しているのは、昨今のアプリはコンテナ化により 1 VM 上で動作する個々のアプリは増加しており、それぞれのアプリは独立したコンテナ上で動いているため、使用する SNAT 数は爆発的に増えていると考えています。つまり、各コンテナ間で SNAT を共有するプールのような仕組みは無いため、 マイクロサービスのように Public IP で外部サービスを多数利用する場合、 SNAT の枯渇はかなり起きやすい問題では? と考えています。
まだ自分の中での仮説にすぎないので、今後この問題に直面した時に、なんらかの解があればまたブログなどにしたいと思います。
今回は Azure だけでなく、AWS と GCP も加えましたので、皆さんの参考になれば幸いです。