エアクロゼットのエンジニアのアインです。最近、私たちがアプリケーションロードバランサーからネットワークロードバランサーに切り替えしたばかりなので本ブログでその経験についてシェアさせていただきます。
ALBとNLBの概要
ALBとは
ALB(Application Load Balancer - アプリケーションロードバランサー)は第7層(OSIモデルのアプリケーション層)で動作するロードバランサーです。
ALBは、HTTP
およびHTTPS
プロトコルを使用したアプリケーションの負荷分散をサポートします。
ALBがサポートする主な機能は:
- Layer-7 Load balancing: EC2、マイクロサービスなどのターゲットへのHTTPおよびHTTPSリクエストを分散できます。
- HTTPSをサポートします。
- 転送: あるURLから別のURLへの転送ができます。
注意点としてはALB作る時に必ずALBに対応するSecurity Group
がを設定しないといけません。
NLBとは
NLB(Network Load Balancer - ネットワークロードバランサー)は第4層(OSIモデルのトランスポート層)で動作するロードバランサーです。
NLBがTCP, UDP, TCP_UDP, TLSをサポートしています。NLBがトラフィックの多いアプリを対応できるように設計されています。また非常に低いレイテンシで一秒あたり数百万リクエストが対策できます。
NLBがサポートする主な機能は:
- Layer-4 Load balancing: EC2、マイクロサービスなどのターゲットへのTCP及びUDPリクエストが分散できます。
- 低いレイテンシ。
- クライアントセッションターミネーションをサポートするし、ロードバランサーへのTLS終了タスクのオフロードができます。
NLBを作る時にSecurity Group
設定が不要となります。
ALBとNLBの違う点
ALB
が第7層に動作するからcontext
またcookieデータ
を結構気にするんですがNLB
が第4層に動作するから特にネットワーク周りの情報のみ気にしています。
他は:
- NLBがトランスポート層で動くから単なるリクエストをターゲットにフォワードするだけですけどALBがルーティングのためリクエストのヘッダの内容を見ています。
- NLBがトランスポート層で動作するのきっかけでアプリケーションの可用性をあまり担保できなくて、普通にはNLBがサーバーがICMP pingに応答できるかどうか、またはサーバーがTCPハンドシェイクを保証できるかどうかによって、この可用性を定義します。ALBが成功なHTTP GETリクエストを通じてアプリケーションの可用性が全然担保できます。
- 例として2つアプリケーションAとBが同じIPアドレスを使用すればNLBが2つのアプリが全く分別できないからNLBがオフラインアプリあるいはクラッシュ中アプリにリクエスト送る可能性があります。
現状のシステム
現状のエアクロゼットのアプリ、Webのインフラはこんな感じです。
システムの説明
エアクロはWebユーザとモバイルアプリのユーザ両方とも対応しているので2つホストがあり:
- www.air-closet.com: Web用ホスト
- api.air-closet.com: API用ホスト
2つホストが1つのみALBを向いています。ALBには次通りにルーティングしています:
-
HTTP
でアクセスする場合HTTPS
に転送します。 - ホスト
api.air-closet.com
だったらAPI EC2インスタンスと紐づくapi-target-group
にルーティングします。 - ホスト
www.air-closet.com
の場合はURIをチェックして/api
形式ならAPI EC2インスタンスと紐づくapi-target-group
にルーティングします。 - 残りとデフォルトはWeb EC2インスタンスと紐づく
web-target-group
にルーティングします。
具体的にはこれです。
出会った問題
モバイルアプリとWebの両方で訪問者数が増加するピーク時に、次の2つのことをやらないといけないです。
- ALBのアクセスキャパシティを増えるためAWSにELB暖機申請が必要でやらなければアプリとWebがめっちゃくちゃ遅くなるはずです。
- API EC2インスタンスを増強します。
基本的にはAPI EC2インスタンス増強のことが全然避けられないですがELB暖機申請がさようならできると思ってます。そのためにALBからNLBに切り替えようと考えております。理由としてはNLBの概要通り
NLBがトラフィックの多いアプリを対応できるように設計されています。また非常に低いレイテンシで一秒あたり数百万リクエストが対策できます。
ということなんです。
切り替え後のシステム
切り替えした後のシステムはこんな感じとなっております。
とても複雑に見えますよね? 順を追って説明しますのでご安心ください。
切り替え後の問題
インフラを変えると問題が発生する可能性が結構高いですよね。下記は我々が出会った問題です。
- どうやってWebからAPIに呼び出せる??? 元々WebからAPIにルーティングするはALBのボールですけどNLBがリクエストもらう際にすぐターゲットにフォワードするからルーティングを全然やらないです。
- どうやって
HTTP
からHTTPS
に転送できる???ALBには転送ルールが設定できるんですがNLBにとっては全然無理です。
問題を解決する
実際にはWeb EC2インスタンスの中にnginx
を設定しており、目的はnginxがReverse Proxy
としてWebに守ってあげます。
ですのでルーティングを全部nginx
に移動しようと思ってます。
どうやってWebからAPIに呼び出せる???
問題に対してはこんな感じでnginxを設定する
server {
listen 80 default_server;
location /api* {
proxy_pass https://api.air-closet.com;
}
}
そうすればAPIルーティングはこんな感じになっています。
WebからのAPI呼び出しのURLはhttps://www.air-closet.com/api/*
という形式になり、これらの呼び出しはNLBによって処理されず、EC2インスタンスに直接送信されて、ここで、nginxはURIが/api*
に類似していることを認識しているため、nginxはこの呼び出しをAPIホストhttps://api.air-closet.com
にフォワードします。
ではAPIルーティングはこれで対応済みです。これからHTTP
からHTTPS
に転送するのを見てみます。
Web用のNLBに2つリスナーを設定します。
-
TCP:80
-HTTP
プロトコル専用。 -
TLS:443
-HTTPS
プロトコル専用。
これらの各リスナーに対応するのは、次のターゲットグループです。
- TCP:81 -
http-web-target-group
: 81ポートにリッスンする - TCP:80 -
https-web-target-group
: 80ポートにリッスンする。
まとめするとこんな感じになっております。
NLBがトランスポート層に動作するからNLBと繋がってるターゲットグループのプロトコルは必ずTCPです。
上に書いている通り
実際にはWeb EC2インスタンスの中にnginxを設定しており、目的はnginxがReverse ProxyとしてWebに守ってあげます。
デフォルトにnginx
が80ポートにリッスンするんですが今回で言うと80ポートだけではなくて81ポートにもハンドリング必要なんでnginx
に81ポートにリッスンする設定を追加しようと思っております。こんな感じですね。
server {
listen 81 default_server;
return 301 https://web.com$request_uri;
}
説明するとリクエストが81ポートに来るならいつもHTTPS
に転送されています。
だから今のNLB、ターゲットグループとWeb EC2インスタンスはこんな感じになります。
簡単に説明するとユーザーがhttp://www.air-closet.com
にアクセスすると、リクエストはNLBによってhttp-web-target-group
に転送されて、このターゲットグループはまたリクエストをWeb EC2インスタンスにフォワードします。インスタンスの81ポートにリッスンしているnginxがリクエストを受け取りhttps://www.air-closet.com
にリダイレクトします。
ルーティングとリダイレクトは一旦大丈夫ですけどSecurity Group
はどうなるかなって思っております。今回はNLBを使ってるから全てのリクエストがEC2インスタンスに転送されるのでインスタンスが全てのIPアドレスからHTTPのリクエストをもらえるように設定が要ると考えていますので一応下の感じで設定しています。
簡単に言うと全てのIPアドレス(0.0.0.0/0)
からHTTP
とTCP
リクエストを80ポート
と81ポート
で受信しています。
システムの最終の形
システムの最終の形はこんな感じになっております。
旧システムと比べるとかなり複雑に見えますが、今のNLBがリクエストを転送するだけでルーティングとリダイレクトを担当してないからALBより暇となっております。ですからAWSに暖機申請が不要になります。
これからまた別の問題が発生するかもしれないと思いますが解決できればまた新しい知識が勉強になりますので引き続きよろしくおねがいします。
では今回のALBとNLBのブログが以上となります、また別のブログにお会いましょう。