コンテンツにスキップ

LB@AWSリソース

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. LB

ロードバランシングしたいプロトコルに合わせて、使用するロードバランサーを選択する。

LB名 OSI階層モデルのレイヤー リスナーが処理できるプロトコル ターゲット リクエストヘッダー (L7) パケットヘッダーのフィールド (L4) セキュリティグループ
ALB:Application Load Balancer L7 (アプリケーション層) HTTP、HTTPS、gRPC IPアドレス、AWS EC2インスタンス、Lambda URL、HTTPヘッダー ポート番号フィールド
NLB:Network Load Balancer L4 (トランスポート層) TCP、UDP、TLS IPアドレス、AWS EC2インスタンス、ALB 不可 IPアドレスフィールド、ポート番号フィールド 不可
GLB:Gateway Load Balancer L3 (ネットワーク層) 、L4 IP IPアドレス、AWS EC2インスタンス 不可 IPアドレスフィールド、ポート番号フィールド 不可
CLB:Classic Load Balancer L4L7 HTTP、HTTPS、TCP、SSL/TLS なし URL、HTTPヘッダー IPアドレスフィールド、ポート番号フィールド


02. ALB:Application Load Balancing

ALBとは

クラウドリバースプロキシサーバー、かつクラウドL7ロードバランサーとして働く。

AWS EC2へのリクエストをバランスよく分配することによって、サーバーへの負荷を緩和する。

aws_alb


02-02. セットアップ

コンソール画面の場合

▼ 設定項目と説明

設定項目 説明 補足
リスナー ALBに割り振るポート番号と受信するプロトコルを設定する。リバースプロキシサーバーかつロードバランサ-として、これらの通信をターゲットグループにルーティングする。
スキマー パブリックネットワークからのリクエストを待ち受けるか、あるいはプライベートネットワークからのリクエストを待ち受けるかを設定する。
セキュリティポリシー リクエストの送信者が使用するSSL/TLSプロトコルや暗号化方式のバージョンに合わせて、ALBが受信できるこれらのバージョンを設定する。 ・リクエストの送信者には、ブラウザ、APIにリクエストを送信する外部サービス、転送元のAWSリソース (例:CloudFrontなど) などを含む。
・- https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies
ルール リクエストのルーティングのロジックを設定する。
ターゲットグループ ルーティング時に使用するプロトコルと、宛先とするポート番号を設定する。 ターゲットグループ内のターゲットのうち、トラフィックはヘルスチェックがOKになっているターゲットにルーティングされる。
ヘルスチェック ターゲットグループに所属するプロトコルとアプリケーションのポート番号を指定して、定期的にリクエストを送信する。

▼ ターゲットグループ

ターゲットの指定方法 補足
AWS EC2インスタンス ターゲットはAWS EC2である必要がある。
IPアドレス ターゲットのパブリックIPアドレスは静的である必要がある。
Lambda ターゲットはLambdaである必要がある。


ルールの設定例

ユースケース ポート IF THEN
リクエストが80番ポートを指定した時に、443番ポートにリダイレクトしたい。 80 それ以外の場合はルーティングされないリクエスト ルーティング先:https://#{host}:443/#{path}?#{query}
ステータスコード:HTTP_301
リクエストが443番ポートを指定した時に、ターゲットグループに転送したい。 443 それ以外の場合はルーティングされないリクエスト 特定のターゲットグループ


ALBインスタンス

▼ ALBインスタンスとは

ALBの実体で、各ALBインスタンスが異なるグローバルIPアドレスを持つ。

複数のAZにルーティングするようにALBを設定した場合、各AZにALBインスタンスが1つずつ配置される。

alb-instance

▼ 割り当てられるIPアドレス

ALBに割り当てられるIPアドレスには、AWS VPCのものが適用される。

そのため、AWS EC2のセキュリティグループでは、AWS VPCのCIDRブロックを許可するように設定する必要がある。

▼ オートスケーリング

単一障害点にならないように、負荷が高まるとALBインスタンスが増えるように自動スケールアウトする仕組みを持つ。

500系ステータスの原因

▼ ALBのセキュリティグループ

AWS Route53からルーティングされるパブリックIPアドレスを受信できるようにしておく必要がある。

パブリックネットワークに公開するサイトであれば、IPアドレスは全ての範囲 (0.0.0.0/0::/0) にする。

社内向けのサイトであれば、社内のプライベートIPアドレスのみ (*.*.*.*/32) を許可する。


常時SSLのアプリケーションへのルーティング

▼ 問題

アプリケーションが常時SSLになっているアプリケーション (例:WordPress) の場合、ALBからアプリケーションにHTTPプロトコルでルーティングすると、HTTPSプロトコルへのリダイレクトループが発生してしまう。

常時SSLがデフォルトになっていないアプリケーションであれば、これは起こらない。

▼ Webサーバーにおける対処方法

ALBを経由したリクエストには、リクエストヘッダーにX-Forwarded-Protoヘッダーが付与される。

これには、ALBに対するリクエストのプロトコルの種類が文字列で代入されている。

これが『HTTPS』だった場合、Webサーバーに対するリクエストをHTTPSプロトコルであるとみなすように対処する。

これにより、アプリケーションに対するリクエストのプロトコルがHTTPSプロトコルとなる (こちらを行った場合は、アプリケーション側の対応不要) 。

*実装例*

SetEnvIf X-Forwarded-Proto https HTTPS=on

▼ アプリケーションにおける対処方法

ALBからEC2に対するリクエストのプロトコルをHTTPSと見なす

ALBを経由したリクエストには、リクエストヘッダーにHTTP_X_FORWARDED_PROTOヘッダーが付与される。

これには、ALBに対するリクエストのプロトコルの種類が文字列で代入されている。

そのため、もしALBに対するリクエストがHTTPSプロトコルだった場合は、ALBからアプリケーションに対するリクエストもHTTPSプロトコルであるとみなすように、index.phpに追加実装を実行する (こちらを行った場合は、Webサーバー側の対応不要) 。

*実装例*

<?php

// index.php
if (isset($_SERVER["HTTP_X_FORWARDED_PROTO"])
    && $_SERVER["HTTP_X_FORWARDED_PROTO"] == "https") {
    $_SERVER["HTTPS"] = "on";
}


負荷分散方式

▼ 負荷分散方式とは

ターゲットに対するリクエスト転送時の負荷分散方式を設定する。

▼ ラウンドロビン方式

受信したリクエストを、ターゲットに均等にルーティングする。

▼ 最小未処理リクエスト方式 (ファステスト)

受信したリクエストを、未処理のリクエスト数が最も少ないターゲットにルーティングする。

▼ スロースタート方式

受信したリクエストをルーティングする時に、スロースタート方式 (通過させるリクエストの数を少しずつ増加させる) で負荷分散を実施する。

リクエスト数の非常に多い高トラフィックなシステムで、起動直後のパフォーマンスが悪いアプリケーション (例:キャッシュに依存、コネクションプールの作成が必要、ウォームアップが必要なJVM言語製アプリケーション) にいきなり高負荷をかけないようにできる。


アクセスログ

▼ HTTPSの場合

HTTPSのアクセスログのフォーマットは以下の通りである。

https 2018-07-02T22:23:00.186641Z app/my-loadbalancer/50dc6c495c0c9188 192.168.131.39:2817 10.0.0.1:80 0.086 0.048 0.037 200 200 0 57 "GET https://www.example.com:443/ HTTP/1.1" "curl/7.46.0" ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067 "Root=1-58337281-1d84f3d73c47ec4e58577259" "www.example.com" "arn:aws:acm:us-east-2:123456789012:certificate/12345678-1234-1234-1234-123456789012" 1 2018-07-02T22:22:48.364000Z "authenticate,forward" "-" "-" "10.0.0.1:80" "200" "-" "-" TID_123456
https # リクエストタイプ
2018-07-02T22:23:00.186641Z
app/my-loadbalancer/50dc6c495c0c9188
192.168.131.39:2817 # クライアント側の情報
10.0.0.1:80  # サーバー側の情報
0.086
0.048
0.037
200 # ロードバランサーのレスポンスのステータスコード
200
0
57
"GET https://www.example.com:443/ HTTP/1.1"
"curl/7.46.0" # ユーザーエージェント
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2
arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067
"Root=1-58337281-1d84f3d73c47ec4e58577259"
"www.example.com"
"arn:aws:acm:us-east-2:123456789012:certificate/12345678-1234-1234-1234-123456789012"
1
2018-07-02T22:22:48.364000Z
"authenticate,forward"
"-"
"-"
"10.0.0.1:80"
"200" # サーバー側のレスポンスのステータスコード
"-"
"-"
TID_123456


03. CLB: Classic Load Balancer

キューを持ち、クラウドL4/L7ロードバランサーとして働く。

ALB、NLB、では元々実装されていたキューを廃止した経緯がある。


04. NLB:Network Load Balancer

クラウドL4ロードバランサーとして働く。