Tại sao cần Load Balancer?
Khi bạn có nhiều servers, bạn cần một cách để phân phối traffic giữa chúng:
Không có Load Balancer:
User ──► Server 1 (quá tải, chậm)
User ──► Server 1 (crash!)
Server 2 (idle, lãng phí)
Server 3 (idle, lãng phí)
Có Load Balancer:
User ──► Load Balancer ──► Server 1 (33% traffic)
├──► Server 2 (33% traffic)
└──► Server 3 (33% traffic)
3 Loại Load Balancer trong AWS
| Loại | Layer | Use Case | Giá |
|---|---|---|---|
| ALB (Application) | 7 (HTTP/HTTPS) | Web apps, APIs, microservices | $$ |
| NLB (Network) | 4 (TCP/UDP) | Gaming, IoT, extreme performance | $$ |
| GLB (Gateway) | 3 (IP) | Firewalls, IDS/IPS, deep packet inspection | $$$ |
Application Load Balancer (ALB)
ALB hoạt động ở Layer 7 - hiểu HTTP/HTTPS protocol.
Tính năng chính
- Path-based routing:
/api/*→ API servers,/static/*→ S3 - Host-based routing:
api.example.com→ API,www.example.com→ Web - HTTP/2, WebSocket, gRPC support
- Authentication tích hợp (Cognito, OIDC)
- Sticky sessions (session affinity)
Architecture
Internet ──► ALB ──► Target Group 1 (/api/*)
│
├── EC2 Instance 1
├── EC2 Instance 2
└── Lambda Function
ALB ──► Target Group 2 (/static/*)
│
└── S3 Bucket
ALB ──► Target Group 3 (default)
│
├── ECS Container 1
└── ECS Container 2
Terraform: ALB
# Application Load Balancer
resource "aws_lb" "main" {
name = "${var.project_name}-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = var.public_subnet_ids
enable_deletion_protection = var.environment == "prod"
enable_http2 = true
# Cross-zone load balancing (miễn phí cho ALB)
enable_cross_zone_load_balancing = true
# Access logs
access_logs {
bucket = aws_s3_bucket.alb_logs.id
prefix = "alb"
enabled = true
}
tags = {
Name = "${var.project_name}-alb"
}
}
# Target Group
resource "aws_lb_target_group" "app" {
name = "${var.project_name}-app-tg"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
target_type = "instance" # hoặc "ip" cho Fargate, "lambda"
# Health check
health_check {
enabled = true
healthy_threshold = 2
unhealthy_threshold = 3
timeout = 5
interval = 30
path = "/health"
port = "traffic-port"
protocol = "HTTP"
matcher = "200-299"
}
# Sticky sessions
stickiness {
type = "lb_cookie"
cookie_duration = 3600 # 1 hour
enabled = true
}
# Deregistration delay
deregistration_delay = 30
tags = {
Name = "${var.project_name}-app-tg"
}
}
# HTTPS Listener
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.main.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.main.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
}
# HTTP to HTTPS redirect
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
# Path-based routing
resource "aws_lb_listener_rule" "api" {
listener_arn = aws_lb_listener.https.arn
priority = 100
action {
type = "forward"
target_group_arn = aws_lb_target_group.api.arn
}
condition {
path_pattern {
values = ["/api/*"]
}
}
}
# Host-based routing
resource "aws_lb_listener_rule" "admin" {
listener_arn = aws_lb_listener.https.arn
priority = 50
action {
type = "forward"
target_group_arn = aws_lb_target_group.admin.arn
}
condition {
host_header {
values = ["admin.${var.domain_name}"]
}
}
}
Network Load Balancer (NLB)
NLB hoạt động ở Layer 4 - chỉ xử lý TCP/UDP, không hiểu HTTP.
Khi nào dùng NLB?
- Extreme performance: Millions of requests/second
- Ultra-low latency: Microseconds vs milliseconds
- Static IP required: NLB có static IP
- Non-HTTP protocols: Gaming, IoT, custom protocols
- AWS PrivateLink: Expose service cho customers
Terraform: NLB
# Network Load Balancer
resource "aws_lb" "nlb" {
name = "${var.project_name}-nlb"
internal = false
load_balancer_type = "network"
subnets = var.public_subnet_ids
# Static IP với Elastic IP
enable_cross_zone_load_balancing = true # Tốn phí cho NLB!
tags = {
Name = "${var.project_name}-nlb"
}
}
# TCP Target Group
resource "aws_lb_target_group" "tcp" {
name = "${var.project_name}-tcp-tg"
port = 8080
protocol = "TCP"
vpc_id = var.vpc_id
target_type = "instance"
# Health check TCP
health_check {
enabled = true
healthy_threshold = 3
unhealthy_threshold = 3
interval = 10
port = "traffic-port"
protocol = "TCP"
}
# Connection termination
connection_termination = true
# Preserve client IP
preserve_client_ip = true
}
# TCP Listener
resource "aws_lb_listener" "tcp" {
load_balancer_arn = aws_lb.nlb.arn
port = 8080
protocol = "TCP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.tcp.arn
}
}
# TLS termination at NLB
resource "aws_lb_listener" "tls" {
load_balancer_arn = aws_lb.nlb.arn
port = 443
protocol = "TLS"
certificate_arn = aws_acm_certificate.main.arn
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.tcp.arn
}
}
Gateway Load Balancer (GLB)
GLB dùng cho virtual appliances - firewalls, IDS/IPS.
Internet ──► GLB ──► Firewall Appliance ──► GLB ──► Application
(inspect traffic)
Terraform: GLB
resource "aws_lb" "glb" {
name = "${var.project_name}-glb"
load_balancer_type = "gateway"
subnets = var.appliance_subnet_ids
tags = {
Name = "${var.project_name}-glb"
}
}
resource "aws_lb_target_group" "appliances" {
name = "${var.project_name}-appliances"
port = 6081
protocol = "GENEVE"
vpc_id = var.vpc_id
target_type = "instance"
health_check {
port = 80
protocol = "HTTP"
path = "/health"
}
}
So sánh ALB vs NLB
| Feature | ALB | NLB |
|---|---|---|
| Layer | 7 (HTTP) | 4 (TCP/UDP) |
| Latency | Milliseconds | Microseconds |
| Throughput | Millions RPS | Millions RPS |
| Static IP | Không | Có |
| Path routing | Có | Không |
| WebSocket | Có | Có |
| SSL offload | Có | Có |
| Cross-zone | Miễn phí | Tốn phí |
| Pricing | Per LCU | Per NLCU |
Health Checks
Health checks quyết định target nào healthy để nhận traffic.
Best Practices
health_check {
# Không check "/" - dùng dedicated health endpoint
path = "/health"
# Health endpoint nên kiểm tra:
# - Database connection
# - Critical dependencies
# - Disk space
# Tune thresholds dựa trên app
healthy_threshold = 2 # 2 successes = healthy
unhealthy_threshold = 3 # 3 failures = unhealthy
# Interval và timeout
interval = 30 # Check mỗi 30s
timeout = 5 # Timeout sau 5s
# Matcher cho ALB
matcher = "200-299" # Accept 2xx responses
}
Health Check Endpoint Example
# /health endpoint
from flask import Flask, jsonify
import psycopg2
app = Flask(__name__)
@app.route('/health')
def health():
checks = {
'database': check_database(),
'redis': check_redis(),
'disk': check_disk_space(),
}
all_healthy = all(c['status'] == 'ok' for c in checks.values())
return jsonify({
'status': 'healthy' if all_healthy else 'unhealthy',
'checks': checks
}), 200 if all_healthy else 503
def check_database():
try:
conn = psycopg2.connect(...)
conn.execute('SELECT 1')
return {'status': 'ok'}
except Exception as e:
return {'status': 'error', 'message': str(e)}
Cross-Zone Load Balancing
Không có Cross-Zone
AZ-a: ALB Node ──► Target 1 (50% traffic)
└► Target 2 (50% traffic)
AZ-b: ALB Node ──► Target 3 (100% traffic của AZ-b)
Nếu AZ-a có 2 targets và AZ-b có 1 target:
- Target 1: 25%
- Target 2: 25%
- Target 3: 50% ← Uneven!
Có Cross-Zone
AZ-a: ALB Node ───┬──► Target 1 (33%)
├──► Target 2 (33%)
└──► Target 3 (33%)
AZ-b: ALB Node ───┬──► Target 1 (33%)
├──► Target 2 (33%)
└──► Target 3 (33%)
Traffic phân phối đều!
resource "aws_lb" "main" {
enable_cross_zone_load_balancing = true # Khuyến nghị bật
}
Connection Draining (Deregistration Delay)
Khi target bị remove khỏi target group, connections hiện tại không bị cắt ngay:
resource "aws_lb_target_group" "app" {
deregistration_delay = 30 # Đợi 30s cho connections hoàn thành
# Đối với deployments, 30-60s thường đủ
# Đối với long-running connections, có thể cần nhiều hơn
}
SSL/TLS Best Practices
Security Policy
resource "aws_lb_listener" "https" {
# Chọn policy phù hợp
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
# Các policy thường dùng:
# - ELBSecurityPolicy-TLS13-1-2-2021-06: TLS 1.3 + 1.2, modern ciphers
# - ELBSecurityPolicy-TLS-1-2-2017-01: TLS 1.2 only
# - ELBSecurityPolicy-FS-1-2-Res-2020-10: Forward Secrecy
}
Multiple Certificates (SNI)
# Primary certificate
resource "aws_lb_listener" "https" {
certificate_arn = aws_acm_certificate.main.arn
}
# Additional certificates for other domains
resource "aws_lb_listener_certificate" "extra" {
listener_arn = aws_lb_listener.https.arn
certificate_arn = aws_acm_certificate.extra.arn
}
Practice Questions (SAA style)
1. Một ứng dụng cần expose REST API và cần routing based on URL path. Load balancer nào phù hợp nhất?
A. Network Load Balancer
B. Application Load Balancer
C. Gateway Load Balancer
D. Classic Load Balancer
Đáp án: B - ALB hỗ trợ path-based routing ở Layer 7.
2. Công ty cần static IP cho TCP-based application để whitelist trong firewall của partner. Giải pháp nào phù hợp?
A. ALB với Elastic IP
B. NLB (có static IP by default)
C. CloudFront với origin ALB
D. Global Accelerator với ALB
Đáp án: B - NLB cung cấp static IP addresses per AZ.
3. Làm thế nào để đảm bảo traffic được phân phối đều giữa tất cả targets ngay cả khi số target khác nhau giữa các AZs?
A. Use sticky sessions
B. Enable cross-zone load balancing
C. Use weighted target groups
D. Configure health check thresholds
Đáp án: B - Cross-zone load balancing phân phối traffic đều giữa tất cả targets bất kể AZ.
Bài tiếp theo: Cost Optimization Strategies - Reserved, Spot và Savings Plans.