固定IPでApplication Load Balancerを使ってみる

記事タイトルとURLをコピーする

どうも、こんにちはエンジニアの横倉です。最近、ひとり暮らしなのにソロキャンプにも興味が出てしまい、いよいよ孤高の存在として仕上がるのも近そうです。

さて、今回は固定IPでApplication Load Balancer を使ったAWS ブログを検証してみました。
固定IPをNetwork Load Balancerで提供し、ターゲットがApplication Load Balancer のローカルIPアドレスとなります。その動的IPアドレスの紐づけ処理をLambdaファンクションで行うことでApplication Load Balancerでも固定IPでサービス提供が出来ます。
元のブログ はこちらです。基本的に同じような内容ですがHTTPSでも動作するかを本記事では確認しています。

利用者へのサービス提供構成図



前提条件

  • NLB(Internal or External)で配置
  •  ALB (Internal) で配置
  • ACMで取得したSSL証明書をALBに付与
  • ALBとNLBを同じAvailability Zone環境に配置
  • NLBにはIPターゲットグループを用意(プロトコルはTCP)※LambdaがNLBとALBを紐付け
  • S3バケットを用意し、ALBのIPアドレス情報を保持
  • Lambdaに必要なIAMロール

Lmabda ファンクションの動き

  • ALBのIPアドレスを名前解決で取得、S3バケットに新IPリストを作成 or 更新
  • describe-target-health API を実行しNLBに登録されているターゲットリストのIPアドレス取得
  • S3から旧 IPアドレスリストを取得
  • CloudWatch ログストリームにIPアドレスリストを送る
  • 内部ALB IPアドレスの数をカウントしCloudWatchのメトリクスに反映
  • 新IPリストのアドレスが旧IPリストに無い場合はNLBに登録
  • 旧IPリストのアドレスが新IPリストにない場合はNLBから解除

Lambdaの連携図

 

セットアップ

IPポリシーの作成

サンプルポリシーは元のブログ一番下に記載されております。

 


IAMロールの作成

Lambda用のIAMロールを作成し、先程のポリシーを紐づけます。

Lambdaファンクションの作成

Pythonランタイム環境  Python2.7で用意し、
ハンドラー名 "populate_NLB_TG_with_ALB.lambda_handler" で登録します。
 Lambdaのzipファイル.で取得したZipファイルをアップロードしてください。


環境変数の設定

  • ALB_DNS_NAME : ALBのエンドポイント名
  • ALB_LISTENER : ALBのリスナーポート
  • S3_BUCKET : ALBのIPアドレスリストを保管するS3バケット
  • NLB_TG_ARN : NLBのターゲットグループのARN
  • MAX_LOOKUP_PER_INVOCATION : 名前解決の実行回数
  • INVOCATIONS_BEFORE_DEREGISTRATION : IPアドレスの登録解除間隔
  • CW_METRIC_FLAG_IP_COUNT : IPアドレスカウントのCloudWatchメトリクスの有効化


CloudWatchイベントの設定

CloudWatch イベントを作成します。スケジュールで1分間隔でLambdaファンクションを呼び出して設定完了です。

動作確認

CloudWatch LogsでLambdaの実行処理が確認できます。こちらにErrorが表示されていたら、設定の誤りなどが考えられます。

固定IPでアクセスも可能ですが、今回はSSLサーバー証明書を適応しているのでRoute53で名前解決しています。
PHPでサーバー変数を出力するようにしてアクセスしてみました。
REMOTE_ADDR はALBのIPアドレス、HTTP_X_FORWARDED_FORはNLBのIPアドレスでした。
察しの良い方はお気づきかもしれませんが接続元IPアドレスはNLBまでしかわかりませんでした。これはIPベースのNLBだとALBに渡される接続元IPアドレスはNLBのものになるためです。

ここで、ダメ元でNLBのターゲットグループの設定でProxy Protocol v2 を有効化してみました。しかし、ERR_SSL_PROTOCOL_ERRORが表示されてパケットが壊れてしまった模様です。

まとめ

固定IPを利用してALBでのサービス提供は可能でした。1分間隔でDNSをチェックするのでALBのIPアドレスが変わっても対応可能です。そしてLambdaのサンプルが用意されているので簡単にセットアップが可能です。※CloudFormationも用意されています

ただ、接続元IPアドレスをサーバー側で確認できないのでサービスを運用する上ではネックになりそうです。また、セッション維持などはNLB、ALBに依存してしまうのも懸念かもしれないですね。
ただ、仕組みとしては非常に面白いので、Lambdaを使って出来なかったことを出来るようにしていくチャレンジをもっとしてみたいですね。