들어가며
이전 글에서 Spring Boot 서버를 ECR + ECS Fargate로 배포하고 GitHub Actions CI/CD까지 연동했다.
그런데 한 가지 문제가 있었다. ECS Fargate는 태스크가 재시작될 때마다 퍼블릭 IP가 바뀐다. 배포할 때마다 IP를 새로 확인해야 하고, 도메인 연결도 불가능한 구조다.
이를 해결하기 위해 ALB(Application Load Balancer)를 도입했다. ALB는 고정 DNS 주소를 제공하고, 내부적으로 태스크 IP를 자동으로 추적해준다.
왜 ALB인가?
Fargate는 EC2와 달리 Elastic IP를 직접 붙일 수 없다. 퍼블릭 IP를 고정하려면 ALB가 유일한 현실적인 선택지다.
| 항목 | 퍼블릭 IP 직접 사용 | ALB 사용 | |
| IP 고정 | ❌ 재시작 시 변경 | ✅ DNS 고정 | |
| 도메인 연결 | ❌ | ✅ | |
| 로드밸런싱 | ❌ | ✅ | |
| SSL/TLS | 직접 설정 | ACM으로 자동 | |
| 비용 | 없음 | 월 약 $18~ |
전체 구조

1. 대상 그룹 생성
ALB가 트래픽을 전달할 대상을 정의하는 그룹이다. Fargate는 IP 타입으로 설정해야 한다.
EC2 → 대상 그룹 → 대상 그룹 생성
- 대상 유형: IP 주소 (Fargate는 IP 타입 필수)
- 대상 그룹 이름: springboot-target-group
- 프로토콜: HTTP
- 포트: 8080
- VPC: ECS와 동일한 VPC 선택
- 상태 검사 경로: /actuator/health



대상 등록 화면에서는 아무것도 등록하지 않고 대상 그룹 생성을 누른다. ECS 서비스가 태스크 실행 시 자동으로 등록해준다.

2. ALB 생성
EC2 → 로드 밸런서 → 로드 밸런서 생성 → Application Load Balancer 선택
기본 구성
- 이름: springboot-alb
- 체계: 인터넷 경계
- IP 주소 유형: IPv4
네트워크 매핑 ⚠️
- VPC: ECS와 동일한 VPC
- 가용 영역: 2개 이상 반드시 선택 (미선택 시 생성 불가)ECS Fargate에 ALB 연결해서 고정 도메인 만들기
보안 그룹
- ALB 전용 보안그룹 생성 또는 선택
- 인바운드: HTTP 80, HTTPS 443 허용 (소스: 0.0.0.0/0)
- 아웃바운드: 8080 포트 허용 (대상: 0.0.0.0/0 또는 ECS 보안그룹)
리스너 및 라우팅
- 프로토콜: HTTP, 포트: 80
- 대상 그룹: springboot-target-group 선택




생성 완료 후 ALB 상태가 활성이 될 때까지 기다린다.

3. ECS 서비스에 ALB 연결
ECS → 클러스터 → 서비스 → springboot-service → 업데이트
로드 밸런싱 섹션
- 로드 밸런싱 사용 체크
- 로드 밸런서 추가 클릭
- 로드 밸런서 유형: Application Load Balancer
- 로드 밸런서: springboot-alb
- 컨테이너: springboot-cicd-ecr-ecs 8080
- 리스너: HTTP:80
- 대상 그룹: springboot-target-group
상태 검사 유예 기간: 60초 설정 (Spring Boot 시작 시간 고려)


업데이트 완료 후 대상 그룹에서 정상: 1 로 바뀌면 성공이다.

4. 접속 확인
EC2 → 로드 밸런서 → springboot-alb → DNS 이름 복사
http://springboot-alb-xxxxxxxxx.ap-northeast-2.elb.amazonaws.com
브라우저에서 접속하면 Spring Boot 응답을 확인할 수 있다.

트러블슈팅
1. Unhealthy - Request timed out
가장 많이 만나는 에러다. ALB가 ECS 태스크로 헬스체크 요청을 보냈는데 응답이 없는 경우다.
원인 1: ALB 보안그룹 아웃바운드 규칙 누락 ← 핵심 원인
ALB 보안그룹의 아웃바운드 규칙이 포트 0으로 되어있어 ECS 8080 포트로 트래픽을 못 보내는 경우다.
ALB 보안그룹 아웃바운드 규칙
유형: 사용자 지정 TCP
포트: 8080
대상: 0.0.0.0/0

원인 2: 상태 검사 유예 기간 부족
Spring Boot가 뜨는 데 6~7초 걸리는데 유예 기간이 0초면 뜨기도 전에 헬스체크가 실패한다.
ECS 서비스 업데이트 → 상태 검사 유예 기간: 60초 이상으로 설정
원인 3: 가용 영역 불일치
service springboot-service task port 8080 is unhealthy in target-group
due to (reason Target is in an Availability Zone that is not enabled for the load balancer)
ECS 태스크가 실행된 가용 영역이 ALB에 등록되어 있지 않은 경우다.
EC2 → 로드 밸런서 → springboot-alb → 네트워크 매핑 편집 → ECS 태스크가 실행되는 모든 가용 영역 추가
보안 그룹 최종 정리
사용자 (0.0.0.0/0)
↓ 80, 443
ALB 보안그룹
↓ 8080 (아웃바운드)
ECS 보안그룹 (인바운드 8080 허용)
↓
Spring Boot :8080
| 보안그룹 | 인바운드 | 아웃바운드 |
| ALB | 80, 443 (0.0.0.0/0) | 8080 (0.0.0.0/0) |
| ECS | 8080 (ALB 보안그룹 또는 0.0.0.0/0) | 전체 허용 |
마무리
ALB 도입으로 해결된 것들이다.
- 태스크 재시작해도 DNS 주소 고정
- 도메인 연결 가능 (Route 53 + ALB)
- SSL/TLS 인증서 적용 가능 (ACM)
- 향후 Auto Scaling 시 로드밸런싱 자동 처리
다음 단계로는 Route 53으로 커스텀 도메인을 연결하거나, ACM으로 HTTPS를 적용하는 것을 고려해볼 수 있다.
'IT > Cloud' 카테고리의 다른 글
| Spring Boot 서버를 AWS ECS Fargate로 배포하기 - Route 53 + ACM으로 HTTPS 적용 (3) (0) | 2026.03.28 |
|---|---|
| Spring Boot 서버를 AWS ECS Fargate로 배포하기 - ECR + ECS + GitHub Actions CI/CD 구축 (1) (0) | 2026.03.26 |
| Nginx Rate Limiting으로 DDoS 공격 막기 (0) | 2026.02.14 |
| 스프링부트 서버 과부화 테스트(2) (0) | 2025.09.10 |
| 스프링부트 서버 과부화 테스트 (0) | 2025.09.09 |