AWS 101 Containers Workshop
컨테이너의 기초부터 AWS ECS, Fargate까지. Docker 이미지를 만들고 AWS에서 컨테이너를 운영하는 방법을 배웁니다.
워크샵 바로가기워크샵 개요
이 워크샵에서는 컨테이너 기술의 기초부터 AWS에서 컨테이너를 운영하는 방법까지 단계별로 학습합니다.
📋 사전 준비: Docker Desktop 설치, AWS 계정
로컬에서 Docker를 실행할 수 있어야 합니다. Docker Desktop을 미리 설치해주세요.
단계별 기본 지식
Amazon ECR (Elastic Container Registry)
AWS에서 제공하는 완전관리형 Docker 컨테이너 레지스트리입니다. Docker Hub의 AWS 버전이라고 생각하면 됩니다. 이미지를 안전하게 저장하고, AWS 서비스들과 쉽게 연동됩니다.
📦 비유: 'AWS 전용 택배 물류창고'입니다. 물건(이미지)을 보관하고, AWS 내 어디서든 빠르게 가져갈 수 있어요.
🏗️ ECR 구조:
AWS Account
└── ECR
├── Repository A (예: my-web-app)
│ ├── Image:latest
│ ├── Image:v1.0.0
│ └── Image:v1.0.1
└── Repository B (예: my-api)
├── Image:latest
└── Image:prodRepository (리포지토리)
같은 애플리케이션의 이미지들을 모아두는 폴더입니다. 예를 들어 'my-web-app' 리포지토리에는 해당 앱의 여러 버전 이미지가 저장됩니다.
📁 비유: '앨범 폴더'입니다. 같은 주제의 사진(이미지 버전)들을 한 폴더에 모아두는 것과 같아요.
Private vs Public Repository
Private 리포지토리는 IAM 권한이 있는 사용자만 접근 가능합니다. Public 리포지토리는 누구나 이미지를 pull할 수 있습니다. 대부분의 경우 Private을 사용합니다.
🔐 비유: Private은 '회사 내부 서버', Public은 '공개 웹사이트'입니다.
Image Tag (이미지 태그)
이미지의 버전을 구분하는 라벨입니다. 'latest', 'v1.0.0', 'production' 등으로 지정합니다. 태그가 없으면 자동으로 'latest'가 됩니다.
🏷️ 비유: '버전 스티커'입니다. 같은 제품이라도 v1, v2로 구분할 수 있어요.
📌 ECR 이미지 URI 형식:
{account-id}.dkr.ecr.{region}.amazonaws.com/{repo-name}:{tag}
예시:
123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest
123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:v1.0.0콘솔에서 ECR 리포지토리 생성하기
AWS 콘솔에서 ECR 서비스로 이동 → 'Create repository' 클릭 → 리포지토리 이름 입력 → 설정 선택 → 생성 완료
🖱️ 콘솔 생성 단계: 1. AWS Console → ECR 서비스 검색 및 이동 2. 'Create repository' 버튼 클릭 3. Visibility: Private 선택 (기본값) 4. Repository name: 예) demo-flask-backend 5. Tag immutability: Disabled (기본값) - Enabled: 같은 태그로 덮어쓰기 불가 6. Scan on push: Enabled 권장 - 이미지 푸시 시 보안 취약점 자동 스캔 7. 'Create repository' 클릭
실무 팁
- •리포지토리 이름은 소문자, 숫자, 하이픈, 언더스코어, 슬래시만 사용 가능합니다
- •Scan on push를 활성화하면 보안 취약점을 자동으로 검사합니다
- •수명 주기 정책(Lifecycle Policy)으로 오래된 이미지를 자동 삭제하여 비용을 절감하세요
- •리포지토리 생성 후 'View push commands'를 클릭하면 이미지 푸시 명령어를 확인할 수 있습니다
Container Image (컨테이너 이미지)
애플리케이션 코드, 런타임, 라이브러리, 환경 변수, 설정 파일 등을 하나로 묶은 패키지입니다. 이 이미지로 어디서든 동일한 환경의 컨테이너를 실행할 수 있습니다.
📀 비유: 'USB 부팅 디스크'입니다. 어떤 컴퓨터에 꽂아도 같은 환경으로 부팅되는 것처럼, 이미지는 어디서든 같은 환경을 제공합니다.
Dockerfile
이미지를 만들기 위한 설명서입니다. 베이스 이미지 선택, 파일 복사, 명령어 실행 등을 순서대로 정의합니다. 레시피처럼 따라하면 동일한 이미지가 만들어집니다.
📝 비유: '요리 레시피'입니다. 재료(베이스 이미지)부터 조리 순서(명령어)까지 적혀있어요.
📝 Dockerfile 기본 명령어: FROM python:3.9-slim # 베이스 이미지 지정 WORKDIR /app # 작업 디렉토리 설정 COPY . . # 현재 폴더 파일들을 컨테이너로 복사 RUN pip install -r requirements.txt # 빌드 시 실행할 명령 EXPOSE 5000 # 컨테이너가 사용할 포트 문서화 CMD ["python", "app.py"] # 컨테이너 시작 시 실행할 명령
Base Image (베이스 이미지)
새 이미지를 만들 때 시작점이 되는 이미지입니다. python:3.9, node:18, nginx:latest 등 공식 이미지를 주로 사용합니다. FROM 명령어로 지정합니다.
🏠 비유: '기본 뼈대 집'입니다. 이 위에 인테리어(애플리케이션)를 추가하는 거예요.
🔍 베이스 이미지 선택 가이드: • python:3.9-slim → Python 앱 (slim은 경량 버전) • node:18-alpine → Node.js 앱 (alpine은 초경량) • nginx:latest → 웹 서버 • amazoncorretto:17 → Java 앱 (Amazon 최적화 JDK) 💡 팁: alpine이나 slim 버전을 사용하면 이미지 크기가 작아집니다
docker build 명령어
Dockerfile을 읽어서 이미지를 생성하는 명령어입니다. -t 옵션으로 이미지 이름과 태그를 지정합니다.
🔨 이미지 빌드 명령어: # 기본 빌드 (현재 디렉토리의 Dockerfile 사용) docker build -t my-app:latest . # ECR용 태그로 빌드 docker build -t 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest . # 빌드 확인 docker images
Image Layer (이미지 레이어)
Docker 이미지는 여러 레이어로 구성됩니다. Dockerfile의 각 명령어가 하나의 레이어를 만들고, 레이어는 캐시되어 재사용됩니다.
🍰 비유: '레이어 케이크'입니다. 각 층(레이어)이 쌓여서 완성된 케이크(이미지)가 됩니다. 아래층이 같으면 재사용할 수 있어요.
실무 팁
- •자주 변경되는 파일(소스 코드)은 Dockerfile 아래쪽에 COPY하세요. 캐시 효율이 좋아집니다
- •.dockerignore 파일로 불필요한 파일(node_modules, .git 등)을 제외하세요
- •alpine이나 slim 베이스 이미지를 사용하면 이미지 크기를 줄일 수 있습니다
- •멀티스테이지 빌드를 사용하면 빌드 도구 없이 실행 파일만 포함된 작은 이미지를 만들 수 있습니다
ECR 인증 (Authentication)
ECR에 이미지를 push/pull하려면 먼저 Docker 클라이언트를 ECR에 인증해야 합니다. AWS CLI로 임시 토큰을 받아 docker login을 수행합니다.
🔑 비유: '출입증 발급'입니다. 건물(ECR)에 들어가려면 먼저 신분 확인 후 출입증을 받아야 해요.
🔐 ECR 로그인 명령어:
# AWS CLI v2 사용
aws ecr get-login-password --region ap-northeast-2 | \
docker login --username AWS \
--password-stdin {account-id}.dkr.ecr.ap-northeast-2.amazonaws.com
# 성공 시 출력: Login Succeeded
💡 토큰은 12시간 후 만료됩니다docker tag (이미지 태깅)
로컬 이미지에 ECR 리포지토리 주소를 포함한 새 이름을 붙이는 것입니다. ECR에 푸시하려면 반드시 ECR URI 형식의 태그가 필요합니다.
📮 비유: '배송 라벨 붙이기'입니다. 택배를 보내려면 받는 주소(ECR URI)를 붙여야 해요.
🏷️ 이미지 태그 명령어:
# 형식
docker tag {로컬이미지}:{태그} {ECR-URI}:{태그}
# 예시
docker tag my-app:latest \
123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest
# 확인
docker images | grep my-appdocker push (이미지 푸시)
태그된 이미지를 ECR 리포지토리에 업로드합니다. 이미지 레이어별로 업로드되며, 이미 존재하는 레이어는 건너뜁니다.
📤 이미지 푸시 명령어:
docker push {ECR-URI}:{태그}
# 예시
docker push 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/my-app:latest
# 출력 예시
The push refers to repository [123456789012.dkr.ecr...]
abc123def: Pushed
xyz789ghi: Pushed
latest: digest: sha256:... size: 1234View push commands (콘솔 기능)
ECR 콘솔에서 리포지토리를 선택하고 'View push commands' 버튼을 클릭하면 해당 리포지토리에 이미지를 푸시하는 전체 명령어를 확인할 수 있습니다.
🖱️ 콘솔에서 푸시 명령어 확인: 1. ECR 콘솔 → 리포지토리 선택 2. 'View push commands' 버튼 클릭 3. 4단계 명령어가 표시됨: ① ECR 로그인 ② Docker 이미지 빌드 ③ 이미지 태그 ④ 이미지 푸시 💡 명령어를 복사해서 터미널에 붙여넣기만 하면 됩니다!
실무 팁
- •ECR 로그인 토큰은 12시간 후 만료됩니다. CI/CD에서는 매번 새로 발급받으세요
- •'View push commands'를 활용하면 명령어를 외울 필요가 없습니다
- •이미지 푸시 후 ECR 콘솔에서 이미지가 잘 올라갔는지 확인하세요
- •같은 태그로 다시 푸시하면 기존 이미지를 덮어씁니다 (Tag immutability가 Disabled인 경우)
VPC Endpoint란?
VPC 내부에서 AWS 서비스(S3, ECR, CloudWatch 등)에 프라이빗하게 연결하는 통로입니다. 인터넷 게이트웨이나 NAT 게이트웨이 없이도 AWS 서비스를 사용할 수 있습니다.
🚇 비유: '지하 연결 통로'입니다. 건물(VPC) 밖으로 나가지 않고 지하 통로로 다른 건물(AWS 서비스)에 갈 수 있어요.
🔗 VPC Endpoint가 필요한 이유: 프라이빗 서브넷의 ECS Task가 다음을 해야 할 때: • ECR에서 이미지 Pull • CloudWatch에 로그 전송 • S3에서 파일 읽기/쓰기 • Secrets Manager에서 비밀 값 가져오기 ❌ Endpoint 없이: 인터넷 → NAT Gateway → AWS 서비스 ✅ Endpoint 사용: VPC 내부 → 직접 AWS 서비스
Interface Endpoint
ENI(Elastic Network Interface)를 사용하는 엔드포인트입니다. 대부분의 AWS 서비스가 이 방식을 사용합니다. 시간당 요금과 데이터 처리 요금이 발생합니다.
📞 비유: '내선 전화'입니다. 외부 전화(인터넷)를 거치지 않고 내선으로 직접 연결해요.
📋 ECS/Fargate에 필요한 Interface Endpoints:
• com.amazonaws.{region}.ecr.api - ECR API 호출
• com.amazonaws.{region}.ecr.dkr - Docker 이미지 Pull
• com.amazonaws.{region}.logs - CloudWatch Logs
• com.amazonaws.{region}.secretsmanager - Secrets Manager
• com.amazonaws.{region}.ssm - Systems ManagerGateway Endpoint
라우팅 테이블을 통해 연결하는 엔드포인트입니다. S3와 DynamoDB만 지원하며, 무료입니다.
🛣️ 비유: '전용 고속도로'입니다. 일반 도로(인터넷)를 거치지 않는 무료 전용 도로예요.
📋 Gateway Endpoints (무료!):
• com.amazonaws.{region}.s3 - S3 접근
• com.amazonaws.{region}.dynamodb - DynamoDB 접근
💡 S3 Gateway Endpoint는 ECR 이미지 레이어 다운로드에도 사용됩니다
(ECR은 이미지 레이어를 S3에 저장함)콘솔에서 VPC Endpoint 생성하기
VPC 콘솔에서 Endpoints 메뉴로 이동하여 필요한 서비스의 엔드포인트를 생성합니다.
🖱️ 콘솔 생성 단계: 1. VPC 콘솔 → Endpoints → Create endpoint 2. Name tag: 예) ecr-api-endpoint 3. Service category: AWS services 4. Services: 검색하여 선택 예) com.amazonaws.ap-northeast-2.ecr.api 5. VPC: 대상 VPC 선택 6. Subnets: 프라이빗 서브넷 선택 7. Security groups: HTTPS(443) 허용하는 SG 8. Create endpoint
실무 팁
- •S3 Gateway Endpoint는 무료이므로 반드시 생성하세요
- •Interface Endpoint는 시간당 약 $0.01 + 데이터 처리 비용이 발생합니다
- •Endpoint용 Security Group은 VPC CIDR에서 443 포트를 허용해야 합니다
- •NAT Gateway 비용이 높다면 VPC Endpoint로 대체하는 것이 경제적입니다
Amazon ECS (Elastic Container Service)
AWS의 완전관리형 컨테이너 오케스트레이션 서비스입니다. 컨테이너의 배포, 관리, 확장을 자동화합니다. Kubernetes보다 간단하게 시작할 수 있습니다.
🎭 비유: '컨테이너 극장 매니저'입니다. 배우(컨테이너)들의 등장, 퇴장, 교체를 관리해요.
ECS Cluster (클러스터)
Task와 Service가 실행되는 논리적 그룹입니다. 하나의 클러스터에 여러 서비스를 배포할 수 있고, 개발/스테이징/프로덕션 환경별로 클러스터를 분리하기도 합니다.
🏟️ 비유: '경기장'입니다. 이 안에서 여러 경기(서비스)가 동시에 진행될 수 있어요.
🏗️ ECS 구조:
ECS Cluster
├── Service A (웹 서버)
│ ├── Task 1 (컨테이너 실행 중)
│ ├── Task 2 (컨테이너 실행 중)
│ └── Task 3 (컨테이너 실행 중)
└── Service B (API 서버)
├── Task 1
└── Task 2Launch Type: Fargate vs EC2
Fargate는 서버리스로 AWS가 인프라를 관리합니다. EC2는 직접 인스턴스를 관리합니다. 초보자는 Fargate로 시작하는 것을 권장합니다.
| 구분 | Fargate | EC2 |
|---|---|---|
| 서버 관리 | AWS가 관리 (서버리스) | 직접 관리 |
| 확장 | 자동 | Auto Scaling 설정 필요 |
| 비용 | Task 단위 과금 | 인스턴스 과금 |
| 시작 시간 | 빠름 (수십 초) | 인스턴스 시작 필요 |
| 적합한 경우 | 가변 워크로드, 간단한 운영 | 대규모, GPU 필요 |
콘솔에서 ECS 클러스터 생성하기
ECS 콘솔에서 클러스터를 생성합니다. Fargate를 사용하면 인프라 설정 없이 바로 생성됩니다.
🖱️ 콘솔 생성 단계: 1. ECS 콘솔 → Clusters → Create cluster 2. Cluster name: 예) demo-cluster 3. Infrastructure: ✅ AWS Fargate (serverless) - 권장 ☐ Amazon EC2 instances 4. Monitoring: Container Insights 활성화 권장 5. Tags: 필요시 추가 6. Create 클릭 💡 Fargate 선택 시 몇 초 만에 클러스터가 생성됩니다!
Container Insights
ECS 클러스터와 서비스의 메트릭을 수집하고 시각화하는 CloudWatch 기능입니다. CPU, 메모리, 네트워크 사용량 등을 모니터링할 수 있습니다.
📊 비유: '건강 모니터링 앱'입니다. 컨테이너의 상태를 실시간으로 확인할 수 있어요.
실무 팁
- •처음에는 Fargate로 시작하세요. 인프라 관리 없이 컨테이너에만 집중할 수 있습니다
- •Container Insights를 활성화하면 문제 발생 시 원인 파악이 쉬워집니다
- •클러스터 이름은 나중에 변경할 수 없으니 신중하게 정하세요
- •개발/스테이징/프로덕션 환경별로 클러스터를 분리하는 것이 좋습니다
Task Definition (태스크 정의)
컨테이너 실행에 필요한 모든 설정을 담은 JSON 템플릿입니다. 이미지 URI, CPU/메모리, 포트 매핑, 환경 변수, 로그 설정 등을 정의합니다.
📋 비유: '작업 지시서'입니다. 어떤 이미지를 쓰고, 얼마나 리소스를 주고, 어떤 설정을 할지 적혀있어요.
Task vs Task Definition
Task Definition은 '설계도'이고, Task는 '실제 실행 중인 컨테이너'입니다. 하나의 Task Definition으로 여러 Task를 실행할 수 있습니다.
🏭 비유: Task Definition은 '제품 설계도', Task는 '생산된 제품'입니다. 같은 설계도로 여러 제품을 만들 수 있어요.
Task Definition 주요 설정
Task Definition에서 설정해야 하는 핵심 항목들입니다.
📝 주요 설정 항목: • Family: Task Definition 이름 (버전 관리됨) • Launch type: Fargate 또는 EC2 • Task size: CPU와 메모리 할당량 • Container definitions: - Name: 컨테이너 이름 - Image: ECR 이미지 URI - Port mappings: 컨테이너 포트 - Environment variables: 환경 변수 - Log configuration: CloudWatch Logs 설정 • Task role: 컨테이너가 AWS 서비스 접근 시 사용 • Execution role: ECS가 이미지 pull 등에 사용
Fargate Task Size
Fargate에서는 미리 정의된 CPU/메모리 조합 중에서 선택해야 합니다. 워크로드에 맞는 적절한 크기를 선택하세요.
| vCPU | 메모리 옵션 (GB) |
|---|---|
| 0.25 | 0.5, 1, 2 |
| 0.5 | 1, 2, 3, 4 |
| 1 | 2, 3, 4, 5, 6, 7, 8 |
| 2 | 4 ~ 16 (1GB 단위) |
| 4 | 8 ~ 30 (1GB 단위) |
콘솔에서 Task Definition 생성하기
ECS 콘솔에서 Task Definition을 생성합니다.
🖱️ 콘솔 생성 단계: 1. ECS 콘솔 → Task definitions → Create new task definition 2. Task definition family: 예) demo-flask-task 3. Launch type: AWS Fargate 4. OS/Architecture: Linux/X86_64 5. Task size: CPU 0.5 vCPU, Memory 1 GB (테스트용) 6. Task role: 필요시 선택 (S3 접근 등) 7. Container - 1: - Name: flask-container - Image URI: ECR 이미지 URI 붙여넣기 - Container port: 5000 (앱 포트) - Protocol: TCP 8. Logging: CloudWatch Logs 자동 설정 9. Create
Task Definition Revision
Task Definition을 수정하면 새 리비전(버전)이 생성됩니다. 이전 버전은 유지되어 롤백이 가능합니다.
📚 비유: '문서 버전 관리'입니다. v1, v2, v3... 문제가 생기면 이전 버전으로 돌아갈 수 있어요.
실무 팁
- •처음에는 작은 Task size로 시작하고, 모니터링 후 필요시 늘리세요
- •환경 변수에 민감한 정보는 넣지 말고 Secrets Manager를 사용하세요
- •CloudWatch Logs를 반드시 설정하세요. 문제 발생 시 로그가 없으면 디버깅이 어렵습니다
- •Task Definition은 수정이 아닌 새 리비전 생성입니다. 이전 버전은 그대로 유지됩니다
Application Load Balancer (ALB)
HTTP/HTTPS 트래픽을 여러 대상(컨테이너, EC2 등)에 분산하는 L7 로드밸런서입니다. URL 경로, 호스트 헤더 등을 기반으로 라우팅할 수 있습니다.
🚦 비유: '교통 정리 경찰'입니다. 들어오는 차량(요청)을 여러 도로(컨테이너)로 분산시켜요.
🔗 ALB 트래픽 흐름: 사용자 → Internet → ALB → Target Group → ECS Tasks • ALB: 트래픽 수신 및 분산 • Target Group: 트래픽을 받을 대상 그룹 • ECS Tasks: 실제 요청을 처리하는 컨테이너
Target Group (대상 그룹)
ALB가 트래픽을 보낼 대상들의 그룹입니다. ECS Service와 연결하면 Service의 Task들이 자동으로 Target Group에 등록됩니다.
👥 비유: '배달 대상 목록'입니다. 이 목록에 있는 사람들(컨테이너)에게 배달(트래픽)을 나눠줘요.
Listener (리스너)
ALB가 트래픽을 수신하는 포트와 프로토콜을 정의합니다. 예: 80번 포트로 HTTP 요청을 받아서 Target Group으로 전달.
📡 Listener 설정 예시: • HTTP:80 → Target Group (개발/테스트용) • HTTPS:443 → Target Group (프로덕션) 💡 프로덕션에서는 HTTPS를 사용하고, HTTP:80은 HTTPS:443으로 리다이렉트하세요
Health Check (상태 확인)
ALB가 주기적으로 Target의 상태를 확인합니다. 응답이 없거나 오류를 반환하면 해당 Target으로 트래픽을 보내지 않습니다.
🏥 비유: '건강 검진'입니다. 아픈 직원(unhealthy 컨테이너)에게는 일을 주지 않아요.
💓 Health Check 설정: • Path: /health 또는 / (확인할 경로) • Interval: 30초 (확인 주기) • Timeout: 5초 (응답 대기 시간) • Healthy threshold: 2 (연속 성공 횟수) • Unhealthy threshold: 3 (연속 실패 횟수)
콘솔에서 ALB 생성하기
EC2 콘솔의 Load Balancers에서 ALB를 생성합니다.
🖱️ 콘솔 생성 단계:
1. EC2 콘솔 → Load Balancers → Create
2. Type: Application Load Balancer
3. Name: 예) demo-alb
4. Scheme: Internet-facing (외부 접근용)
5. IP address type: IPv4
6. VPC: 대상 VPC 선택
7. Mappings: 2개 이상 AZ의 Public 서브넷 선택
8. Security group: HTTP(80) 허용하는 SG
9. Listener: HTTP:80
10. Target group: Create target group
- Type: IP addresses (Fargate용)
- Name: demo-tg
- Port: 5000 (컨테이너 포트)
- Health check path: /
11. Create load balancer실무 팁
- •ALB는 최소 2개 AZ에 배포해야 합니다 (고가용성)
- •Target Group 타입은 Fargate 사용 시 'IP addresses'를 선택하세요
- •Health Check 경로는 빠르게 응답하는 가벼운 엔드포인트로 설정하세요
- •ALB Security Group은 0.0.0.0/0에서 80/443만 허용하고, ECS Task SG는 ALB SG에서만 허용하세요
ECS Service (서비스)
Task Definition을 기반으로 지정된 수의 Task를 실행하고 유지하는 기능입니다. Task가 실패하면 자동으로 새 Task를 시작합니다.
👨💼 비유: '인력 관리자'입니다. 항상 3명이 근무해야 한다면, 누가 퇴근해도 바로 대체 인력을 투입해요.
Desired Count (원하는 개수)
Service가 유지해야 하는 Task의 수입니다. 3으로 설정하면 항상 3개의 Task가 실행됩니다. 하나가 죽으면 자동으로 새로 시작합니다.
🎯 비유: '목표 인원'입니다. 항상 이 숫자만큼 일하는 사람이 있어야 해요.
Service와 ALB 연동
Service를 생성할 때 ALB Target Group을 연결하면, Task가 시작/종료될 때 자동으로 Target Group에 등록/해제됩니다.
🔗 Service + ALB 연동 흐름: 1. Service가 Task 시작 2. Task가 healthy 상태가 되면 3. 자동으로 Target Group에 등록 4. ALB가 트래픽 전달 시작 Task 종료 시: 1. Target Group에서 해제 (draining) 2. 진행 중인 요청 완료 대기 3. Task 종료
Rolling Update (롤링 업데이트)
새 버전 배포 시 기존 Task를 점진적으로 새 Task로 교체합니다. 서비스 중단 없이 배포할 수 있습니다.
🔄 비유: '교대 근무'입니다. 새 직원이 출근하면 기존 직원이 퇴근해요. 항상 누군가는 일하고 있습니다.
⚙️ Rolling Update 설정: • Minimum healthy percent: 50% → 업데이트 중 최소 유지 비율 • Maximum percent: 200% → 업데이트 중 최대 Task 비율 예: desired=4, min=50%, max=200% → 최소 2개 유지, 최대 8개까지 동시 실행
콘솔에서 ECS Service 생성하기
ECS 클러스터 내에서 Service를 생성합니다.
🖱️ 콘솔 생성 단계: 1. ECS 콘솔 → Clusters → 클러스터 선택 2. Services 탭 → Create 3. Compute options: Launch type - FARGATE 4. Task definition: 생성한 Task Definition 선택 5. Service name: 예) demo-flask-service 6. Desired tasks: 2 (또는 원하는 수) 7. Networking: - VPC: 대상 VPC - Subnets: Private 서브넷 선택 - Security group: 컨테이너 포트 허용 (ALB SG에서) - Public IP: Off (Private 서브넷이므로) 8. Load balancing: - Type: Application Load Balancer - ALB: 생성한 ALB 선택 - Target group: 생성한 Target Group 선택 9. Create
실무 팁
- •처음에는 Desired count를 2로 시작하세요. 고가용성을 위해 최소 2개 권장
- •Private 서브넷에 Task를 배포하고 ALB만 Public에 두는 것이 보안상 좋습니다
- •Service 생성 후 Tasks 탭에서 Task 상태를 확인하세요. RUNNING이 되어야 정상입니다
- •문제 발생 시 Task의 Logs 탭에서 CloudWatch 로그를 확인하세요
Amazon S3 (Simple Storage Service)
무제한 용량의 객체 스토리지 서비스입니다. 파일(객체)을 버킷에 저장하고, HTTP/HTTPS로 접근합니다. 내구성 99.999999999%(11 9's)를 제공합니다.
📦 비유: '무한 창고'입니다. 파일을 얼마든지 저장할 수 있고, 인터넷으로 어디서든 접근할 수 있어요.
S3 Bucket (버킷)
객체를 저장하는 컨테이너입니다. 버킷 이름은 전 세계적으로 고유해야 합니다. 리전을 선택하여 생성합니다.
🪣 비유: '파일 보관함'입니다. 이 안에 폴더처럼 구조를 만들어 파일을 정리할 수 있어요.
컨테이너에서 S3 접근하기
ECS Task가 S3에 접근하려면 Task Role에 S3 권한이 필요합니다. AWS SDK를 사용하여 파일을 업로드/다운로드합니다.
🔐 S3 접근 설정: 1. IAM Role 생성 (ECS Task용) 2. S3 권한 정책 연결: - s3:GetObject (읽기) - s3:PutObject (쓰기) - s3:ListBucket (목록 조회) 3. Task Definition에서 Task Role 지정 💡 컨테이너 내 코드에서 AWS SDK 사용: boto3 (Python), aws-sdk (Node.js) 등
S3 버킷 정책 vs IAM 정책
버킷 정책은 버킷에 '누가 접근할 수 있는지' 정의합니다. IAM 정책은 사용자/역할이 '어떤 리소스에 접근할 수 있는지' 정의합니다.
📋 정책 비교: 버킷 정책 (리소스 기반): '이 버킷에 특정 계정/역할이 접근 가능' IAM 정책 (자격 증명 기반): '이 역할은 특정 버킷에 접근 가능' 💡 ECS Task는 주로 IAM 정책(Task Role)을 사용합니다
실무 팁
- •버킷 이름은 전 세계적으로 고유해야 합니다. 회사명-프로젝트명-환경 형식 추천
- •퍼블릭 액세스는 기본적으로 차단하세요. 필요한 경우에만 CloudFront를 통해 제공
- •Task Role에 최소 권한만 부여하세요 (특정 버킷, 특정 작업만)
- •대용량 파일은 Multipart Upload를 사용하세요
Amazon EFS (Elastic File System)
완전관리형 NFS 파일 시스템입니다. 여러 EC2 인스턴스나 ECS Task가 동시에 읽고 쓸 수 있습니다. 용량이 자동으로 확장/축소됩니다.
📁 비유: '공유 네트워크 드라이브'입니다. 여러 컴퓨터(컨테이너)가 같은 폴더를 동시에 사용할 수 있어요.
EFS vs EBS vs S3
각 스토리지 서비스의 특성과 용도가 다릅니다.
| 구분 | EFS | EBS | S3 |
|---|---|---|---|
| 타입 | 파일 스토리지 | 블록 스토리지 | 객체 스토리지 |
| 동시 접근 | 여러 인스턴스 | 단일 인스턴스 | 무제한 |
| 용량 | 자동 확장 | 고정 (수동 확장) | 무제한 |
| 용도 | 공유 파일 | DB, OS 디스크 | 정적 파일, 백업 |
| Fargate 지원 | ✅ | ❌ | SDK로 접근 |
EFS Mount Target
EFS에 접근하기 위한 네트워크 엔드포인트입니다. 각 AZ에 Mount Target을 생성해야 해당 AZ의 리소스가 EFS에 접근할 수 있습니다.
🚪 비유: '출입구'입니다. 각 건물(AZ)에 출입구가 있어야 창고(EFS)에 들어갈 수 있어요.
ECS Task에서 EFS 사용하기
Task Definition에서 EFS 볼륨을 정의하고, 컨테이너에 마운트합니다. 컨테이너 내에서 일반 파일 시스템처럼 사용할 수 있습니다.
📋 EFS + ECS 설정 단계: 1. EFS 파일 시스템 생성 2. Mount Target 생성 (각 AZ) 3. Security Group 설정 (NFS 2049 포트) 4. Task Definition에서: - Volumes: EFS 볼륨 추가 - Container: Mount point 지정 💡 컨테이너 내 경로 예: /mnt/efs/data
EFS Access Point
EFS 내 특정 디렉토리에 대한 접근을 관리하는 기능입니다. 애플리케이션별로 다른 디렉토리를 사용하도록 격리할 수 있습니다.
🗂️ 비유: '개인 사물함'입니다. 같은 창고지만 각자 지정된 사물함만 사용할 수 있어요.
실무 팁
- •EFS Security Group은 ECS Task Security Group에서 NFS(2049) 포트를 허용해야 합니다
- •성능이 중요하면 Provisioned Throughput 모드를 고려하세요
- •Access Point를 사용하면 컨테이너별로 다른 디렉토리를 격리할 수 있습니다
- •EFS는 S3보다 비용이 높으므로, 공유가 필요 없는 경우 S3를 사용하세요
Service Auto Scaling
ECS Service의 Desired Count를 자동으로 조절하는 기능입니다. 부하가 높으면 Task를 늘리고(Scale Out), 낮으면 줄입니다(Scale In).
🎚️ 비유: '자동 온도 조절기'입니다. 더우면 에어컨을 세게, 시원해지면 약하게 자동 조절해요.
Target Tracking Scaling
목표 값(예: CPU 70%)을 설정하면 AWS가 자동으로 Task 수를 조절하여 목표를 유지합니다. 가장 간단하고 권장되는 방식입니다.
🎯 비유: '크루즈 컨트롤'입니다. 목표 속도를 설정하면 자동으로 속도를 유지해요.
📊 Target Tracking 설정 예시: • 메트릭: ECSServiceAverageCPUUtilization • 목표 값: 70% • Scale-out cooldown: 60초 • Scale-in cooldown: 300초 → 평균 CPU가 70%를 넘으면 Task 추가 → 70% 미만이면 Task 감소
Step Scaling
CloudWatch 알람을 기반으로 단계별로 확장합니다. 예: CPU 70% 초과 시 +1, 90% 초과 시 +3. 더 세밀한 제어가 필요할 때 사용합니다.
📈 Step Scaling 예시: CPU 60-70%: Task 수 유지 CPU 70-80%: +1 Task CPU 80-90%: +2 Tasks CPU 90%+: +3 Tasks 💡 급격한 트래픽 증가에 빠르게 대응 가능
Scheduled Scaling
예측 가능한 트래픽 패턴에 맞춰 미리 Task 수를 조절합니다. 예: 매일 오전 9시에 Task를 5개로 늘리고, 오후 6시에 2개로 줄이기.
📅 비유: '예약 알람'입니다. 정해진 시간에 자동으로 설정이 바뀌어요.
콘솔에서 Auto Scaling 설정하기
ECS Service 설정에서 Auto Scaling을 구성합니다.
🖱️ 콘솔 설정 단계: 1. ECS 콘솔 → Clusters → 클러스터 선택 2. Services → 서비스 선택 → Update 3. Service auto scaling 섹션: - Use service auto scaling: 체크 - Minimum tasks: 2 - Maximum tasks: 10 4. Scaling policy: - Policy type: Target tracking - Policy name: cpu-tracking - ECS service metric: ECSServiceAverageCPUUtilization - Target value: 70 - Scale-out cooldown: 60 - Scale-in cooldown: 300 5. Update
Cooldown Period (쿨다운 기간)
스케일링 후 다음 스케일링까지 대기하는 시간입니다. 너무 짧으면 불필요한 스케일링이 발생하고, 너무 길면 대응이 느려집니다.
⏱️ Cooldown 권장 설정: • Scale-out cooldown: 60초 (빠른 확장) • Scale-in cooldown: 300초 (신중한 축소) 💡 Scale-in은 보수적으로 설정하세요. 너무 빨리 줄이면 다시 늘려야 할 수 있습니다.
실무 팁
- •Target Tracking으로 시작하세요. 대부분의 경우 충분합니다
- •Minimum tasks는 2 이상으로 설정하여 고가용성을 유지하세요
- •Scale-in cooldown은 Scale-out보다 길게 설정하세요 (불필요한 축소 방지)
- •ALB Request Count Per Target 메트릭도 유용합니다 (요청 기반 스케일링)
Capacity Provider
ECS 클러스터에 컴퓨팅 용량을 제공하는 방법을 정의합니다. Fargate, Fargate Spot, 또는 EC2 Auto Scaling Group을 Capacity Provider로 사용할 수 있습니다.
🏭 비유: '인력 공급 업체'입니다. 일손이 필요하면 자동으로 인력(인스턴스)을 공급해요.
📋 Capacity Provider 종류: • FARGATE: AWS 관리형 서버리스 • FARGATE_SPOT: 저렴한 Fargate (중단 가능) • EC2 Auto Scaling Group: 직접 관리하는 EC2 💡 Fargate 사용 시 Capacity Provider는 자동으로 설정되어 신경 쓸 필요 없습니다
Capacity Provider Strategy
여러 Capacity Provider를 조합하여 사용하는 전략입니다. 예: Fargate 70%, Fargate Spot 30%로 비용 최적화.
📊 Strategy 예시: 비용 최적화 전략: - FARGATE_SPOT: base=0, weight=3 - FARGATE: base=2, weight=1 → 최소 2개는 안정적인 Fargate → 추가 Task는 75%가 Spot으로 실행
EC2 Capacity Provider Auto Scaling
EC2 기반 ECS에서 Task 수요에 따라 EC2 인스턴스를 자동으로 추가/제거합니다. Auto Scaling Group과 연동됩니다.
🔄 EC2 Capacity Provider 동작: 1. Service가 Task 추가 요청 2. 클러스터에 용량 부족 감지 3. Capacity Provider가 ASG에 인스턴스 추가 요청 4. 새 EC2 인스턴스 시작 5. ECS Agent가 클러스터에 등록 6. Task 배치 및 실행
Managed Scaling
Capacity Provider가 자동으로 EC2 인스턴스 수를 관리하는 기능입니다. Target Capacity(목표 사용률)를 설정하면 AWS가 알아서 조절합니다.
⚙️ Managed Scaling 설정: • Status: Enabled • Target capacity: 100% (권장) • Minimum scaling step size: 1 • Maximum scaling step size: 10 💡 Target capacity 100%: Task가 필요한 만큼만 인스턴스 유지
실무 팁
- •Fargate를 사용하면 Capacity Provider 설정이 거의 필요 없습니다
- •EC2 사용 시 Managed Scaling을 활성화하면 인스턴스 관리가 자동화됩니다
- •Fargate Spot을 혼합하면 비용을 크게 절감할 수 있습니다 (최대 70%)
- •base 값으로 최소 안정적인 용량을 확보하고, weight로 비율을 조절하세요
Task가 시작되지 않을 때
Task가 PENDING 상태에서 멈추거나 바로 STOPPED 되는 경우입니다. 이미지 pull 실패, 리소스 부족, 네트워크 문제 등이 원인일 수 있습니다.
🔍 일반적인 원인과 해결:
1. 이미지 Pull 실패
원인: ECR 권한 없음, 이미지 URI 오타
해결: Execution Role에 ECR 권한 확인
이미지 URI 정확히 복사
2. 리소스 부족 (EC2 Launch Type)
원인: 클러스터에 CPU/메모리 부족
해결: 인스턴스 추가 또는 Task size 줄이기
3. 네트워크 문제
원인: VPC Endpoint 없음, Security Group 차단
해결: 필요한 Endpoint 생성, SG 규칙 확인CloudWatch Logs 확인하기
컨테이너의 stdout/stderr 출력이 CloudWatch Logs에 저장됩니다. 애플리케이션 오류, 시작 실패 원인 등을 확인할 수 있습니다.
📋 로그 확인 방법:
1. ECS 콘솔 → Clusters → 클러스터
2. Tasks 탭 → Task 선택
3. Logs 탭 클릭
4. 또는 CloudWatch 콘솔에서 직접:
Log groups → /ecs/{task-definition-name}
💡 로그가 없다면:
- Task Definition의 Log configuration 확인
- Execution Role에 logs:CreateLogStream,
logs:PutLogEvents 권한 확인Stopped Task 원인 확인
Task가 중지된 이유를 ECS 콘솔에서 확인할 수 있습니다. 'Stopped reason' 필드에 원인이 표시됩니다.
🛑 자주 보는 Stopped Reasons: • Essential container exited → 컨테이너가 종료됨 (앱 오류, 크래시) → 로그에서 오류 메시지 확인 • CannotPullContainerError → 이미지 pull 실패 → ECR 권한, 이미지 URI 확인 • ResourceNotFoundException → 리소스를 찾을 수 없음 → Secrets, 파라미터 등 확인 • OutOfMemoryError → 메모리 부족 → Task size 늘리기
ECS Exec으로 컨테이너 접속
실행 중인 컨테이너에 직접 접속하여 디버깅할 수 있습니다. SSH 없이 컨테이너 내부에서 명령어를 실행할 수 있습니다.
🔧 ECS Exec 사용법:
1. Task Definition에서 enableExecuteCommand: true
2. Task Role에 SSM 권한 추가
3. Service 업데이트 (Enable Execute Command)
# 컨테이너 접속
aws ecs execute-command \
--cluster demo-cluster \
--task {task-id} \
--container flask-container \
--interactive \
--command "/bin/sh"
💡 컨테이너 내부에서 직접 확인 가능:
환경 변수, 파일, 네트워크 연결 등Health Check 실패
ALB Health Check가 실패하면 Task가 unhealthy로 표시되고 트래픽을 받지 못합니다. 컨테이너는 실행 중이지만 서비스가 안 될 수 있습니다.
💓 Health Check 문제 해결: 1. Health Check 경로 확인 - 앱에서 해당 경로가 200 응답하는지 - 예: curl http://localhost:5000/health 2. 포트 매핑 확인 - Target Group 포트 = 컨테이너 포트 3. Security Group 확인 - ALB → Task 포트 허용되어 있는지 4. 시작 시간 고려 - Health Check Grace Period 늘리기 - 앱 시작에 시간이 걸리면 초기 실패 가능
유용한 디버깅 명령어
AWS CLI를 사용하여 ECS 리소스 상태를 확인하는 명령어들입니다.
🛠️ 디버깅 CLI 명령어:
# Task 목록 및 상태 확인
aws ecs list-tasks --cluster demo-cluster
aws ecs describe-tasks --cluster demo-cluster --tasks {task-id}
# 중지된 Task 원인 확인
aws ecs describe-tasks --cluster demo-cluster \
--tasks {task-id} \
--query 'tasks[0].stoppedReason'
# Service 이벤트 확인
aws ecs describe-services --cluster demo-cluster \
--services demo-service \
--query 'services[0].events[:5]'
# 최근 로그 확인
aws logs tail /ecs/demo-task --follow실무 팁
- •문제 발생 시 가장 먼저 CloudWatch Logs를 확인하세요
- •Task의 'Stopped reason'은 문제 해결의 첫 번째 단서입니다
- •ECS Exec을 활성화해두면 실시간 디버깅이 가능합니다
- •Health Check Grace Period를 충분히 설정하세요 (앱 시작 시간 고려)
- •Service Events에서 배포 실패, 스케일링 문제 등을 확인할 수 있습니다
워크샵 완료 후 생성한 리소스를 삭제하지 않으면 계속 비용이 발생합니다. 다음 순서로 삭제하세요:
- ECS Service 삭제 (desired count를 0으로 먼저 설정)
- ECS Cluster 삭제
- ALB 및 Target Group 삭제
- ECR Repository 삭제 (이미지 먼저 삭제)
- CloudWatch Log Group 삭제
- VPC 삭제 (연결된 리소스 자동 삭제)