학습 목표

로드 밸런서 3종 — 계층이 선택을 결정한다 SAA 빈출

Elastic Load Balancing은 현재 세 가지 로드 밸런서를 제공합니다. API의 타입 값도 정확히 세 개(application, network, gateway)입니다. 셋을 가르는 것은 이름이 아니라 어느 계층에서 트래픽을 보는가이고, 그 결과가 지원 프로토콜로 드러납니다.

ALB · NLB · GWLB의 계층 비교 세 종류의 Elastic Load Balancing 로드 밸런서를 OSI 계층 축 위에 세운 비교표입니다. Application Load Balancer 는 L7 애플리케이션 계층에서 HTTP 와 HTTPS 를 다루고 경로·호스트 조건으로 라우팅합니다. Network Load Balancer 는 L4 전송 계층에서 TCP, UDP, TLS 를 다루고 가용 영역마다 고정 IP 를 가질 수 있습니다. Gateway Load Balancer 는 L3 네트워크 계층에서 동작하며 GENEVE 프로토콜로 서드파티 가상 어플라이언스에 트래픽을 넘깁니다. 아래 표의 강조된 칸이 결론입니다. 문제 지문에 GENEVE 나 방화벽·IDS 어플라이언스 배포가 보이면 Gateway Load Balancer 입니다. L7 애플리케이션 L4 전송 L3 네트워크 OSI 계층 ALB Application Load Balancer NLB Network Load Balancer GWLB Gateway Load Balancer 프로토콜 HTTP, HTTPS TCP, UDP, TLS GENEVE (6081) 대상 유형 인스턴스 · IP · Lambda 인스턴스 · IP 가상 어플라이언스 고정 IP 없음 — DNS 이름만 AZ 마다 고정 IP 가능 엔드포인트로 연결 판별 단서 경로·호스트 기반 라우팅 초고성능 · 고정 IP 요구 방화벽 · IDS/IPS 배포
Application Load Balancer · Network Load Balancer · Gateway Load Balancer를 OSI 계층 축 위에 놓은 비교 — 지원 프로토콜과 고정 IP 가능 여부가 계층 차이에서 그대로 따라 나옵니다
로드 밸런서 3종의 계층 · 프로토콜 · 특성 비교
항목 Application Load Balancer Network Load Balancer Gateway Load Balancer
API 타입 값 application network gateway
동작 계층 L7 (애플리케이션) L4 (전송) L3 게이트웨이 + L4 로드 밸런서
지원 프로토콜 HTTP, HTTPS TCP, TLS, UDP, TCP_UDP, QUIC, TCP_QUIC GENEVE (포트 6081)
라우팅 판단 근거 호스트 헤더 · URL 경로 · HTTP 헤더 · 쿼리 문자열 · HTTP 메서드 · 소스 IP 소스 IP (그리고 dual-stack NLB의 리스너 규칙) 대상 어플라이언스로의 흐름 유지
Elastic IP 지정 불가 — 서브넷에 EIP를 지정할 수 없다 가능 — 서브넷당 EIP 1개 불가
보안 그룹 연결 가능 가능 API 파라미터에 없음
서브넷 요구 서로 다른 가용 영역 2개 이상의 서브넷이 필수 가용 영역 1개 이상 가용 영역 1개 이상
스킴 지정 internet-facing / internal internet-facing / internal 지정 불가
대표 용도 HTTP 마이크로서비스 라우팅, 인증 연동, 리디렉션 초고성능 TCP·UDP, 고정 IP 요구, 게임·IoT·VoIP 서드파티 방화벽 · IDS/IPS 어플라이언스 삽입
세 로드 밸런서의 특성 프로파일. 계층이 높을수록 라우팅 판단은 정교해지고, 계층이 낮을수록 고정 IP와 프로토콜 자유도가 커집니다. 축의 값은 절대 수치가 아니라 특성을 등급화한 것이며, 등급 기준은 표 대체본에 적어 두었습니다

Application Load Balancer — 요청 내용을 보고 나눈다

ALB는 HTTP 요청을 열어 보고 라우팅합니다. 그래서 경로 기반(/api/*는 API 타깃 그룹, /static/*은 정적 타깃 그룹)과 호스트 기반(a.example.com과 b.example.com을 한 로드 밸런서로) 분기가 가능합니다. 같은 이유로 TLS 종료, Amazon Cognito · OIDC 인증 연동, HTTP에서 HTTPS로의 리디렉션, 고정 응답 반환 같은 L7 기능이 여기에 붙습니다.

ALB의 로드 밸런싱 알고리즘은 기본이 라운드 로빈(round_robin)이고, least_outstanding_requests(미처리 요청이 가장 적은 대상)와 weighted_random을 고를 수 있습니다. 요청마다 처리 시간이 크게 다른 애플리케이션에서는 미처리 요청 기준이 더 고르게 분산됩니다. 유휴 제한 시간(idle_timeout.timeout_seconds)은 기본 60초이고 1초에서 4000초 사이로 조정합니다.

Network Load Balancer — 고정 IP가 필요하면 여기

NLB는 TCP · UDP · TLS 수준에서 동작하므로 HTTP가 아닌 프로토콜을 그대로 통과시킵니다. 시험에서 NLB를 지목하는 결정적 신호는 두 가지입니다. (1) HTTP가 아닌 프로토콜, (2) 고정 IP 주소 요구입니다. API 문서는 NLB에 대해 "인터넷 경계 로드 밸런서에 고정 IP 주소가 필요하면 서브넷당 Elastic IP 주소 1개를 지정할 수 있다"고 명시하는 반면, ALB에 대해서는 "서브넷에 Elastic IP 주소를 지정할 수 없다"고 명시합니다.

"방화벽 허용 목록에 IP를 등록해야 한다", "클라이언트가 DNS 이름이 아니라 IP로 접속한다"는 제약이 붙으면 ALB 선택지는 그 자리에서 소거됩니다. ALB 앞에 굳이 고정 IP를 두고 싶다면 AWS Global Accelerator를 붙이는 별도 설계가 되며, 이는 14장 엣지와 DNS에서 다룹니다.

Gateway Load Balancer — GENEVE가 보이면 이것

GWLB는 서드파티 가상 어플라이언스(방화벽, 침입 탐지 · 방지 시스템, 심층 패킷 검사)를 트래픽 경로에 투명하게 끼워 넣기 위한 로드 밸런서입니다. 어플라이언스와는 GENEVE 프로토콜, 포트 6081로 통신하며, 이 프로토콜은 세 로드 밸런서 중 GWLB만 지원합니다. 따라서 문항에 GENEVE나 6081이 등장하면 다른 선택지를 볼 필요가 없습니다.

타깃 그룹 — 로드 밸런서가 실제로 트래픽을 보내는 곳

로드 밸런서 자체는 대상을 직접 알지 않습니다. 리스너가 요청을 받고, 규칙이 조건을 평가해 타깃 그룹으로 넘기고, 타깃 그룹이 헬스체크를 통과한 대상에게 보냅니다. 이 세 단계를 분리해 두었기 때문에 대상을 바꿔도 리스너 설정을 건드리지 않습니다.

ALB 리스너 · 규칙 · 타깃 그룹의 처리 순서 요청이 Application Load Balancer 안에서 내려가는 순서입니다. 먼저 포트와 프로토콜로 정해진 리스너가 요청을 받고, 리스너에 붙은 규칙들을 우선순위 번호가 낮은 것부터 차례로 평가합니다. 호스트 헤더, 경로, HTTP 헤더 같은 조건 가운데 처음으로 일치하는 규칙에서 평가가 멈추고 그 규칙이 지정한 타깃 그룹으로 요청이 넘어갑니다. 어떤 규칙에도 걸리지 않으면 항상 마지막에 놓이는 기본 규칙이 처리합니다. 타깃 그룹은 등록된 대상 가운데 헬스체크를 통과한 대상에만 요청을 보냅니다. 같은 규칙 집합이라도 우선순위 번호를 바꾸면 도착하는 타깃 그룹이 달라진다는 것이 이 그림의 요점입니다. 요청 리스너 HTTPS:443 규칙 — 우선순위 순 평가 1 2 3 4 우선순위 10 Host: api.example.com 우선순위 20 Path: /images/* 우선순위 30 Header: X-Beta=true 기본 규칙 — 항상 마지막 default tg-api tg-static tg-beta tg-web 타깃 그룹 우선순위 번호가 낮은 규칙부터 평가하고, 처음 일치하는 규칙에서 멈춥니다 같은 규칙 집합이라도 번호를 바꾸면 요청이 도착하는 타깃 그룹이 달라집니다 타깃 그룹은 등록된 대상 가운데 헬스체크를 통과한 대상에만 요청을 보냅니다
Application Load Balancer의 처리 순서 — 리스너가 요청을 받고, 우선순위가 낮은 번호부터 규칙을 평가하며, 조건에 맞는 규칙의 동작이 타깃 그룹으로 전달되고, 헬스체크를 통과한 대상만 트래픽을 받습니다

대상 유형 네 가지

타깃 그룹의 대상 유형과 용도
대상 유형 무엇을 등록하는가 언제 쓰는가
instance 인스턴스 ID. 기본값 Auto Scaling 그룹이 인스턴스를 자동으로 등록 · 해제하는 표준 구성
ip IP 주소. VPC 서브넷의 주소, RFC 1918 사설 대역, RFC 6598 대역만 가능하며 공인 라우팅 가능한 주소는 등록할 수 없다 컨테이너 태스크, 온프레미스 서버를 VPN이나 Direct Connect 너머로 대상에 넣을 때
lambda Lambda 함수 1개 HTTP 요청을 서버리스 함수로 직접 넘길 때. 헬스체크가 기본 비활성이며 켤 수 있다
alb Application Load Balancer 1개 NLB 뒤에 ALB를 두어 고정 IP와 L7 라우팅을 동시에 만족시킬 때

하나의 타깃 그룹에는 한 가지 대상 유형만 쓸 수 있습니다. 인스턴스와 IP를 한 그룹에 섞을 수 없으므로, 마이그레이션 중 두 형태가 공존한다면 타깃 그룹을 나누고 리스너 규칙으로 가중치를 나눠 보내는 구성이 됩니다.

리스너 규칙은 우선순위 순으로 평가된다

규칙은 우선순위 값이 낮은 것부터 평가되고, 조건이 맞는 첫 규칙의 동작이 수행됩니다. 어느 규칙에도 걸리지 않으면 기본 규칙의 동작이 수행됩니다. 같은 우선순위를 가진 규칙 두 개는 존재할 수 없습니다. 조건으로 쓸 수 있는 필드는 host-header, path-pattern, http-header, http-request-method, query-string, source-ip이고, 동작에는 forward, redirect, fixed-response, authenticate-cognito, authenticate-oidc가 있습니다.

여기서 자주 나오는 사고가 넓은 규칙을 낮은 번호에 두는 것입니다. /*를 우선순위 1에 두면 그 뒤의 /api/* 규칙은 영원히 평가되지 않습니다. 규칙은 좁은 것부터 배치합니다.

create-target-group.sh — 타깃 그룹 생성과 헬스체크 설정 (리소스 ID와 리전은 예시입니다)
aws elbv2 create-target-group \
  --name app-tg \
  --protocol HTTP \
  --port 8080 \
  --vpc-id vpc-0123456789abcdef0 \
  --target-type instance \
  --health-check-protocol HTTP \
  --health-check-path /healthz \
  --health-check-interval-seconds 10 \
  --health-check-timeout-seconds 5 \
  --healthy-threshold-count 2 \
  --unhealthy-threshold-count 2 \
  --matcher HttpCode=200 \
  --region ap-northeast-2

헬스체크 · 연결 드레이닝 · 고정 세션

헬스체크가 장애 감지 속도를 정한다

로드 밸런서는 대상마다 주기적으로 헬스체크를 보내고, 연속 실패 횟수가 임계치에 닿으면 대상을 unhealthy로 표시해 트래픽에서 뺍니다. 즉 장애가 트래픽에서 제거되기까지 걸리는 시간은 검사 간격과 비정상 임계치의 곱에 좌우되고, 이 두 값이 곧 설계 파라미터입니다.

타깃 그룹 헬스체크 설정의 범위와 기본값
설정 범위 기본값
검사 간격 HealthCheckIntervalSeconds 5 – 300초 30초 (GENEVE는 10초, 대상 유형이 lambda면 35초)
응답 제한 시간 HealthCheckTimeoutSeconds 2 – 120초 HTTP 6초, TCP · TLS · HTTPS 10초, GENEVE 5초, lambda 30초
정상 임계치 HealthyThresholdCount 2 – 10회 5회
비정상 임계치 UnhealthyThresholdCount 2 – 10회 2회 (lambda는 5회)
성공 응답 코드 Matcher HTTP · HTTPS는 200–499, TCP 계열은 200–599, GENEVE는 200–399 프로토콜별 기본 코드

헬스체크 경로는 애플리케이션이 실제로 요청을 처리할 수 있는지를 반영해야 합니다. 정적 파일 하나를 반환하는 경로로 검사하면, 데이터베이스 연결이 끊긴 인스턴스가 계속 정상으로 표시되어 트래픽을 받아 오류를 냅니다. 반대로 헬스체크에서 하위 의존성까지 전부 확인하면 의존성 한 곳의 순간 지연이 전체 대상을 한꺼번에 비정상으로 만들 수 있으므로, 검사 범위는 의도적으로 정합니다.

대상 상태 값은 initial, healthy, unhealthy, unhealthy.draining, unused, draining, unavailable입니다. 상태가 unused라면 대상이 등록은 되었지만 어떤 리스너에도 연결되지 않았거나 중지 상태라는 뜻이므로, 헬스체크 실패와는 원인이 다릅니다.

등록 취소 지연 — 흔히 연결 드레이닝이라 부르는 것

대상을 뺄 때 즉시 끊으면 처리 중이던 요청이 실패합니다. 그래서 로드 밸런서는 대상을 draining 상태로 두고 새 요청은 보내지 않되 진행 중인 요청은 끝나게 합니다. 이 대기 시간이 deregistration_delay.timeout_seconds이며 범위는 0 – 3600초, 기본값은 300초입니다.

이 값이 배포 속도와 직결됩니다. 요청이 짧은 웹 서비스라면 300초를 기다릴 이유가 없어 값을 낮추고, 업로드나 장시간 응답이 있는 서비스라면 값을 늘립니다. Auto Scaling 그룹이 인스턴스를 축소할 때도 이 지연을 거치므로, "스케일인이 왜 이렇게 느린가"의 답이 여기 있는 경우가 많습니다.

고정 세션 — 필요악이라는 사실을 함께 가르친다

고정 세션(sticky session)은 같은 클라이언트를 같은 대상으로 계속 보내는 기능입니다. 기본값은 비활성(stickiness.enabled는 false)이고, 방식은 로드 밸런서마다 다릅니다.

로드 밸런서별 고정 세션 방식
로드 밸런서 stickiness.type 값 기준
Application Load Balancer lb_cookie / app_cookie 로드 밸런서가 발급한 쿠키, 또는 애플리케이션이 발급한 쿠키
Network Load Balancer source_ip 클라이언트 소스 IP
Gateway Load Balancer source_ip_dest_ip / source_ip_dest_ip_proto 소스와 목적지 IP 조합(그리고 프로토콜)

ALB의 쿠키 기반 고정 세션 유지 기간은 1초에서 1주일 사이이고 기본값은 1일입니다. 문제는 고정 세션이 부하 분산을 망가뜨린다는 점입니다. 특정 대상에 세션이 몰리면 스케일아웃을 해도 새 인스턴스로 트래픽이 옮겨 가지 않고, 그 대상이 죽으면 거기에 묶여 있던 사용자만 세션을 잃습니다.

교차 영역 로드 밸런싱 — 기본값이 다르다

교차 영역 로드 밸런싱(cross-zone load balancing)이 켜져 있으면 각 가용 영역의 로드 밸런서 노드가 모든 가용 영역의 대상에 트래픽을 보냅니다. 꺼져 있으면 노드는 자기 가용 영역 안의 대상에만 보냅니다.

여기서 기본값이 갈립니다. API 문서는 Network Load Balancer와 Gateway Load Balancer의 기본값은 false, Application Load Balancer의 기본값은 true이며 변경할 수 없다고 명시합니다. 따라서 가용 영역마다 대상 수가 다른 상태로 NLB를 쓰면 대상이 적은 가용 영역의 인스턴스에 트래픽이 몰립니다. NLB를 쓸 때 가용 영역별 대상 수를 맞추거나 교차 영역을 켜야 하는 이유입니다.

다중 AZ 분산과 AZ 장애 시 트래픽 재분배 위쪽 왼편은 두 가용 영역에 대상이 고르게 등록된 정상 상태이고, 오른편은 가용 영역 a 가 장애를 겪은 상태입니다. 헬스체크가 연속으로 실패하면 로드 밸런서는 그 대상을 제외하고 남은 가용 영역의 정상 대상에만 요청을 보냅니다. 아래쪽은 교차 영역 로드 밸런싱의 기본값 차이가 트래픽 분포를 어떻게 바꾸는지 보여 줍니다. 가용 영역 a 에 대상 1개, 가용 영역 b 에 대상 3개가 있는 같은 상황에서, 교차 영역 로드 밸런싱이 켜져 있으면 가용 영역을 무시하고 대상 4개가 각각 25 퍼센트를 받습니다. 꺼져 있으면 트래픽이 먼저 가용 영역끼리 절반씩 나뉜 뒤 그 안에서 다시 나뉘므로 가용 영역 a 의 대상 하나가 50 퍼센트를, 가용 영역 b 의 대상 셋이 각각 약 16.7 퍼센트를 받습니다. ALB 는 기본으로 켜져 있고 NLB 는 기본으로 꺼져 있다는 차이가 여기서 결과를 가릅니다. 정상 상태 로드 밸런서 50% 50% AZ a 대상 1 · 정상 대상 2 · 정상 AZ b 대상 3 · 정상 대상 4 · 정상 AZ a 장애 로드 밸런서 0% 100% AZ a 헬스체크 실패 대상에서 제외 AZ b 대상 3 · 정상 대상 4 · 정상 연속 실패 횟수를 채워야 대상이 제외되므로 전환에는 헬스체크 간격만큼 시간이 걸립니다 같은 구성(AZ a 대상 1개 · AZ b 대상 3개)에서 기본값이 결과를 가릅니다 교차 영역 켜짐 — ALB 기본값 AZ 를 무시하고 전체 대상에 균등 분배 25% 25% 25% 25% AZ a 대상 1개 · AZ b 대상 3개 대상 수가 기울어도 대상별 부하는 같습니다 ALB 는 기본으로 켜져 있습니다 교차 영역 꺼짐 — NLB 기본값 먼저 AZ 끼리 나눈 뒤 그 안에서 분배 50% 16.7% 16.7% 16.7% AZ a 대상 1개 · AZ b 대상 3개 대상 하나에 부하가 세 배로 쏠립니다 NLB 는 기본으로 꺼져 있습니다
가용 영역 하나가 장애를 겪을 때의 흐름 — 헬스체크 실패가 대상 제외로 이어지고 남은 가용 영역이 트래픽을 받으며, 교차 영역 로드 밸런싱 설정에 따라 실제 트래픽 분포가 달라집니다

Auto Scaling 그룹 — 용량을 선언하고 유지시킨다

Amazon EC2 Auto Scaling은 "인스턴스를 몇 대 유지할 것인가"를 선언하면 그 상태를 계속 맞춰 주는 서비스입니다. 인스턴스가 죽으면 새로 띄우고, 부하가 늘면 정책에 따라 더 띄우고, 줄면 종료합니다. 자동 복구와 자동 확장이 같은 장치에서 나온다는 점이 핵심입니다.

시작 템플릿 — 무엇을 띄울지의 정의

Auto Scaling 그룹은 시작 템플릿(launch template) 또는 시작 구성(launch configuration)으로 인스턴스의 사양을 받습니다. AMI, 인스턴스 타입, 보안 그룹, IAM 인스턴스 프로파일, 사용자 데이터, 블록 디바이스 매핑, 인스턴스 메타데이터 옵션이 여기에 들어갑니다. 시작 템플릿은 버전을 가지므로 변경 이력을 남기고 되돌릴 수 있고, 온디맨드와 스팟을 섞는 혼합 인스턴스 정책도 시작 템플릿에서만 구성할 수 있습니다. 새로 만들 때는 시작 템플릿을 씁니다.

최소 · 원하는 · 최대 용량

Auto Scaling 그룹의 용량 설정 세 가지
설정 의미 주의
MinSize 어떤 경우에도 이 아래로는 줄이지 않는 하한 가용성의 바닥. 다중 가용 영역이라면 최소 2 이상이어야 의미가 있다
DesiredCapacity 지금 유지하려는 대수. 스케일링 정책이 이 값을 조정한다 지정하지 않으면 MinSize가 기본값이 된다
MaxSize 스케일아웃이 넘어설 수 없는 상한 비용 상한이자 사고 시 폭주를 막는 안전장치. 너무 낮으면 급증을 못 따라간다

원하는 용량은 최소 이상, 최대 이하여야 합니다. 시험에서 "트래픽이 급증했는데 확장이 되지 않았다"는 시나리오의 원인 후보 1번이 최대 용량에 이미 도달한 상태입니다.

다중 가용 영역 배치 SAA 빈출

Auto Scaling 그룹에는 VPCZoneIdentifier로 여러 가용 영역의 서브넷을 지정합니다. 그러면 Auto Scaling이 가용 영역 사이에 인스턴스를 고르게 배치하려 시도하고, 한 가용 영역이 통째로 사라져도 남은 가용 영역에서 용량을 다시 채웁니다. 가용 영역 하나에 인스턴스를 여러 대 두는 것은 고가용성이 아닙니다 (1장 가용 영역).

고가용성 웹 계층의 표준 조합은 결국 세 가지입니다 — 여러 가용 영역의 서브넷 + Auto Scaling 그룹 + 로드 밸런서. 이 조합이 성립하려면 인스턴스가 언제 죽어도 되는 상태 비저장 설계가 전제입니다. 세션과 업로드 파일이 인스턴스 로컬 디스크에 있으면 인스턴스 교체가 곧 데이터 손실이 됩니다.

asg-multi-az.yaml — 두 가용 영역에 걸친 Auto Scaling 그룹과 대상 추적 정책 (리소스 ID는 예시입니다)
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  WebAsg:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      MinSize: '2'
      MaxSize: '10'
      DesiredCapacity: '2'
      VPCZoneIdentifier:
        - subnet-0123456789abcdef0   # 가용 영역 A 프라이빗 서브넷
        - subnet-0abcdef1234567890   # 가용 영역 C 프라이빗 서브넷
      LaunchTemplate:
        LaunchTemplateId: !Ref WebLaunchTemplate
        Version: !GetAtt WebLaunchTemplate.LatestVersionNumber
      TargetGroupARNs:
        - !Ref WebTargetGroup
      HealthCheckType: ELB
      HealthCheckGracePeriod: 120
      DefaultInstanceWarmup: 60

  ScaleOnCpu:
    Type: AWS::AutoScaling::ScalingPolicy
    Properties:
      AutoScalingGroupName: !Ref WebAsg
      PolicyType: TargetTrackingScaling
      TargetTrackingConfiguration:
        PredefinedMetricSpecification:
          PredefinedMetricType: ASGAverageCPUUtilization
        TargetValue: 50

Auto Scaling 헬스체크 유형 — ELB를 켜야 하는 이유

Auto Scaling 그룹의 헬스체크 유형은 EC2, ELB, EBS, VPC_LATTICE이며 EC2가 기본이고 끌 수 없습니다. 문제는 EC2 헬스체크가 인스턴스와 시스템 상태 확인만 본다는 점입니다. 운영체제는 멀쩡한데 애플리케이션 프로세스만 죽은 경우, EC2 헬스체크는 정상이라고 보고 인스턴스를 교체하지 않습니다.

HealthCheckType에 ELB를 추가하면 로드 밸런서의 헬스체크 실패가 곧 인스턴스 교체로 이어집니다. 로드 밸런서 뒤의 Auto Scaling 그룹에서는 사실상 항상 켜야 하는 설정입니다.

함께 보는 값이 헬스체크 유예 기간(HealthCheckGracePeriod)이고 기본값은 0초입니다. 부팅과 애플리케이션 기동에 시간이 걸리는데 유예가 0이면, 아직 준비되지 않은 인스턴스가 비정상으로 판정되어 종료되고 다시 시작되는 교체 루프에 빠집니다. 기동 시간을 재서 그보다 넉넉하게 잡습니다.

스케일링 정책 — 언제, 얼마나 늘릴 것인가

정책이 하나도 없으면 Auto Scaling 그룹은 원하는 용량을 유지하기만 합니다. 자동으로 늘고 줄게 하려면 정책을 붙여야 하고, 정책 유형은 다음과 같습니다.

스케일링 정책 유형과 선택 기준
정책 동작 언제 고르는가
대상 추적 TargetTrackingScaling 지표가 목표값에 머물도록 Auto Scaling이 알아서 용량을 조정한다. 필요한 알람을 스스로 만든다 기본 선택. "평균 CPU를 50%로 유지"처럼 목표를 말할 수 있으면 이것
단계별 StepScaling 알람 위반 폭에 따라 단계별로 다른 조정량을 적용한다 급증 크기에 비례해 다르게 대응해야 할 때. "80% 넘으면 2대, 90% 넘으면 4대"
단순 SimpleScaling 알람 하나에 조정 하나. 조정 후 쿨다운이 끝날 때까지 다음 조정을 하지 않는다. API 기본값 구세대 방식. 새 설계에서는 대상 추적이나 단계별을 쓴다
예약 PutScheduledUpdateGroupAction 지정한 시각이나 반복 일정에 최소 · 최대 · 원하는 용량을 바꾼다 부하 시점을 미리 아는 경우. 업무 시간, 정기 배치, 판매 개시 시각

조정량을 어떻게 해석할지는 AdjustmentType이 정합니다 — ChangeInCapacity(증감), ExactCapacity(절대값), PercentChangeInCapacity(비율). 단계별과 단순 정책에서만 씁니다.

대상 추적에서 바로 쓸 수 있는 사전 정의 지표는 ASGAverageCPUUtilization, ASGAverageNetworkIn, ASGAverageNetworkOut, ALBRequestCountPerTarget입니다. 웹 계층에서는 CPU보다 대상당 요청 수가 부하를 더 정확히 반영하는 경우가 많습니다.

이 밖에 예측 스케일링(PredictiveScaling)이 있어 과거 패턴으로 미리 용량을 올려 둘 수 있습니다. 위 네 가지를 먼저 확실히 구분한 뒤에 보조 수단으로 이해하면 충분합니다.

워밍업과 쿨다운 — 진동을 막는 두 장치

Auto Scaling 그룹의 스케일링 반응 타임라인 가로축은 시간, 세로축은 부하와 수용 용량입니다. 실선은 실제 수요이고 파선은 그룹이 실제로 트래픽을 받아 낼 수 있는 용량입니다. 수요가 먼저 급격히 오른 뒤 용량이 따라 오르기까지 여섯 단계의 지연이 쌓입니다. 지표가 집계되기를 기다리는 시간, 알람이 평가 기간을 채워 ALARM 으로 바뀌는 시간, 용량을 계산하고 인스턴스 시작을 요청하는 시간, 인스턴스가 부팅되는 시간, 그리고 워밍업을 지나 헬스체크를 통과할 때까지의 시간입니다. 그 사이 붉게 칠해진 구간이 요청이 대기하거나 실패하는 서비스 부족 구간이며, 스케일아웃이 트래픽을 따라가지 못했다는 말은 정확히 이 구간의 길이를 가리킵니다. 서비스가 부족한 구간 요청이 대기하거나 실패합니다 부하 · 용량 높음 낮음 시간 → 부하 (수요) 용량 (수용 가능) 1 2 3 4 5 6 1 부하 급증 — 실제 수요가 먼저 오릅니다 2 지표 수집 — 집계 주기만큼 지연 3 알람 전환 — 평가 기간을 채워야 ALARM 4 용량 계산 — 시작할 인스턴스 수 결정 5 부팅 완료 — 아직 트래픽을 받지 않음 6 워밍업 통과 — 이제 트래픽을 받습니다 쿨다운이 끝나기 전에는 다음 스케일링 동작이 억제됩니다 부족 구간 = 지표 지연 + 알람 지연 + 부팅 시간 + 워밍업 시간 스케일아웃이 트래픽을 못 따라갔다는 말의 정체가 이 합계입니다
부하 급증부터 새 인스턴스가 트래픽을 받기까지의 지연 구간 — 지표 수집, 알람 발생, 용량 계산, 인스턴스 시작, 워밍업이 차례로 시간을 먹기 때문에 스케일아웃은 트래픽보다 언제나 늦게 도착합니다

새로 시작한 인스턴스는 부팅과 애플리케이션 기동 동안 CPU가 높거나 요청을 받지 못합니다. 이 값을 그대로 그룹 평균에 넣으면 지표가 왜곡되어 필요 없는 인스턴스를 더 띄웁니다. 그래서 워밍업(DefaultInstanceWarmup)을 두어 새 인스턴스가 안정될 때까지 지표 집계에서 제외합니다.

쿨다운(DefaultCooldown)은 단순 스케일링 정책에만 적용되며 조정 하나가 끝나고 다음 조정이 시작되기까지의 간격입니다. 기본값은 300초입니다. 대상 추적과 단계별 정책은 쿨다운 대신 워밍업을 씁니다. 정책마다 워밍업을 따로 주고 싶으면 EstimatedInstanceWarmup으로 덮어쓸 수 있고, 그룹 기본 워밍업이 비어 있으면 이 값이 기본 쿨다운으로 대체됩니다.

수명주기 훅 — 시작 직후와 종료 직전에 끼어들기

Auto Scaling 그룹 수명주기 훅과 상태 전이 Auto Scaling 그룹 인스턴스의 상태 기계를 왼쪽에서 오른쪽으로 그린 그림입니다. 스케일 아웃이 시작되면 인스턴스는 Pending 상태가 되고, 시작 수명주기 훅이 걸려 있으면 Pending:Wait 에서 멈춥니다. 이 대기 구간에서 애플리케이션 설치나 설정 반영 같은 초기화를 끝내고 CONTINUE 를 보내야 InService 로 넘어가 트래픽을 받습니다. 스케일 인이나 종료가 시작되면 Terminating 을 거쳐, 종료 수명주기 훅이 있으면 Terminating:Wait 에서 멈춥니다. 이 대기 구간에서 로그를 회수하고 연결을 드레이닝한 뒤 CONTINUE 를 보내면 Terminated 로 끝납니다. 훅 대기는 무한하지 않아서 하트비트 시간이 지나면 미리 정한 기본 동작으로 자동 진행됩니다. Pending 시작 요청 Pending:Wait 시작 훅 대기 InService 트래픽 수용 Terminating: Wait 종료 훅 대기 Terminated 제거 완료 CONTINUE CONTINUE 시작 훅이 하는 일 초기화 완료까지 대기 종료 훅이 하는 일 로그 회수 · 드레이닝 훅이 걸린 대기 상태에서는 상태 전이가 멈춰 있어 원하는 작업을 끼워 넣을 수 있습니다 하트비트 시간이 지나면 미리 정한 기본 동작(CONTINUE 또는 ABANDON)으로 자동 진행됩니다 시간이 더 필요하면 하트비트를 갱신해 대기를 연장합니다
Auto Scaling 인스턴스의 상태 전이와 수명주기 훅의 위치 — 시작 대기 상태에서 초기화를 마치고, 종료 대기 상태에서 로그를 회수한 뒤에야 다음 상태로 넘어갑니다

수명주기 훅은 인스턴스를 대기 상태에 붙잡아 두고 그동안 우리가 할 일을 하게 합니다. 전환 지점은 두 개입니다.

대기 시간은 HeartbeatTimeout으로 정하며 범위는 30 – 7200초, 기본값은 3600초입니다. 작업이 더 필요하면 RecordLifecycleActionHeartbeat로 시간을 연장하고, 끝나면 CompleteLifecycleAction으로 즉시 다음 단계로 넘깁니다. 시간이 다 지나면 DefaultResult가 적용되며 기본값은 ABANDON입니다. 기본 한도는 Auto Scaling 그룹당 훅 50개입니다.

확장의 방향 — 수직인가 수평인가

수직 확장과 수평 확장의 비교
항목 수직 확장 (scale up) 수평 확장 (scale out)
방법 인스턴스 타입을 더 큰 것으로 바꾼다 같은 인스턴스를 여러 대로 늘린다
중단 타입 변경은 인스턴스 중지가 필요하다 무중단으로 늘리고 줄일 수 있다
상한 가장 큰 인스턴스 타입이 상한이다 실질적인 상한이 훨씬 높다
가용성 효과 여전히 인스턴스 한 대 — 단일 장애점이 남는다 여러 가용 영역에 분산하면 장애를 견딘다
전제 없음 상태 비저장 설계와 로드 밸런서가 필요하다

시험에서 탄력성 · 확장성 · 고가용성이 요구되면 답은 수평 확장입니다. 수직 확장이 정답이 되는 경우는 수평으로 나눌 수 없는 워크로드일 때입니다 — 단일 쓰기 노드인 관계형 데이터베이스, 라이선스가 노드 수에 묶인 소프트웨어 같은 경우입니다. 데이터베이스 계층의 확장 판단은 10장 RDS와 관계형 데이터베이스에서 다룹니다.

단일 장애점을 남기지 않는 조립법

안정성(Reliability, 신뢰성으로도 번역됨)의 기준은 단순합니다. 어느 구성 요소 하나가 사라져도 서비스가 계속되는가입니다. Auto Scaling 그룹과 로드 밸런서를 붙여 놓고도 서비스가 통째로 멈추는 구성이 흔한데, 원인은 대개 아래 다섯 가지 중 하나입니다.

웹 계층에서 자주 남는 단일 장애점과 해소 방법
남아 있는 단일 장애점 증상 해소
서브넷이 한 가용 영역에만 있음 Auto Scaling 그룹이 있어도 그 가용 영역이 죽으면 전면 중단 가용 영역 2개 이상의 서브넷을 VPCZoneIdentifier에 넣는다
NAT 게이트웨이가 한 개 프라이빗 서브넷 전체의 아웃바운드가 그 가용 영역과 함께 끊긴다 가용 영역마다 NAT 게이트웨이를 두고 라우팅 테이블을 분리한다 (3장)
세션과 업로드 파일이 인스턴스 로컬에 인스턴스가 교체될 때마다 로그아웃과 파일 유실 세션은 ElastiCache나 DynamoDB, 파일은 Amazon S3나 Amazon EFS로 뺀다
헬스체크 유형이 EC2뿐 애플리케이션이 죽어도 교체되지 않고 계속 오류를 반환 HealthCheckType에 ELB를 추가한다
데이터베이스가 단일 인스턴스 웹 계층은 살아 있는데 서비스는 멈춘다 Multi-AZ 배포로 전환한다 (10장)

가용 영역 하나의 서브넷만 지정하고, 헬스체크는 EC2만 쓰고, 세션을 인스턴스 로컬에 둡니다. 인스턴스는 여러 대지만 장애 도메인은 하나입니다.

안티패턴 — 단일 가용 영역 Auto Scaling 그룹
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name web-asg \
  --min-size 2 --max-size 6 --desired-capacity 2 \
  --vpc-zone-identifier "subnet-0123456789abcdef0" \
  --launch-template LaunchTemplateId=lt-0123456789abcdef0,Version='$Latest'

두 가용 영역의 서브넷을 지정하고 타깃 그룹에 연결한 뒤, 헬스체크를 ELB로 두고 기동 시간만큼 유예를 줍니다.

권장 — 다중 가용 영역 + 로드 밸런서 헬스체크
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name web-asg \
  --min-size 2 --max-size 10 --desired-capacity 2 \
  --vpc-zone-identifier "subnet-0123456789abcdef0,subnet-0abcdef1234567890" \
  --target-group-arns "$TARGET_GROUP_ARN" \
  --health-check-type ELB \
  --health-check-grace-period 120 \
  --default-instance-warmup 60 \
  --launch-template LaunchTemplateId=lt-0123456789abcdef0,Version='$Latest'

흔한 오해

시험 포인트 정리

확인 문제

이 장의 핵심을 확인하는 10문항입니다. 키보드만으로 완주할 수 있습니다 — 숫자키 1~5로 선택지를 고르고 Enter로 제출합니다.

이어서 볼 곳

공식 문서 출처

이 장의 설정값 · 기본값 · 동작은 모두 아래 문서에서 확인했습니다.