外部公開している NLB 1 台だけでプライベートなアクセス経路も確保する

外部公開しているサービスを社内利用するかつ社内利用の場合はインターネットに出ずにプライベートにアクセスしたい場面を考えます
2024.04.04

タイトルを見て思った方もいるかと思います。

おまえは何を言っているんだ、と。

外部へ公開しているアプリケーションがあった場合へのアクセスとして、

  • インターネットへ公開するためのアクセス経路
  • メンテナンスや社内利用するためのアクセス経路

の 2 系統の経路を用意したいシチュエーションを考えます。

その場合、外部公開用、社内利用用の 2 つの経路のロードバランサーを用意するアーキテクチャを見かけると思います。

例えば、外部公開用の NLB または ALB と内部向けの NLB または ALB をそれぞれ用意し、
それぞれのターゲットグループでターゲットへリクエストを送る構成です。

※1 つの AZ にしかアイコンを書いていないですが、厳密には両 AZ にまたがっています。

また、ロードバランサーの宛先には ALB を指定可能なので、
外部公開用の NLB または ALB のターゲットに内部向けの ALB を指定することで似たようなことが実現可能です。

しかし、ロードバランサーを 2 台設置せずに実現できる方法があるため、その構成をチャレンジしてみます。

早くも結論

ロードバランサーを 2 つ設置せずに実現できる方法は、
外部公開用の NLB とエンドポイントサービスを関連付け、PrivateLink を経由してアクセスすることで、
NLB 1 台の使用に留め、パブリックアクセスもプライベートアクセスも両立できます。

なぜ

Internet-Facing の NLB を使用しているため違和感があるかもしれませんが、
PrivateLink で結ばれた接続は AWS Hyperplane という技術が使われ、プライベートかつ拡張性の高い分散システムとなっています。

こちらの記事も合わせてご確認ください。

エンドポイントサービスと NLB 間も AWS 空間内で接続されているため当然プライベートに接続されます。

そのため PrivateLink の入り口になるインターフェイス型 VPC エンドポイントまでプライベートで接続されていれば、インターネットに出ることなく外部公開用の NLB に到達可能となります。

実際にやってみた

専用線を模した疑似的な環境で実際にやってみます。

専用線の代わりに VPC ピアリングで VPC 同士を接続し、インターネットゲートウェイへのデフォルトルートのない環境からアクセスしてみようと思います。

構築には、Terraform を使用しました。
テンプレートは下記リポジトリにありますので、もし検証してみたい方いましたらご活用ください。

上記コードをデプロイできたらまずはインターネット経由で NLB にアクセスできるかを確認します。

ELB のコンソール画面を確認すると nlb という名前の NLB が作成されているため、DNS 名をブラウザで開きます。

すると、Hello form (ホスト名)の形で表示されるかと思います。

まずはインターネット経由でアクセスできていることが確認できたので、
続いて接続元の EC2 に Instance Connect Endpoint を使用して接続したいと思います。

EC2 のコンソール画面を見ると、test-ec2-instanceというインスタンスがあるためこちらに接続します。

まず外部のドメイン宛てに ping コマンドをたたくと、レスポンスがなくインターネットに出れないことが分かります。

続いて VPC エンドポイントのコンソール画面から DNS 名を取得します。
対象の VPC エンドポイントはサービス名が com.amazonaws.vpce.ap-northeast-1.vpce- で始まるものです。

この DNS 名宛に curl コマンドをたたくと、

無事、Hello form (ホスト名)の形で表示されました。
※EC2 を冗長化しているため、ホスト名はラウンドロビンで変わります。

比較

ロードバランサーを 2 つ活用する方法と、 NLB1 つに対して PrivateLink も活用する方法それぞれの比較していきます。

コスト

まずコストを比較してみます。
条件は、ELB の料金ページの 例 1 を参考にします。

アプリケーションが 1 秒あたり平均 1 個の新しい接続を受信し、それぞれ 2 分間継続すると仮定します。クライアントは毎秒平均 5 つのリクエストを送信し、リクエストと応答の合計処理バイト数は毎秒 300 KB です。このとき、ロードバランサーにおいて、クライアントのリクエストをルーティングする 60 個のルールを設定したとします。

この条件に 2AZ で冗長化する条件を加える場合、Pricing Calculator で確認すると、

ALB1 台で、17.74USD/月(固定時間料金)+6.31USD/月(LCU の使用料金) = 24.05USD/月
NLB1 台で、17.74USD/月(固定時間料金)+4.73USD/月(LCU の使用料金) = 22.48USD/月

合計で46.52USD/月

LCU の計算方法は下記ブログが大変参考になりました。
AWS ALB の LCU の料金計算方法の備忘録 #AWS - Qiita

続いて同じ条件で PrivateLink も計算します。

PrivateLink は、インターフェイス型 VPC エンドポイントの使用料金とデータ処理コストで決められます。
冗長化により 2AZ にそれぞれエンドポイントがあることを条件に加えます。

すると、1.08GB/時間は 777.6GB/月のため

20.44USD/月(固定時間料金) ×2 + 7.776USD/月(データ処理コスト) = 48.66USD/月

上記より、約 2USD ほど PrivateLink のほうが高くなってしまいました。
コスト観点だとロードバランサーを 2 台使用するほうが軍配がありそうです。

柔軟性

続いて柔軟性ですが、アクセス制限について考えると、

まずロードバランサー 2 つ活用する場合、それぞれでセキュリティグループを割り当てられるため、セキュリティグループで出来る範囲以上のアクセス制限をしたい場合は別の仕組みを導入する必要があります。

しかし PrivateLink の場合、VPC エンドポイントのエンドポイントポリシーにより、柔軟にアクセス制限をかけることができます。

スケーリングという観点では、ロードバランサーは内部的にスケーリングし、VPC エンドポイントについても帯域幅などは最大 100Gbps まで自動でスケーリングしてくれます。

おわりに

今回は、1 つの NLB に対してパブリックアクセスとプライベートアクセスを両立させる方法を検証してみました。

実際どちらの方法を選択いただくかはユースケースに応じて変わってくるかと思いますので方法の 1 つとして覚えておいていただければと思います。

この記事がどなたかの役に立つと嬉しいです。