こんにちは!SRE兼クラウドアーキテクトの私です。
クラウドの世界に飛び込んだばかりの頃って、次から次へと出てくる横文字の略語に圧倒されてしまいますよね。「ALB? NLB? どっちを使えばいいの?」「IPアドレスがそのまま通るってどういうこと?」と、頭がぐるぐるしてしまう方も多いはずです。
今回は、AWSなどのメガクラウドで超重要な役割を持つ「NLB(Network Load Balancer)」を取り上げます。その中でも、特に現場でよく使われる「TCPトラフィックの透過的フォワーディング(クライアントのIPアドレスをそのまま保持する仕組み)」について、現実世界のエピソードを交えながら、優しく丁寧に紐解いていきたいと思います。
一歩ずつ、リラックスして読み進めていきましょう!
—
そもそも「NLB」ってなに? 身近な例えで考えてみよう
ロードバランサー(負荷分散装置)という言葉を聞くと、なんだか難しそうな機械を想像してしまいますよね。でも、基本の役割はとてもシンプルです。
例えば、大人気のラーメン屋さんにたくさんのお客さんが行列を作っていると想像してください。店主(サーバー)が1人だけだと、注文を聞いて、ラーメンを作って、会計をして…と手が回りませんよね。そこで登場するのが「案内係のお兄さん(ロードバランサー)」です。
案内係のお兄さんは、次々やってくるお客さんを、空いているカウンターの席へ上手に振り分けてくれます。これによって、お店全体としての処理能力がぐっと上がるわけです。
この案内係には、いくつか種類があります。
- ALB(Application Load Balancer):お客さんの注文の内容(「餃子を追加で」「味噌ラーメンで」といったHTTPのURLやパス)までしっかり聞いて、詳しい案内をしてくれる「気が利くコンシェルジュタイプ」。
- NLB(Network Load Balancer):お客さんが何を食べたいかは気にせず、「はい、あなたは何番の席ね!」と、秒速で次々と案内していく「超高速かつ体育会系な案内係」。
NLBは、レイヤー4(トランスポート層)と呼ばれるネットワークの深くない層で動くため、とにかくスピードが命です。TCPやUDPといった通信を、驚異的な速さでバックエンドのサーバー(EC2インスタンスやKubernetesのノードなど)へ届けます。
—
謎解き:なぜNLBは「クライアントのIPアドレス」を隠さないのか?
さて、ここからが今回の本題です。
普通の一般的なプロキシや、先ほど紹介したALBを通すと、バックエンドのサーバーから見たときに見える「お客さんのIPアドレス」は、ロードバランサー自身のものに書き換わってしまいます。郵便物で例えるなら、一度中継地点の郵便局で差出人の名前が「郵便局の住所」に書き換えられてから届くようなイメージですね。
しかし、NLBは違います。
NLBがポート80番(HTTP)、443番(HTTPS)、あるいは22番(SSH)などのTCPトラフィックをバックエンドのターゲットグループへ転送するとき、クライアントが使っていた本来の送信元IPアドレスとポート番号を、そのまま(透過的に)保持した状態でパススルーするという特徴を持っています。
郵便の例えで言えば、中継地点の配達員が中身を開けず、封筒の差出人欄をそのままにしてあなたの元へ届けてくれるような状態です。これをネットワークの世界では「ソースIP保存(Source IP Preservation)」と呼びます。
なぜこの仕組みが現場で喜ばれるのか?
「IPアドレスがそのまま見えると、何が嬉しいの?」と思いますよね。現場のSREやインフラエンジニアがこの仕組みに歓喜する理由は主に3つあります。
1. アクセスログに本当の客の足跡が残る
Webサーバーやセキュリティアプライアンス(WAFやファイアウォールなど)にとって、「誰がアクセスしてきたのか」という送信元IPアドレスは命の次に大事な情報です。NLBがIPを隠さないおかげで、バックエンドのサーバー側で「お、またあの常連さんが来てくれたな」と正確に把握できます。
2. SSHなどのリモート接続(ポート22番)で必須になる
例えば、踏み台サーバーを経由せずに、NLB経由で直接特定のプライベートインスタンスへSSH(ポート22番)接続したい場合、サーバー側で「どのIPからの接続を許可するか(セキュリティグループやhosts.allowなど)」を厳密に制御したいですよね。IPが保持されるからこそ、こうしたセキュリティ担保が成り立ちます。
3. ゲームサーバーやリアルタイム通信との相性が抜群
オンプレミスからクラウドへ移行するオンラインゲームのサーバーなどでは、クライアントとのTCP/UDPセッションが密に結ばれています。IPアドレスやポート番号が途中で変わってしまうと、セッションがプツリと切れてしまうことがあるため、透過的なNLBが必須となります。
—
実務でどう設定する? AWS CLIでの具体例
言葉だけだとフワッとしてしまうので、実際にAWS上でNLBのリスナーとターゲットグループを作成する際の設定例を見てみましょう。
今回は、読者の皆さんが実務でそのままコピー&ペーストして調整できるように、AWS CLIのコマンドを用意しました。もちろん日本語の解説付きです!
# 1. バックエンドのサーバーを受け入れる「ターゲットグループ」を作成します
# ここでポイントなのは、ターゲットのタイプとして「instance(EC2インスタンス)」や「ip(IPアドレス指定)」を指定できる点です。
aws elbv2 create-target-group \
--name my-nlb-target-group \
--protocol TCP \
--port 443 \
--target-type instance \
--vpc-id vpc-xxxxxxxxxxxxxxxxx \
--health-check-protocol TCP \
--health-check-port 443
# 2. NLB本体に「TCPリスナー(ポート443番)」を作成し、先ほどのターゲットグループへ紐付けます
# NLBのデフォルトの挙動として、TCPリスナーを作成すると自動的にソースIPの保存(透過的フォワーディング)が有効になります。
aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:loadbalancer/net/my-nlb/abcdef1234567890 \
--protocol TCP \
--port 443 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/my-nlb-target-group/fedcba9876543210
このように、特別な複雑なフラグを立てなくても、NLBのTCPリスナーを選ぶだけで、クライアントのIPアドレスはそのままバックエンドへと駆け抜けていきます。
—
⚠️ ちょっと待って! 運用時の重要な落とし穴(注意点)
「おっ、じゃあ全部NLBに任せれば万事解決だな!」と思ってしまうところですが、現場のプロとして、少しだけ注意すべきポイントもお伝えしておきますね。
それは、「自分自身のサーバーへアクセスする(リターンルート問題)」です。
バックエンドのサーバー(例えばEC2)から、同じNLBを経由して自分自身(あるいは同じVPC内の別のサーバー)へ通信を返そうとしたとき、クライアントのIPアドレスがそのまま残っているが故に、パケットのルーティングがループしたり、レスポンスが迷子になったりする現象が起きることがあります。
もし「あれ、パケットがうまく返っていかないぞ?」という壁にぶぶつかったら、以下のポイントを疑ってみてください。
- バックエンドサーバーのルーティングテーブルやセキュリティグループの設定に抜けはないか?
- クライアントIPを保持する必要がどうしてもない場合は、NLBではなくALBや他のアーキテクチャ(PrivateLink等)を検討する余地はないか?
こうした泥臭いネットワークの仕組みを一つずつクリアしていくのも、インフラエンジニアの醍醐味です!
—
まとめ
今回は、NLBにおけるTCPリスナー(ポート80番・443番・22番など)の透過的フォワーディングについて、現実の例えを交えながら解説しました。
- NLBは超高速なネットワークの案内係であること
- クライアントの送信元IPアドレスやポートを隠さず、そのままバックエンドへ届けてくれる(ソースIP保存)こと
- アクセスログの正確性や、SSH(ポート22番)などのセキュリティ制御において、この仕組みが非常に強力であること
クラウドやKubernetesのネットワークは、一見すると黒魔術のように思えるかもしれませんが、パケットの流れを一つずつイメージできれば怖くありません。
今日の解説が、あなたのインフラ学習や日々の業務の小さな「なるほど!」に繋がればとても嬉しいです。それでは、また次回の技術解説でお会いしましょう!
コメント