前書き
Terraformを使用してApplication Load Balancer (ALB)を構築しました。今回の構築に取り組む中で、負荷分散の基本的な概念についても理解が不足していた為、その学びも踏まえて、LD(ロードバランサー)の概要とALBの構築手順を以下に記載します。
ロードバランサーの概要(Load Balancer)
- 複数のサーバーにトラフィックを均等に分配し、システム全体のパフォーマンスを向上させる為の仕組み
| 機能 | 説明 |
|---|---|
| トラフィック(通信)の分散 | クライアントからのリクエストを複数のサーバー(バックエンド)に均等に割り振り、負荷集中を防止する |
| 可用性の向上 | サーバーの1つがダウンした場合、他の正常なサーバーに自動でトラフィックを切り替え、サービスを継続する |
| スケーラビリティ (負荷に応じて拡張・縮小できる柔軟性) |
負荷増加時にサーバーを追加し、ロードバランサーが自動的に新しいサーバーにトラフィックを分散する |
| 障害検知 (ヘルスチェック) |
定期的に各サーバーを監視し、正常なサーバーだけにリクエストを割り振る |
| SSL/TLSオフロード |
SSL/TLSの暗号化・復号化をロードバランサーで処理し、バックエンドの負荷を軽減する |
| 種類別ロードバランサー |
L4: ネットワーク層(IPやポート)で分散 L7: アプリケーション層(URLやHTTPヘッダ)で分散する |
用語説明
- オフロード : 重い作業を別の場所に分散して効率化
AWSのロードバランサーの種類
Application Load Balancer (ALB)
- L7(アプリケーション層) で動作
-
HTTP/HTTPSプロトコルに対応し、URLやHTTPヘッダーに基づくルーティングが可能 -
WebアプリケーションやAPIゲートウェイに適している
Network Load Balancer (NLB)
- L4(ネットワーク層) で動作
-
TCP/UDPトラフィックを高速に処理し、低レイテンシが必要なアプリケーションに最適 - ゲームサーバーや金融アプリケーションに適している
Gateway Load Balancer (GWLB)
- ネットワークアーキテクチャの一部として、サードパーティのセキュリティアプライアンスを統合する
- ファイアウォールや侵入防止システム(IPS) を構築する場合に使用
Classic Load Balancer (CLB)
- AWS初期から提供されているロードバランサーで、アプリケーション層とネットワーク層の両方をサポート
- 現在は、
ALBやNLBへの移行が推奨されている
特徴と機能
- 下記にAWSのロードバランサー機能・説明を記載する
| 機能 | 説明 |
|---|---|
| 自動スケーリング対応 | インスタンスを自動で追加・削除し、負荷に応じてスケールアウト・スケールインを実現する |
| ヘルスチェック | 定期的にバックエンドのサーバーの状態を確認し、正常なサーバーだけにトラフィック(通信)を転送する |
SSL/TLSオフロード |
暗号化・復号化をロードバランサーで処理し、バックエンドの負荷を軽減する |
| セキュリティグループ対応 | セキュリティ設定を制御し、特定のIPからのアクセスのみを許可するなどのポリシーを設定する |
参考資料
- [AWS公式] Application Load Balancer とは?
- [AWS公式] Network Load Balancer とは?
- [AWS公式] Gateway Load Balancer とは?
- [AWS公式] Classic Load Balancer の設定
ターゲットグループの概要
- Elastic Load Balancing(ELB)の一部で、ロードバランサーからのリクエストを受け取るサーバーやサービスのグループを管理している
- リクエストをどのように分散するかのルールを定義し、ロードバランサーの背後にある複数のターゲットに負荷を均等に分散する役割を果たす
特徴と機能
- 下記にAWSのターゲットグループの機能・説明を記載する
| 項目 | 説明 |
|---|---|
| ターゲットの種類 |
EC2、ECS、Lambda、IPアドレス等をターゲットに指定可能 |
| プロトコルとポート | 各ターゲットごとに プロトコル(HTTP, HTTPS, TCP, UDP等)とポートを設定可能 |
| ヘルスチェック | 各ターゲットの 正常性を監視 し、障害が発生したターゲットへのトラフィック(通信)を停止させる |
| ターゲットの登録方法 |
IPアドレスでの直接登録、EC2の登録、またはAuto Scalingで管理可能 |
| ターゲットグループの種類 |
Application Load Balancer(ALB)、Network Load Balancer(NLB)、Gateway Load Balancer(GLB)などに対応したターゲットグループが存在する |
| スティッキネス(Stickiness) | ユーザーのリクエストを同じターゲットに維持する設定。セッションを一貫させる用途に使用する |
| 重み付きルーティング | 各ターゲットに 異なる重み(ウェイト) を設定し、特定のターゲットに多くのリクエストを送ることが可能 |
| ターゲットの状態管理 |
initial, healthy, unhealthy, draining等のステータスで各ターゲットの状態を管理 |
参考資料
- [AWS公式] Application Load Balancer のターゲットグループ
- [AWS公式] Application Load Balancer ターゲットグループのヘルスチェック
- [AWS公式] Application Load Balancer のセキュリティポリシー
Terraformの構築
Application Load Balancer(ALB)
alb.tf
resource "aws_lb" "test_alb" {
name = "test-alb"
internal = false
idle_timeout = 60
enable_deletion_protection = true
enable_cross_zone_load_balancing = true
subnets = [
# サブネット ID
]
security_groups = [
# セキュリティーグループ ID
]
tags = {
Name = "test-alb"
}
}
aws_lb内で使用しているメソッドと説明
| メソッド | 説明 |
|---|---|
| internal | ロードバランサーを 内部用(VPC内限定) にするか、パブリック(インターネットからアクセス可能)にするかを制御する。falseの場合、外部からのアクセスが可能なパブリックロードバランサーになる |
| idle_timeout | クライアントとの無通信状態が続く最大秒数を設定する。指定時間(今回の場合は60秒)が経過すると接続が切断される |
| enable_deletion_protection | 誤削除を防止する為の削除保護を有効化する。有効にすると、手動でこの保護を解除するまでリソースを削除出来なくなる |
| enable_cross_zone_load_balancing | 複数の可用ゾーン(AZ)間でトラフィックを均等に分散 する様にする。これにより、負荷分散の効率が向上し、各ゾーンのトラフィックがバランスよく処理される |
警告
HTTPSで接続する場合、SSL/TLS証明書が必要になる為、DNSの構築が必要となる。その為、certificate_arnの部分を別途Terraformで構築する必要がある
alb_listener.tf
# 疎通テスト用のリスナールール
resource "aws_lb_listener" "test_http_alb_listener" {
# HTTPでのアクセスを受け付ける
port = "80"
protocol = "HTTP"
load_balancer_arn = aws_lb.test_alb.arn
# "ok" という固定レスポンスを設定する
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
status_code = "200"
message_body = "ok"
}
}
}
# EC2やECSに接続する際のリスナールール
resource "aws_lb_listener" "test_https_alb_listener" {
load_balancer_arn = aws_lb.test_alb.arn
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-3-2021-06"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.test_tg.arn
order = 1
}
# 使用するSSL/TLS証明書
certificate_arn = # aws_acm_certificateのarn
}
aws_lb_listener内で使用しているメソッドと説明
疎通テスト用のリスナールール
| メソッド | 説明 |
|---|---|
| port | ロードバランサーが待ち受ける ポート番号を指定する。今回の場合は、HTTPトラフィック用の 80 番ポートを設定している |
| protocol | 通信プロトコルを指定する。今回の場合は、HTTPプロトコルを使用している |
| load_balancer_arn | 対象のロードバランサー(ALB)のARNを指定する |
| default_action | デフォルトのアクションを定義する。指定した条件に一致するリクエストがない場合、このアクションが自動で実行される |
| fixed_response | クライアントに返す 固定レスポンス を設定する |
| content_type | レスポンスのコンテンツタイプを指定する。今回の場合は、text/plainを指定する |
| status_code | レスポンスに含まれる HTTP ステータスコード を指定する |
| message_body | レスポンスボディとしてクライアントにokという固定メッセージを返す |
EC2やECSに接続する際のリスナールール
| メソッド | 説明 |
|---|---|
| port | ロードバランサーが待ち受ける443番ポートを指定する。これはHTTPSトラフィックに使用される |
| protocol |
HTTPSプロトコル を使用して暗号化された通信を行う |
| ssl_policy |
SSL/TLSのポリシー を指定する。この場合、ELBSecurityPolicy-TLS13-1-3-2021-06ポリシーを適用して、TLS 1.3を強制する |
| default_action | デフォルトのアクションとして、リクエストを ターゲットグループに転送 (forward)する |
| target_group_arn | 転送先のターゲットグループ のARNを指定する |
| order | このアクションの実行順序を指定する。1を指定すると最優先で実行される |
| certificate_arn |
HTTPS通信で使用するSSL/TLS証明書 のARNを指定する。証明書のTerraformが構築されている場合は、aws_acm_certificateから取得したARNを使用する |
Target Group(TG)
- EC2やECSに通信を送る際のターゲットグループ
疎通テストを行うのみでターゲットグループの構築は不要
target_group.tf
resource "aws_lb_target_group" "test_tg" {
name = "test-tg"
vpc_id = # VPC ID
target_type = "ip"
port = 80
protocol = "HTTP"
deregistration_delay = 300
health_check {
path = "/test.txt"
healthy_threshold = 5
unhealthy_threshold = 2
timeout = 5
interval = 30
matcher = 200
port = "traffic-port"
protocol = "HTTP"
}
depends_on = [aws_lb.test_alb]
lifecycle {
create_before_destroy = true
}
}
aws_lb_target_group内で使用しているメソッドと説明
| メソッド | 説明 |
|---|---|
name |
ターゲットグループの名前を指定する |
vpc_id |
ターゲットグループが関連付けられるVPCのIDを指定する |
target_type |
ターゲットの種類を指定する (instance, ip, lambda) |
port |
ターゲットグループがリッスンするポート番号を指定する |
protocol |
通信プロトコルをHTTP または HTTPSのどちらかを指定する。他には、TCP、UDP、TLS、GENEVEがある |
deregistration_delay |
ターゲットの登録解除後に待機する秒数を指定する |
depends_on |
リソースの依存関係を設定する |
lifecycle |
リソースの作成・破棄時の挙動を制御する |
create_before_destroy |
リソースを新規作成してから既存リソースを削除する挙動を指定する |
health_check内で使用しているメソッドと説明
| メソッド | 説明 |
|---|---|
path |
ヘルスチェックでリクエストを送信するパスを指定する |
healthy_threshold |
ターゲットを「ヘルシー」と判定するために必要な成功チェック数を指定 |
unhealthy_threshold |
ターゲットを「アンヘルシー」と判定するために必要な失敗チェック数を指定 |
timeout |
タイムアウトまでの秒数を指定する |
interval |
ヘルスチェックを実行する間隔(秒単位)を指定する |
matcher |
ヘルスチェックの成功を判定するステータスコードを指定する |
port |
ヘルスチェックで使用するポートを指定する |
protocol |
ヘルスチェックの通信プロトコルを指定する |
Security Group(SG)
- 今回の構築では、
HTTPSのインバウンドは不要 - セキュリティーグループに関しては、メソッドの説明を割愛する
- セキュリティーグループの基本的な仕組みは過去に記載しましたので、下記を参照して下さい
セキュリティーグループのインバウンドで設定するソースとアウトバウンドで設定する送信先の役割について理解した事をまとめた
security_group.tf
resource "aws_security_group" "test_alb_sg" {
name = "test-alb"
description = "test alb"
vpc_id = # VPC ID
# インバウンド
# HTTP
ingress {
description = "HTTP from VPC"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# HTTPS
ingress {
description = "HTTPS from VPC"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# アウトバンド
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "test-alb-sg"
}
}
Terrformの参考資料
- [HashiCorp] aws_lb
- [HashiCorp] aws_lb_listener
- [HashiCorp] aws_lb_target_group
- [HashiCorp] aws_security_group
- [Terraformで構築するAWS] ALB
まとめ
今回は、ALBの構築を行いました。ALBに関して改め理解出来たので、今回学んだ事を活し、引き続きインフラの構築を頑張りたいと思いました。