こんにちは!エンタープライズクラウド部技術2課の日高です。
初めて、私がALBの設定をする際に「アイドルタイムアウト」や「Desync 緩和モード」などのALBやターゲットグループの属性が何を意味しているのか知らず困った経験があるので、同じ状況の方向けに本ブログでApplication Load Balancer(今後はALBと表記)とターゲットグループの属性について簡単にまとめてみます。
公式ドキュメントにもまとまっているので、気になる方はご覧ください。
※WAFのフェイルオープンの説明に誤りがありました。大変申し訳ございません。
2023年7月30日に該当箇所を修正いたしました。
ALBの概要
Elastic Load Balancing(ELB)の1種で、アプリケーション層で動作する負荷分散サービスになります。
ただ負荷分散を行うだけではなく、サーバの稼働状況をチェックするヘルスチェック機能や、セッションが続いている間は同じクライアントを同じサーバへ誘導する機能であるスティッキーセッションなど様々な機能を持ち合わせています。
※公式ドキュメントには以下のように書いています。
Application Load Balancer は、開放型システム間相互接続 (OSI) モデルの第 7 層であるアプリケーションレイヤーで機能します。ロードバランサーはリクエストを受信すると、優先度順にリスナールールを評価して適用するルールを決定し、ルールアクションのターゲットグループからターゲットを選択します。リスナールールを構成し、アプリケーショントラフィックのコンテンツに基づいて異なるターゲットグループにリクエストをルーティングできます。それぞれのターゲットグループでルーティングは個別に実行され、複数のターゲットグループに登録されているターゲットの場合も同じです。ターゲットグループレベルで使用するルーティングアルゴリズムを設定できます。デフォルトのルーティングアルゴリズムはラウンドロビンです。代わりに最小の未処理のリクエストを指定することもできます。
アプリケーションへのリクエストの流れを中断することなく、ニーズの変化に応じてロードバランサーに対してターゲットの追加と削除を行うことができます。Elastic Load Balancing はアプリケーションへのトラフィックが時間の経過とともに変化するのに応じてロードバランサーをスケーリングします。Elastic Load Balancing では、大半のワークロードに合わせた自動的なスケーリングが可能です。
登録済みのインスタンスのヘルス状態をモニタリングするために使用されるヘルスチェックを設定することで、ロードバランサーは正常なターゲットにのみリクエストを送信できます。
抜粋:
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/introduction.html
ALBの属性とは
ALBをマネジメントコンソールから作成する際に、「属性」は設定せずALB作成後に表示および編集をすることができます。
マネジメントコンソールから作成したALBを選択し、「属性」を選択することで設定の一覧を表示することができます。
今回はここの一覧にある「削除保護」や「Desync 緩和モード」、「アイドルタイム」など各設定値について書いていきいます。
削除保護
ALBの誤削除を防止する設定になり、有効と無効から選ぶことができます。(デフォルトでは無効)
削除保護を有効にしているALBを削除しようとすると以下のようなエラーがでて削除することできません。
削除保護を有効にしているALBを削除するには、属性の設定から削除保護を無効にしてから削除する必要があります。
本番環境でALBを使用する場合は誤削除を防ぐために有効をお勧めします。
TLS バージョンと暗号ヘッダー
有効にした場合、ロードバランサーは、クライアントリクエストに 2 つの TLS ヘッダー (x-amzn-tls-version および x-amzn-tls-cipher-suite) を追加してから、そのリクエストをターゲットに送信します。
x-amzn-tls-version ヘッダーには、クライアントとネゴシエートされた TLS プロトコルのバージョンに関する情報があり、x-amzn-tls-cipher-suite ヘッダーには、クライアントとの暗号スイート(様々な手段や方式を組み合わせた暗号通信システムにおいて、暗号アルゴリズムやハッシュ関数、鍵長などの設定の組み合わせ。)に関する情報があります。
ALBのヘッダーはクライアントとネゴシエートしたSSLの情報を持っているので、この機能を有効にすることで、ALB - クライアントブラウザ 間で通信し終わったSSLの情報をターゲットに送信することができます。
WAF のフェイルオープン
※説明に誤りがありました。大変申し訳ございません。(2023年7月30日に修正)
WAFのルールによってブロックされたリクエストが、指定された回数だけ続いた場合に、一時的にWAFを無効化しALBにルーティングを許可する機能になり、有効と無効から選ぶことができます。(デフォルトでは無効)
メリットとしてはWAFのルールによって誤って正当なトラフィックがブロックされた場合でも、サービスの可用性が確保されます。
デメリットとして WAFのルールによってブロックされたトラフィックが、悪意のある攻撃である場合はWAFが無効化されることによるセキュリティリスクが考えられます。
AWS WAFとALBを利用している際の動作を設定するパラメータになります。
デフォルト(無効の状態)では、ALBがWAFから応答を取得できない場合(WAFが障害等で無応答になるなどの場合)HTTP 500 エラー応答が返されALBにリクエストは転送されません。
WAF のフェイルオープンを有効にすることで、WAF に接続できない場合でもリクエストを素通しできる機能になります。
これにより、WAF に起因する問題が発生した場合でもエラー応答が返されることを防ぐことができます。
この機能のメリットとしては、WAFが障害等で無応答になった場合などにリクエストを素通しできるので、サービスの可用性を高めることができます。
メリットの裏返しになりますが、デメリットとして悪意のあるリクエストを通してしまう可能性があることです。
HTTP 500 エラー (waf-failed) の 抑制を必要とし、ブロック指定したリクエストが素通りする事を許容できる場合にこちらの機能を有効にすることをお勧めします。
ただ、それ以外の場合は無効で問題ないと考えています。
Desync 緩和モード
リクエストに対して、その中身を検査しRFC 7230に準拠しているか等の条件で分類することで、ロードバランサーがどのように処理するかを決定する機能になります。
こちらは「防御的」「最も厳格」「モニタリング」の3つから選択することができます。(デフォルトでは防御的)
※詳しくは以下をご覧ください
X-Forward-For ヘッダー
クライアントの IP アドレスを識別するのに役立つ機能で、「付加」「保持」「削除」から選択することができます。(デフォルトでは付加)
ロードバランサーは通常クライアントとサーバー間の通信をインターセプトするので、サーバー側のアクセスログにはロードバランサーのIPアドレスのみが含まれます。
この機能にて、各項目を選択すると以下のようになります。 ※参考資料:https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/x-forwarded-headers.html#x-forwarded-for
- 付加:X-Forwarded-For リクエストヘッダーがオリジナルリクエストが含まれていない場合、ロードバランサーはリクエスト値としてクライアント IP アドレスを持つリクエストヘッダーを作成する(リクエストヘッダーが含まれている際はそのまま保持する)
- 保持: X-Forwarded-For ヘッダーは、ターゲットに送信される前に変更されることはない
- 削除: X-Forwarded-For ヘッダーは、ターゲットに送信される前に削除される
クライアントIPを保持したいかどうかにより設定値を変更します。
ホストヘッダーを保持
リクエストの Host ヘッダーを保持するかどうかの設定になり、有効か無効かを選択できます。(デフォルトでは無効)
有効にすることでホストヘッダーが保持されます。無効時のALBの挙動を以下に記載します。 参考資料:
- リスナーポートがデフォルトポート (ポート 80 または 443) 以外のポートである場合、クライアントによってポート番号が追加されなければ、ホストヘッダーにポート番号を追加する
- リスナーポートがデフォルトポート (ポート 80 または 443) の場合、送信されるホストヘッダーにポート番号を追加しない。受信したホストヘッダーに含まれていたポート番号はすべて削除される
HTTP/2
プロトコルバージョン HTTP/2 を使用してロードバランサーにリクエストを送信するかどうかを指定する設定です。
有効か無効かを選択することができます。(デフォルトでは有効)
アイドルタイムアウト
ロードバランサーが、アイドル状態にあると判断した接続を閉じるまでの秒数を示すもので、1~4000秒の範囲内で指定できる。(デフォルトでは60秒)
アイドルタイムアウトの時間を設定する際に注意する必要があるのが、バランジング先の KeepAlive(クライアントとサーバー間での接続が有効であるかを確認するために一定周期で行う通信)になります。
例えば、ApacheやNginxを利用している場合KeepAliveの時間を設定できるKeepAlive Timeoutという設定値があります。
このKeepAlive Timeoutよりも大きい数値をアイドルタイムアウトで設定すると504 Gateway Timeoutエラーが起きてしまいます。
なぜならば、KeepAlive Timeout値がアイドルタイムアウトより短い場合、ALBとのTCPコネクションを切断してしまうからです。
ALB側では、既に切断されたTCPコネクションを利用しようとしてしまうので504 Gateway Timeoutエラーが起きてしまいます。
このことから、アイドルタイムアウトの秒数を決める際はKeepAliveの時間を考慮したうえで決める必要があります。
無効なヘッダーフィールドを削除
HTTP ヘッダー名が正規表現 [-A-Za-z0-9]+ (※)に準拠しているかどうかによりALBによりヘッダーが削除されるかターゲットにルーティングするかを決める設定になり、有効(削除)か無効(ターゲットにルーティング)かを選択できます。(デフォルトでは無効)
あくまで個人の解釈ではありますが、正規表現 [-A-Za-z0-9]+ に準拠していないヘッダーはWebサーバーに対しての攻撃の場合が多いと考えています。
このことから、この機能を有効にすることによりセキュリティ上にメリットがあると思います。
その一方で、作成したヘッダーが正規表現 [-A-Za-z0-9]+ 以外のものを使っている場合などは無効にすることがいいのではないでしょうか。
※正規表現のパターンの一つで、小文字のアルファベット(a-z)、大文字のアルファベット(A-Z)、数字(0-9)、ハイフン(-)のいずれかの文字が、1回以上繰り返された文字列にマッチします。
クライアントポートの保持
X-Forwarded-For ヘッダーで、クライアントがロードバランサーへの接続に使用した送信元ポートを保持するかどうかを示す設定で、有効か無効化を選択できます。(デフォルトでは無効です)
送信元ポートを保持したい要件があれば有効とします。
アクセスログ
有効にすることで、ALBに送信されるリクエストについての詳細情報(リクエストを受け取った時刻、クライアントの IP アドレス、レイテンシー、リクエストのパス、サーバーレスポンスなど)のアクセスログを5分ごとに発行します。
アクセスログは、S3に保存することができます。(デフォルトでは無効)
障害発生時などの切り分けに有効となりますので、アクセスログの有効化を推奨します。
※アクセスログの詳細については以下をご覧ください
ターゲットグループの属性とは
ALB同様にターゲットグループをマネジメントコンソールから作成する際に、「属性」は設定せずターゲットグループ作成後に表示および編集をすることができます。
マネジメントコンソールから作成したターゲットグループを選択し、「属性」を選択することで設定の一覧を表示することができます。
ここの一覧にある各設定値について書いていきいます。
登録解除の遅延
バックエンドに異常があっても処理中のリクエストがいきなり切断されないようにする機能です。
ターゲットグループのEC2インスタンスをALBから登録解除したり、ヘルスチェックが失敗した場合に、新規リクエストの割り振りは中止して、処理中のリクエストは指定した期間待つという挙動をします。
期間は0~3600秒から指定することができます。(デフォルトでは300秒)
スロースタート期間
新しく登録されたターゲットに、リクエストを送信し始めるまでの猶予期間です。(30~900 秒のいずれか、または 0秒 で無効)
デフォルトでは、ターゲットに初期ヘルスチェックを渡した後、すぐにリクエストを送信します。(デフォルトではスロースタート期間は0秒)
ユースケースとして、新規に起動したEC2インスタンスなどがリクエストを受け取る際に、CPUやメモリのリソースが十分に確保されていない状態でリクエストを受け取ること(過負荷になること)を防ぐためなどに使用されます。
ただし、スロースタート期間が長すぎると、ユーザーがウェブサイトの応答を待つ時間が長くなってしまう可能性があるため、設定には注意が必要です。
適切なスロースタート期間の設定は、アプリケーションの負荷特性やトラフィックパターンに応じて調整する必要があります。
ロードバランシングアルゴリズム
リクエストをルーティングするときに、ロードバランサーがターゲットグループ内からターゲットを選択する方法を指定できます。
「ラウンドロビン」「最小の未処理のリクエスト」の2つから選択することができます。(デフォルトではラウンドロビン)
ラウンドロビンは、リクエストを受け取ったALBが、バックエンドのEC2インスタンスに順番にリクエストを送信する方法です。
最小の未処理のリクエストは、新しいリクエストが到着したときにロードバランサーが未処理のリクエスト数が最も少ないターゲットにリクエストを送信する方法です。
適切なロードバランシング方式は、アプリケーションの負荷やスケーラビリティの要件によって異なります。
ラウンドロビンを利用すると良い例としては、サーバーへのリクエストが等しく分散される必要がある場合、サーバー間の処理時間に大きな差がない場合が挙げられます。
※注意点としては「最小の未処理のリクエスト」はスロースタート期間が0秒で設定されている場合のみ利用できます。
維持設定
セッションが続いている間は同じクライアントを同じサーバへ誘導する機能(スティッキーセッションと呼びます)で、有効と無効から選択することができます。(デフォルトでは無効)
また有効の場合は、1 秒~7 日間で維持期間を設定することができます。
アプリケーション側の要件などで、セッションを維持する必要がある場合に利用できると思います。
クロスゾーン負荷分散
ALBではクロスゾーン負荷分散はデフォルトで有効になっています。
クロスゾーン負荷分散とは、複数のAZで起動しているEC2インスタンスの台数に偏りがある場合でもトラフィックを均等にターゲットに分散する機能になります。
クロスゾーン負荷分散のメリットとしては、負荷を標準化できることになります。
デメリットとしては、AZ間で通信が発生するため、AZ間ネットワーク料金がかかることと多少の Latency が発生する可能性があるということです。
※ネットワーク料金
・AZまたぎの通信料(各方向 0.01 USD/GB)
同じ AWS リージョン内のアベイラビリティーゾーンをまたいだ、または VPC ピアリング接続間の Amazon EC2、Amazon RDS、Amazon Redshift、Amazon DynamoDB Accelerator (DAX)、Amazon ElastiCache インスタンス、または Elastic Network Interface で「受信 (イン)」/「送信 (アウト)」されるデータの転送料金は、各方向 0.01 USD/GB です
抜粋: https://aws.amazon.com/jp/ec2/pricing/on-demand/
ターゲットグループの正常要件
ターゲットグループを正常とみなす最小数または割合の指定と、指定されたしきい値を下回ったときにロードバランサーが実行するアクションを指定することができます。
デフォルトでは、ターゲットグループが1 つ以上の正常なターゲットを持っている限り、そのターゲットグループは正常であると見なされます。
設定するタイプは「統合設定」「詳細設定」の2つがあります。
統合設定
しきい値として、「最小限の正常なターゲット数」「最小限の正常なターゲットパーセンテージ」を設定することができます。
異常状態のアクションとして、 DNS アクションはDNS フェイルオーバーになりルーティングアクションはフェイルオープンになります。
詳細設定
しきい値として、「最小限の正常なターゲット数」「最小限の正常なターゲットパーセンテージ」をDNSとルーティングのそれぞれで設定することができます。
異常状態のアクションとして、統合設定と同様、 DNS アクションはDNS フェイルオーバーになりルーティングアクションはフェイルオープンになります。
まとめ
ALBの属性について簡単にですがまとめてみました。
本記事が誰かの助けになれば幸いです。
日高 僚太(執筆記事の一覧)
2024 Japan AWS Jr. Champions / 2024 Japan AWS All Certifications Engineers
EC部クラウドコンサルティング課所属。2022年IT未経験でSWXへ新卒入社。
記事に関するお問い合わせや修正依頼⇒ hidaka@serverworks.co.jp