AWS

AWS Load Balancer 완전 비교 가이드

Somaz 2026. 1. 27. 00:00
728x90
반응형

Overview

AWS는 다양한 유형의 로드 밸런서를 제공하여 애플리케이션의 가용성, 확장성, 보안을 향상시킨다. 각 로드 밸런서는 고유한 특성과 최적화된 사용 사례를 가지고 있어, 올바른 선택이 시스템 성능과 비용에 큰 영향을 미친다.

 

본 가이드에서는 AWS의 4가지 주요 로드 밸런서(ALB, NLB, CLB, Gateway Load Balancer)의 특징, 성능, 사용 사례를 심층 분석하고, Terraform을 활용한 실제 구현 방법과 비용 최적화 전략을 제시한다.

 

이를 통해 여러분의 아키텍처에 가장 적합한 로드 밸런서를 선택하고 효율적으로 운영할 수 있는 실무 지식을 제공하겠다.

 

 

 

📅 관련 글

2022.02.13 - [AWS] - AWS IAM (Identity and Access Management) 개요 및 설정 방법

2022.02.07 - [AWS] - AWS EC2 인스턴스 생성

2022.02.13 - [AWS] - AWS S3 (Simple Storage Service) 개요 및 활용 방법

2023.03.30 - [AWS] - AWS Secrets Manager란?(OAuth, SSO)

2023.03.29 - [AWS] - AWS CLI 정리

2023.03.28 - [AWS] - AWS IAM이란?

2023.03.28 - [AWS] - AWS S3 권한이란?

2023.03.28 - [AWS] - AWS S3란?(개념, 속성)

2023.03.30 - [AWS] - AWS Cloudfront란? / Canary 및 Blue-Green 배포

2023.04.03 - [AWS] - AWS VPC란?

2023.05.26 - [AWS] - AWS IRSA(IAM Roles for Service Accounts)란?

2024.11.07 - [AWS] - AWS Ingress Annotations 정리

2024.11.04 - [AWS] - AWS Assume Role이란?

2024.11.16 - [AWS] - AWS Network ACL vs Security Group

2024.11.21 - [AWS] - ALB access Log 활성화 → S3 권한 설정 및 로그 저장

2024.11.24 - [AWS] - EKS Pod Identity Addon

2024.11.27 - [AWS] - AWS DynamoDB란?

2025.01.03 - [AWS] - AWS DynamoDB Local 설치

2025.09.02 - [AWS] - AWS EFS와 Kubernetes를 활용한 영구 스토리지 구축 가이드

2025.09.05 - [AWS] - AWS CDN 구축 가이드: Kubernetes + AWS CloudFront로 API와 정적 파일 서빙 최적화

2025.09.05 - [AWS] - AWS 네트워크 연결 방식 완전 비교: VPC Peering vs Transit Gateway vs VPN

2025.09.04 - [AWS] - AWS Load Balancer 완전 비교 가이드

 

 

 


 

 

AWS Load Balancer 완전 비교 가이드

 

 

 

1. AWS Load Balancer 종류별 특징

 

Application Load Balancer (ALB)

Layer 7 HTTP/HTTPS 트래픽을 위한 고급 로드 밸런서

 

 

핵심 특징

  • HTTP/HTTPS 프로토콜 지원 (Layer 7)
  • 경로 기반, 호스트 기반 라우팅
  • 웹소켓 및 HTTP/2 지원
  • 컨테이너 및 람다 함수 지원
  • SSL/TLS 터미네이션
  • WAF 통합 가능
  • 고급 헬스체크 옵션

 

성능 특성

  • 처리량: 초당 수십만 요청 처리 가능
  • 지연시간: 평균 1-5ms 추가 레이턴시
  • 자동 확장: 트래픽에 따른 동적 확장

 

 

 

Network Load Balancer (NLB)

Layer 4 고성능 TCP/UDP 트래픽 로드 밸런서

 

 

핵심 특징

  • TCP, UDP, TLS 프로토콜 지원 (Layer 4)
  • 초고성능 및 초저지연
  • 고정 IP 주소 지원
  • Preserve client IP
  • Cross-zone 로드 밸런싱
  • PrivateLink 엔드포인트 지원

 

성능 특성

  • 처리량: 초당 수백만 요청 처리 가능
  • 지연시간: 100 마이크로초 미만
  • 연결 처리: 초당 수백만 동시 연결

 

 

Classic Load Balancer (CLB)

레거시 EC2-Classic을 위한 기본 로드 밸런서

 

 

핵심 특징

  • Layer 4 (TCP) 및 Layer 7 (HTTP/HTTPS) 지원
  • EC2-Classic 및 VPC 지원
  • 기본적인 헬스체크
  • SSL 터미네이션
  • 제한된 라우팅 기능

 

현재 상태

  • AWS에서 사용 중단 권장
  • 기존 워크로드 유지보수 목적으로만 사용
  • 신규 프로젝트에서는 ALB 또는 NLB 권장

 

 

Gateway Load Balancer (GWLB)

네트워크 보안 어플라이언스를 위한 투명한 로드 밸런서

 

 

핵심 특징

  • Layer 3 (IP) 레벨에서 동작
  • GENEVE 프로토콜 사용
  • 투명한 네트워크 게이트웨이
  • 써드파티 보안 어플라이언스 통합
  • VPC 엔드포인트 서비스 지원

 

성능 특성

  • 처리량: 수백만 패킷 처리 가능
  • 지연시간: 극도로 낮은 레이턴시
  • 확장성: 자동 확장 및 고가용성

 

 


 

 

 

2. 사용 사례별 최적 선택 가이드

 

ALB 최적 사용 사례

  • 웹 애플리케이션 및 API 서비스
  • 마이크로서비스 아키텍처
  • 컨테이너 기반 애플리케이션 (ECS, EKS)
  • 서버리스 아키텍처 (Lambda)
  • 경로 기반 라우팅이 필요한 경우
  • 고급 보안 기능 (WAF) 연동
  • A/B 테스팅 및 카나리 배포

 

실제 시나리오 예시

  • 전자상품몰에서 `/api/products` 는 상품 서비스로, `/api/users` 는 사용자 서비스로 라우팅
  • React 프론트엔드와 Node.js API 서버 간 로드 밸런싱
  • 쿠버네티스 클러스터의 서비스 노출

 

 

 

NLB 최적 사용 사례

  • 초고성능이 필요한 애플리케이션
  • 게임 서버 및 실시간 스트리밍
  • IoT 및 센서 데이터 처리
  • 고정 IP가 필요한 서비스
  • TCP/UDP 기반 애플리케이션
  • 온프레미스와의 VPN/DirectConnect 연결
  • 극도로 낮은 지연시간이 요구되는 서비스

 

실제 시나리오 예시

  • 온라인 게임의 게임 서버 클러스터
  • 금융 거래 시스템의 실시간 데이터 처리
  • 화상회의 시스템의 미디어 스트리밍 서버

 

 

 

 

Gateway Load Balancer 최적 사용 사례

  • 방화벽 어플라이언스 배포
  • IDS/IPS 시스템 통합
  • DDoS 보호 솔루션
  • 네트워크 모니터링 및 분석
  • 써드파티 보안 도구 통합
  • 네트워크 가상화 환경

 

실제 시나리오 예시

  • Palo Alto Networks 방화벽을 통한 트래픽 검사
  • Fortinet 보안 어플라이언스 클러스터 운영
  • 네트워크 패킷 분석 및 로깅 시스템

 

 

 


 

 

 

 

3. Terraform 구현 예제 및 Kubernetes 사용 시 구현 예제

 

ALB Terraform 구현

# Application Load Balancer
resource "aws_lb" "main_alb" {
  name               = "main-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb_sg.id]
  subnets            = var.public_subnet_ids

  enable_deletion_protection = false
  
  access_logs {
    bucket  = aws_s3_bucket.alb_logs.id
    prefix  = "alb-logs"
    enabled = true
  }

  tags = {
    Environment = var.environment
    Name        = "main-alb"
  }
}

# Target Group
resource "aws_lb_target_group" "web_tg" {
  name     = "web-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id
  
  health_check {
    enabled             = true
    healthy_threshold   = 2
    interval            = 30
    matcher             = "200"
    path                = "/health"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = 5
    unhealthy_threshold = 2
  }
  
  target_type = "instance"
  
  tags = {
    Name = "web-target-group"
  }
}

# Listener
resource "aws_lb_listener" "web_listener" {
  load_balancer_arn = aws_lb.main_alb.arn
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS-1-2-2017-01"
  certificate_arn   = var.ssl_certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.web_tg.arn
  }
}

# Path-based routing
resource "aws_lb_listener_rule" "api_rule" {
  listener_arn = aws_lb_listener.web_listener.arn
  priority     = 100

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.api_tg.arn
  }

  condition {
    path_pattern {
      values = ["/api/*"]
    }
  }
}

# Security Group
resource "aws_security_group" "alb_sg" {
  name_prefix = "alb-sg"
  vpc_id      = var.vpc_id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    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 = "alb-security-group"
  }
}
 
 
 
 
 

NLB Terraform 구현

# Network Load Balancer
resource "aws_lb" "main_nlb" {
  name               = "main-nlb"
  internal           = false
  load_balancer_type = "network"
  subnets            = var.public_subnet_ids

  enable_deletion_protection = false
  
  # Static IP allocation
  subnet_mapping {
    subnet_id     = var.public_subnet_ids[0]
    allocation_id = aws_eip.nlb_eip_1.id
  }
  
  subnet_mapping {
    subnet_id     = var.public_subnet_ids[1]
    allocation_id = aws_eip.nlb_eip_2.id
  }

  tags = {
    Environment = var.environment
    Name        = "main-nlb"
  }
}

# Elastic IPs for static IPs
resource "aws_eip" "nlb_eip_1" {
  vpc = true
  tags = {
    Name = "nlb-eip-1"
  }
}

resource "aws_eip" "nlb_eip_2" {
  vpc = true
  tags = {
    Name = "nlb-eip-2"
  }
}

# Target Group for TCP
resource "aws_lb_target_group" "tcp_tg" {
  name     = "tcp-tg"
  port     = 8080
  protocol = "TCP"
  vpc_id   = var.vpc_id
  
  health_check {
    enabled             = true
    healthy_threshold   = 2
    interval            = 30
    port                = "traffic-port"
    protocol            = "TCP"
    timeout             = 6
    unhealthy_threshold = 2
  }
  
  target_type = "instance"
  
  # Preserve client IP
  preserve_client_ip = true
  
  tags = {
    Name = "tcp-target-group"
  }
}

# Listener for TCP
resource "aws_lb_listener" "tcp_listener" {
  load_balancer_arn = aws_lb.main_nlb.arn
  port              = "80"
  protocol          = "TCP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.tcp_tg.arn
  }
}

 

 

 

 

Gateway Load Balancer Terraform 구현

# Gateway Load Balancer
resource "aws_lb" "gateway_lb" {
  name               = "gateway-lb"
  load_balancer_type = "gateway"
  subnets            = var.private_subnet_ids

  enable_deletion_protection = false

  tags = {
    Name = "gateway-load-balancer"
  }
}

# Target Group for GWLB
resource "aws_lb_target_group" "gwlb_tg" {
  name     = "gwlb-tg"
  port     = 6081
  protocol = "GENEVE"
  vpc_id   = var.vpc_id
  
  health_check {
    enabled             = true
    healthy_threshold   = 2
    interval            = 30
    port                = "80"
    protocol            = "HTTP"
    path                = "/health"
    timeout             = 5
    unhealthy_threshold = 2
  }
  
  target_type = "instance"
  
  tags = {
    Name = "gwlb-target-group"
  }
}

# GWLB Listener
resource "aws_lb_listener" "gwlb_listener" {
  load_balancer_arn = aws_lb.gateway_lb.arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.gwlb_tg.arn
  }
}

# VPC Endpoint Service
resource "aws_vpc_endpoint_service" "gwlb_endpoint_service" {
  acceptance_required        = false
  gateway_load_balancer_arns = [aws_lb.gateway_lb.arn]
  
  tags = {
    Name = "gwlb-endpoint-service"
  }
}

# VPC Endpoint
resource "aws_vpc_endpoint" "gwlb_endpoint" {
  vpc_id              = var.vpc_id
  service_name        = aws_vpc_endpoint_service.gwlb_endpoint_service.service_name
  vpc_endpoint_type   = "GatewayLoadBalancer"
  subnet_ids          = var.private_subnet_ids

  tags = {
    Name = "gwlb-endpoint"
  }
}

 

 

 

 

고급 ALB 구성 예제 (컨테이너 환경)

# ECS Service용 ALB 타겟 그룹
resource "aws_lb_target_group" "ecs_tg" {
  name                 = "ecs-service-tg"
  port                 = 80
  protocol             = "HTTP"
  vpc_id               = var.vpc_id
  target_type          = "ip"
  deregistration_delay = 30
  
  health_check {
    enabled             = true
    healthy_threshold   = 2
    interval            = 15
    matcher             = "200,404"
    path                = "/health"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = 5
    unhealthy_threshold = 3
  }
  
  tags = {
    Name = "ecs-target-group"
  }
}

# Lambda 함수용 타겟 그룹
resource "aws_lb_target_group" "lambda_tg" {
  name        = "lambda-tg"
  target_type = "lambda"
  
  health_check {
    enabled             = true
    healthy_threshold   = 2
    interval            = 30
    matcher             = "200"
    path                = "/health"
    timeout             = 5
    unhealthy_threshold = 2
  }
}

# Lambda 권한
resource "aws_lambda_permission" "allow_alb" {
  statement_id  = "AllowExecutionFromALB"
  action        = "lambda:InvokeFunction"
  function_name = var.lambda_function_name
  principal     = "elasticloadbalancing.amazonaws.com"
  source_arn    = aws_lb_target_group.lambda_tg.arn
}

 

 

Kubernetes Ingress 사용하여 구현

 

AWS Load Balancer Controller 설치

# Helm을 통한 AWS Load Balancer Controller 설치
helm repo add eks https://aws.github.io/eks-charts
helm repo update

helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=your-cluster-name \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller

 

 

기본 Ingress 구성 예제

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app-ingress
  namespace: default
  annotations:
    # ALB 생성 지정
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    
    # SSL/HTTPS 설정
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:123456789012:certificate/your-cert-arn
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    
    # 로드 밸런서 이름 지정
    alb.ingress.kubernetes.io/load-balancer-name: web-app-alb
    
    # 헬스체크 설정
    alb.ingress.kubernetes.io/healthcheck-path: /health
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: "30"
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: "5"
    alb.ingress.kubernetes.io/healthy-threshold-count: "2"
    alb.ingress.kubernetes.io/unhealthy-threshold-count: "3"
    
    # External DNS 통합
    external-dns.alpha.kubernetes.io/hostname: webapp.example.com
  labels:
    app: web-app
spec:
  ingressClassName: alb
  rules:
  - host: webapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-app-service
            port:
              number: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-app-service
  namespace: default
spec:
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 8080
  type: ClusterIP

 

 

 

다중 서비스 라우팅 예제

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: microservices-ingress
  namespace: production
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:123456789012:certificate/your-cert-arn
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/load-balancer-name: microservices-alb
    
    # WAF 연결
    alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:us-west-2:123456789012:regional/webacl/your-waf/12345
    
    # 태그 지정
    alb.ingress.kubernetes.io/tags: Environment=production,Team=backend
  labels:
    app: microservices
spec:
  ingressClassName: alb
  rules:
  - host: api.example.com
    http:
      paths:
      # 사용자 서비스
      - path: /api/users
        pathType: Prefix
        backend:
          service:
            name: user-service
            port:
              number: 80
      # 상품 서비스
      - path: /api/products
        pathType: Prefix
        backend:
          service:
            name: product-service
            port:
              number: 80
      # 주문 서비스
      - path: /api/orders
        pathType: Prefix
        backend:
          service:
            name: order-service
            port:
              number: 80
      # 기본 경로
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

 

 

 

공유 ALB 사용 예제 (제공해주신 파일 기반)

# 첫 번째 애플리케이션
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: alpha-game-app
  namespace: gameservice
  annotations:
    # 공유 ALB 그룹 설정
    alb.ingress.kubernetes.io/group.name: luckyday-shared-alb
    alb.ingress.kubernetes.io/group.order: "10"
    
    # 기본 ALB 설정
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/load-balancer-name: luckyday-shared-alb-loadbalancer
    
    # SSL/HTTPS 설정
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-central-1:010339071704:certificate/14eeaf2b-e34e-416d-a1bb-fbfb18c9f59b
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    
    # External DNS
    external-dns.alpha.kubernetes.io/hostname: alpha-game.luckyday.soulssvc.com
    
    # ArgoCD 추적
    argocd.argoproj.io/tracking-id: alpha-luckyday-game:networking.k8s.io/Ingress:luckyday/alpha-luckyday-game
  labels:
    app.kubernetes.io/instance: alpha-luckyday-game
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: alpha-luckyday-game
    app.kubernetes.io/version: 1.16.0
    helm.sh/chart: base-aws-0.1.0
spec:
  ingressClassName: alb
  rules:
  - host: alpha-game.luckyday.soulssvc.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: alpha-luckyday-game
            port:
              number: 80

---
# 두 번째 애플리케이션 (같은 ALB 공유)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: beta-game-app
  namespace: gameservice
  annotations:
    # 동일한 ALB 그룹 사용
    alb.ingress.kubernetes.io/group.name: luckyday-shared-alb
    alb.ingress.kubernetes.io/group.order: "20"
    
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/load-balancer-name: luckyday-shared-alb-loadbalancer
    
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-central-1:010339071704:certificate/14eeaf2b-e34e-416d-a1bb-fbfb18c9f59b
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    
    external-dns.alpha.kubernetes.io/hostname: beta-game.luckyday.soulssvc.com
spec:
  ingressClassName: alb
  rules:
  - host: beta-game.luckyday.soulssvc.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: beta-luckyday-game
            port:
              number: 80

 

 

 

고급 설정 예제 (실제 운영 환경)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: production-app-ingress
  namespace: production
  annotations:
    # 기본 ALB 설정
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/load-balancer-name: production-app-alb
    
    # SSL/보안 설정
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:123456789012:certificate/your-cert-arn
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-2-2017-01
    
    # 헬스체크 커스터마이징
    alb.ingress.kubernetes.io/healthcheck-path: /api/health
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTPS
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: "15"
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: "5"
    alb.ingress.kubernetes.io/healthy-threshold-count: "2"
    alb.ingress.kubernetes.io/unhealthy-threshold-count: "3"
    
    # 성능 및 연결 설정
    alb.ingress.kubernetes.io/target-group-attributes: |
      deregistration_delay.timeout_seconds=30,
      slow_start.duration_seconds=60,
      stickiness.enabled=true,
      stickiness.lb_cookie.duration_seconds=86400
    
    # WAF 및 보안
    alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:us-west-2:123456789012:regional/webacl/production-waf/12345
    alb.ingress.kubernetes.io/security-groups: sg-12345678,sg-87654321
    
    # 서브넷 및 네트워크 설정
    alb.ingress.kubernetes.io/subnets: subnet-12345678,subnet-87654321
    
    # 로깅 및 모니터링
    alb.ingress.kubernetes.io/load-balancer-attributes: |
      access_logs.s3.enabled=true,
      access_logs.s3.bucket=my-alb-logs-bucket,
      access_logs.s3.prefix=production-app,
      deletion_protection.enabled=true
    
    # 태깅
    alb.ingress.kubernetes.io/tags: |
      Environment=production,
      Application=main-app,
      Team=platform,
      CostCenter=engineering
    
    # External DNS
    external-dns.alpha.kubernetes.io/hostname: app.example.com,www.example.com
  labels:
    app: production-app
    environment: production
spec:
  ingressClassName: alb
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: production-app-service
            port:
              number: 80
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: production-app-service
            port:
              number: 80

 

 

 

External DNS로 CDN 도메인도 관리

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cdn-integrated-ingress
  namespace: production
  annotations:
    # ALB 설정
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/load-balancer-name: cdn-origin-alb
    
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:123456789012:certificate/your-cert-arn
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    
    # External DNS - 여러 도메인 관리
    external-dns.alpha.kubernetes.io/hostname: |
      origin.example.com,
      cdn.example.com
    
    # CDN 친화적 헤더 설정
    alb.ingress.kubernetes.io/load-balancer-attributes: |
      routing.http2.enabled=true,
      idle_timeout.timeout_seconds=60
    
    # Origin용 캐시 헤더 설정을 위한 커스텀 응답 헤더
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "Cache-Control: public, max-age=31536000" if ($uri ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$);
      more_set_headers "Cache-Control: no-cache" if ($uri !~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$);
spec:
  ingressClassName: alb
  rules:
  - host: origin.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp-service
            port:
              number: 80
  - host: cdn.example.com  # CDN 도메인도 같은 ALB로 처리 (CDN 없이 직접 접근 시)
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp-service
            port:
              number: 80

 

 

 

 

CDN + External DNS를 위한 완전한 설정

# 1. Origin 전용 Ingress (CDN에서 사용)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: origin-ingress
  namespace: production
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/load-balancer-name: origin-alb
    
    # Origin 전용 인증서
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:123456789012:certificate/origin-cert
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
    
    # Origin 도메인 - External DNS로 자동 생성
    external-dns.alpha.kubernetes.io/hostname: origin-api.example.com
    
    # CDN 최적화 설정
    alb.ingress.kubernetes.io/target-group-attributes: |
      deregistration_delay.timeout_seconds=10,
      stickiness.enabled=false
    
    # Origin 식별을 위한 태그
    alb.ingress.kubernetes.io/tags: "Purpose=CDN-Origin,Environment=production"
spec:
  ingressClassName: alb
  rules:
  - host: origin-api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80

---
# 2. CDN Distribution (Terraform으로 생성되지만 참조용)
# terraform에서 다음과 같이 생성:
# resource "aws_cloudfront_distribution" "main" {
#   origin {
#     domain_name = "origin-api.example.com"  # 위 Ingress에서 생성된 도메인
#     origin_id   = "ALB-Origin"
#   }
#   aliases = ["api.example.com", "www.api.example.com"]
# }

---
# 3. CDN 도메인을 위한 External DNS 설정 (별도 관리)
apiVersion: v1
kind: Service
metadata:
  name: cdn-external-dns
  namespace: production
  annotations:
    # CloudFront Distribution 도메인을 External DNS로 관리
    external-dns.alpha.kubernetes.io/hostname: api.example.com
    external-dns.alpha.kubernetes.io/cloudfront-distribution-id: E1234567890123
spec:
  type: ExternalName
  externalName: d123456789.cloudfront.net  # CloudFront 도메인

 

 

 

 

 

 


 

 

 

 

4. 성능 비교 및 벤치마크

 

처리량 비교

로드 밸런서 최대 RPS 동시 연결 대역폭
ALB ~100,000 RPS ~25,000 ~25 Gbps
NLB ~3,000,000 RPS 수백만 ~100 Gbps
CLB ~10,000 RPS ~55,000 ~10 Gbps
GWLB 패킷 기준 수백만 ~100 Gbps

 

 

지연시간 비교

로드 밸런서 P50 지연시간 P99 지연시간 추가 홉
ALB 1-3ms 5-10ms 1 홉
NLB 0.1ms 0.5ms 투명
CLB 2-5ms 10-15ms 1 홉
GWLB 0.1ms 0.3ms 투명

 

 

기능 비교 매트릭스

기능 ALB NLB CLB GWLB
Layer 7 라우팅 O X O X
고정 IP X O X O
WebSocket O O O X
HTTP/2 O X X X
SNI O O X X
WAF 통합 O X X X
Lambda 지원 O X X X
Cross-zone LB 기본값 옵션 옵션 기본값

 

 


 

 

 

5. 비용 최적화 전략

 

5.1 비용 구조 이해

 

ALB 비용 구성요소

  • 시간당 요금: $0.0225/시간
  • LCU(Load Balancer Capacity Unit): $0.008/LCU
  • 데이터 전송: 표준 EC2 요금

 

NLB 비용 구성요소

  • 시간당 요금: $0.0225/시간
  • NLCU(Network Load Balancer Capacity Unit): $0.006/NLCU
  • 데이터 전송: 표준 EC2 요금

 

GWLB 비용 구성요소

  • 시간당 요금: $0.0225/시간
  • GWLCU(Gateway Load Balancer Capacity Unit): $0.004/GWLCU
  • VPC 엔드포인트: $0.01/시간

 

 

 

5.2 비용 최적화 기법

 

1. 적절한 로드 밸런서 선택

# 비용 효율적인 선택 로직
locals {
  # 트래픽이 적고 HTTP만 사용하는 경우 ALB
  use_alb = var.avg_requests_per_second < 1000 && var.protocol == "HTTP"
  
  # 고성능이 필요한 TCP 트래픽의 경우 NLB
  use_nlb = var.avg_requests_per_second > 10000 || var.protocol == "TCP"
  
  # 보안 어플라이언스 통합이 필요한 경우 GWLB
  use_gwlb = var.security_appliance_required
}

 

 

2. Cross-Zone 로드 밸런싱 최적화

# NLB에서 Cross-zone 로드 밸런싱 비용 고려
resource "aws_lb" "cost_optimized_nlb" {
  name               = "cost-optimized-nlb"
  load_balancer_type = "network"
  
  # Cross-zone 로드 밸런싱 비활성화로 데이터 전송 비용 절약
  # (단, 고가용성 고려 필요)
  enable_cross_zone_load_balancing = false
  
  subnets = var.subnet_ids
}

 

3. 타겟 그룹 최적화

# 효율적인 헬스체크 설정
resource "aws_lb_target_group" "optimized_tg" {
  name     = "optimized-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id
  
  health_check {
    enabled             = true
    healthy_threshold   = 2
    interval            = 30  # 기본값, 더 짧게 하면 비용 증가
    matcher             = "200"
    path                = "/health"
    timeout             = 5
    unhealthy_threshold = 3
  }
  
  # 빠른 연결 해제로 비용 절약
  deregistration_delay = 30
}

 

4. 로그 및 모니터링 최적화

# 선택적 로그 활성화
resource "aws_lb" "log_optimized_alb" {
  name               = "log-optimized-alb"
  load_balancer_type = "application"
  subnets            = var.subnet_ids
  
  # 로그를 필요한 경우에만 활성화
  access_logs {
    bucket  = var.enable_access_logs ? aws_s3_bucket.alb_logs[0].id : ""
    enabled = var.enable_access_logs
  }
}

# S3 버킷 라이프사이클 정책으로 로그 비용 관리
resource "aws_s3_bucket_lifecycle_configuration" "alb_logs_lifecycle" {
  count  = var.enable_access_logs ? 1 : 0
  bucket = aws_s3_bucket.alb_logs[0].id

  rule {
    id     = "log_retention"
    status = "Enabled"

    expiration {
      days = 30  # 30일 후 삭제
    }

    transition {
      days          = 7
      storage_class = "STANDARD_IA"
    }

    transition {
      days          = 14
      storage_class = "GLACIER"
    }
  }
}

 

 

 

5.3 비용 모니터링 및 알람

# CloudWatch 비용 알람
resource "aws_cloudwatch_metric_alarm" "lb_cost_alarm" {
  alarm_name          = "lb-monthly-cost-alarm"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "2"
  metric_name         = "EstimatedCharges"
  namespace           = "AWS/Billing"
  period              = "86400"  # 1일
  statistic           = "Maximum"
  threshold           = var.monthly_cost_threshold
  alarm_description   = "This metric monitors lb monthly charges"
  alarm_actions       = [var.sns_topic_arn]

  dimensions = {
    Currency = "USD"
    ServiceName = "AmazonEC2"  # 로드 밸런서는 EC2 서비스에 포함
  }
}

# LCU 사용량 모니터링
resource "aws_cloudwatch_metric_alarm" "alb_lcu_alarm" {
  alarm_name          = "alb-lcu-usage-high"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "2"
  metric_name         = "ConsumedLCUs"
  namespace           = "AWS/ApplicationELB"
  period              = "300"
  statistic           = "Average"
  threshold           = var.lcu_threshold
  alarm_description   = "ALB LCU usage is too high"
  
  dimensions = {
    LoadBalancer = aws_lb.main_alb.arn_suffix
  }
}

 

 

5.4 예상 비용 계산 도구

# 변수 정의
variable "monthly_requests" {
  description = "Monthly request count"
  type        = number
  default     = 1000000
}

variable "avg_request_size" {
  description = "Average request size in KB"
  type        = number
  default     = 10
}

variable "avg_response_size" {
  description = "Average response size in KB"
  type        = number
  default     = 50
}

# 비용 계산 로컬 값
locals {
  # ALB 비용 계산
  alb_hourly_cost = 0.0225
  alb_monthly_hours = 24 * 30
  alb_base_cost = local.alb_hourly_cost * local.alb_monthly_hours
  
  # LCU 계산 (4가지 차원 중 최대값)
  new_connections_per_second = var.monthly_requests / (30 * 24 * 3600)
  requests_per_second = local.new_connections_per_second
  bandwidth_mbps = (var.avg_request_size + var.avg_response_size) * local.requests_per_second / 1024
  rule_evaluations_per_second = local.requests_per_second * 2  # 평균 2개 룰 평가
  
  max_lcu = max(
    local.new_connections_per_second / 25,    # 25 new connections/sec per LCU
    local.requests_per_second / 1000,         # 1000 requests/sec per LCU
    local.bandwidth_mbps / 1,                 # 1 Mbps per LCU
    local.rule_evaluations_per_second / 1000  # 1000 rule evaluations/sec per LCU
  )
  
  lcu_cost = local.max_lcu * 0.008 * local.alb_monthly_hours
  total_alb_cost = local.alb_base_cost + local.lcu_cost
}

# 비용 출력
output "estimated_monthly_cost" {
  value = {
    alb_base_cost = local.alb_base_cost
    lcu_cost = local.lcu_cost
    total_cost = local.total_alb_cost
    estimated_lcu = local.max_lcu
  }
}

 

 

 

 


 

 

 

6. 모니터링 및 트러블슈팅

 

6.1 핵심 메트릭 모니터링

# ALB 핵심 메트릭 대시보드
resource "aws_cloudwatch_dashboard" "alb_dashboard" {
  dashboard_name = "ALB-Monitoring-Dashboard"

  dashboard_body = jsonencode({
    widgets = [
      {
        type   = "metric"
        x      = 0
        y      = 0
        width  = 12
        height = 6

        properties = {
          metrics = [
            ["AWS/ApplicationELB", "RequestCount", "LoadBalancer", aws_lb.main_alb.arn_suffix],
            [".", "TargetResponseTime", ".", "."],
            [".", "HTTPCode_Target_2XX_Count", ".", "."],
            [".", "HTTPCode_Target_4XX_Count", ".", "."],
            [".", "HTTPCode_Target_5XX_Count", ".", "."],
            [".", "HealthyHostCount", "TargetGroup", aws_lb_target_group.web_tg.arn_suffix],
            [".", "UnHealthyHostCount", ".", "."]
          ]
          period = 300
          stat   = "Sum"
          region = var.aws_region
          title  = "ALB Key Metrics"
        }
      }
    ]
  })
}

# 중요 알람 설정
resource "aws_cloudwatch_metric_alarm" "high_response_time" {
  alarm_name          = "alb-high-response-time"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "2"
  metric_name         = "TargetResponseTime"
  namespace           = "AWS/ApplicationELB"
  period              = "60"
  statistic           = "Average"
  threshold           = "1.0"  # 1초
  alarm_description   = "ALB response time is too high"
  alarm_actions       = [var.sns_topic_arn]

  dimensions = {
    LoadBalancer = aws_lb.main_alb.arn_suffix
  }
}

resource "aws_cloudwatch_metric_alarm" "high_error_rate" {
  alarm_name          = "alb-high-5xx-error-rate"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = "2"
  metric_name         = "HTTPCode_Target_5XX_Count"
  namespace           = "AWS/ApplicationELB"
  period              = "300"
  statistic           = "Sum"

 

 

 

 


 

 

마무리

 

핵심 선택 기준 요약

  • Application Load Balancer (ALB)는 HTTP/HTTPS 기반 웹 애플리케이션과 마이크로서비스에 최적화되어 있으며, 경로 기반 라우팅과 고급 보안 기능이 필요한 경우 최고의 선택이다. Kubernetes 환경에서 Ingress Controller를 통한 통합도 매우 원활하다.
  • Network Load Balancer (NLB)는 극도의 성능과 낮은 지연시간이 요구되는 TCP/UDP 애플리케이션에 이상적입니다. 게임 서버, 실시간 스트리밍, IoT 환경에서 탁월한 성능을 발휘한다.
  • Gateway Load Balancer (GWLB)는 네트워크 보안 어플라이언스의 투명한 통합을 위한 특수 목적 로드 밸런서로, 엔터프라이즈 보안 환경에서 필수적인 역할을 한다.

 

 

성공적인 구현을 위한 권장사항

  • 아키텍처 설계 단계에서는 트래픽 패턴, 성능 요구사항, 보안 정책을 충분히 분석하여 적절한 로드 밸런서를 선택하고, Terraform과 같은 IaC 도구를 활용하여 일관되고 재현 가능한 인프라를 구축하자.
  • 비용 최적화는 지속적인 모니터링과 조정을 통해 달성할 수 있습니다. LCU/NLCU 사용량을 정기적으로 검토하고, 불필요한 기능은 비활성화하며, 적절한 헬스체크 간격을 설정하여 비용을 절감하자.
  • 운영 관리에서는 CloudWatch 메트릭과 알람을 통한 proactive 모니터링을 구축하고, 액세스 로그 분석을 통해 트래픽 패턴을 이해하며, 정기적인 성능 검토를 통해 지속적으로 최적화하자.

 

 

AWS 로드 밸런서는 단순한 트래픽 분산 도구를 넘어 현대적 애플리케이션 아키텍처의 핵심 구성 요소이다. 이 가이드의 모범 사례를 적용하여 안정적이고 확장 가능한 시스템을 구축하시기 바란다.

 

 

 

 

 

 


Reference

 

 

 

 

 

 

 

 

728x90
반응형