☁️ 클라우드

Fargate

AWS Fargate

서버리스 컨테이너 실행 서비스. 인프라 관리 없이 컨테이너 운영.

상세 설명

AWS Fargate는 서버리스 컨테이너 컴퓨팅 엔진으로, EC2 인스턴스를 관리하지 않고도 컨테이너를 실행할 수 있습니다. ECS(Elastic Container Service)와 EKS(Elastic Kubernetes Service) 모두에서 사용 가능하며, 태스크/Pod 단위로 리소스를 할당하고 과금합니다.

Fargate의 핵심 특징:

  • 서버리스: 서버 프로비저닝, OS 패치, 클러스터 관리가 필요 없음
  • 세밀한 과금: vCPU/메모리 사용량 기준 초 단위 과금 (최소 1분)
  • 보안 격리: 각 태스크가 자체 커널에서 실행되어 완전 격리
  • AWS 통합: VPC, IAM, CloudWatch, ALB/NLB 네이티브 통합

리소스 구성 옵션:

  • vCPU: 0.25 ~ 16 vCPU (0.25 단위)
  • 메모리: 0.5GB ~ 120GB (vCPU에 따라 범위 제한)
  • Ephemeral Storage: 기본 20GB, 최대 200GB까지 확장 가능
  • Fargate Spot: 최대 70% 할인, 중단 가능한 워크로드용

코드 예제

# ECS Fargate 클러스터 생성 aws ecs create-cluster --cluster-name my-fargate-cluster # Task Definition 등록 (Fargate용) cat > task-definition.json <<'EOF' { "family": "my-web-app", "networkMode": "awsvpc", "requiresCompatibilities": ["FARGATE"], "cpu": "256", "memory": "512", "executionRoleArn": "arn:aws:iam::123456789:role/ecsTaskExecutionRole", "taskRoleArn": "arn:aws:iam::123456789:role/ecsTaskRole", "containerDefinitions": [ { "name": "web", "image": "nginx:latest", "portMappings": [ { "containerPort": 80, "protocol": "tcp" } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/my-web-app", "awslogs-region": "ap-northeast-2", "awslogs-stream-prefix": "ecs" } }, "essential": true } ] } EOF aws ecs register-task-definition --cli-input-json file://task-definition.json # Fargate 서비스 생성 aws ecs create-service \ --cluster my-fargate-cluster \ --service-name my-web-service \ --task-definition my-web-app:1 \ --desired-count 3 \ --launch-type FARGATE \ --network-configuration "awsvpcConfiguration={ subnets=[subnet-1234,subnet-5678], securityGroups=[sg-1234], assignPublicIp=ENABLED }" \ --load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=web,containerPort=80" # Fargate Spot 사용 (비용 절감) aws ecs create-service \ --cluster my-fargate-cluster \ --service-name batch-service \ --capacity-provider-strategy "capacityProvider=FARGATE_SPOT,weight=4" \ --capacity-provider-strategy "capacityProvider=FARGATE,weight=1"
# EKS에서 Fargate 프로파일 생성 eksctl create fargateprofile \ --cluster my-cluster \ --name fp-default \ --namespace default \ --namespace kube-system # 특정 레이블 기반 Fargate 프로파일 eksctl create fargateprofile \ --cluster my-cluster \ --name fp-production \ --namespace production \ --labels "compute=fargate" # Fargate에서 실행할 Pod 배포 cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: web-fargate namespace: default labels: compute: fargate # Fargate 프로파일 매칭 spec: replicas: 3 selector: matchLabels: app: web template: metadata: labels: app: web compute: fargate spec: containers: - name: web image: nginx:latest ports: - containerPort: 80 resources: # Fargate는 requests 기반으로 리소스 할당 requests: cpu: "256m" memory: "512Mi" limits: cpu: "512m" memory: "1Gi" --- apiVersion: v1 kind: Service metadata: name: web-service annotations: service.beta.kubernetes.io/aws-load-balancer-type: nlb spec: type: LoadBalancer selector: app: web ports: - port: 80 targetPort: 80 EOF # Fargate Pod 확인 kubectl get pods -o wide # NODE 컬럼에 fargate-ip-xxx 형식으로 표시 # Fargate 리소스 사용량 확인 kubectl top pods
# Terraform ECS Fargate 구성 resource "aws_ecs_cluster" "main" { name = "my-fargate-cluster" setting { name = "containerInsights" value = "enabled" } # Capacity Provider 설정 configuration { execute_command_configuration { logging = "OVERRIDE" log_configuration { cloud_watch_log_group_name = aws_cloudwatch_log_group.ecs_exec.name } } } } # Fargate Capacity Provider 연결 resource "aws_ecs_cluster_capacity_providers" "main" { cluster_name = aws_ecs_cluster.main.name capacity_providers = ["FARGATE", "FARGATE_SPOT"] default_capacity_provider_strategy { base = 1 # 최소 1개는 FARGATE weight = 1 capacity_provider = "FARGATE" } default_capacity_provider_strategy { base = 0 weight = 4 # 80%는 FARGATE_SPOT capacity_provider = "FARGATE_SPOT" } } # Task Definition resource "aws_ecs_task_definition" "app" { family = "my-app" network_mode = "awsvpc" requires_compatibilities = ["FARGATE"] cpu = 256 memory = 512 execution_role_arn = aws_iam_role.ecs_execution.arn task_role_arn = aws_iam_role.ecs_task.arn # Ephemeral Storage 확장 (기본 20GB) ephemeral_storage { size_in_gib = 50 } container_definitions = jsonencode([ { name = "app" image = "${aws_ecr_repository.app.repository_url}:latest" portMappings = [{ containerPort = 8080 protocol = "tcp" }] environment = [ { name = "ENV", value = "production" } ] secrets = [ { name = "DB_PASSWORD" valueFrom = aws_secretsmanager_secret.db_password.arn } ] logConfiguration = { logDriver = "awslogs" options = { "awslogs-group" = "/ecs/my-app" "awslogs-region" = "ap-northeast-2" "awslogs-stream-prefix" = "ecs" } } } ]) } # Fargate 서비스 resource "aws_ecs_service" "app" { name = "my-app-service" cluster = aws_ecs_cluster.main.id task_definition = aws_ecs_task_definition.app.arn desired_count = 3 # Fargate Spot 혼합 전략 capacity_provider_strategy { capacity_provider = "FARGATE" weight = 1 base = 1 # 최소 1개는 안정적인 FARGATE } capacity_provider_strategy { capacity_provider = "FARGATE_SPOT" weight = 4 # 나머지 80%는 Spot } network_configuration { subnets = var.private_subnets security_groups = [aws_security_group.app.id] assign_public_ip = false } load_balancer { target_group_arn = aws_lb_target_group.app.arn container_name = "app" container_port = 8080 } # Auto Scaling 연동 lifecycle { ignore_changes = [desired_count] } } # Application Auto Scaling resource "aws_appautoscaling_target" "ecs" { max_capacity = 20 min_capacity = 2 resource_id = "service/${aws_ecs_cluster.main.name}/${aws_ecs_service.app.name}" scalable_dimension = "ecs:service:DesiredCount" service_namespace = "ecs" } resource "aws_appautoscaling_policy" "cpu" { name = "cpu-target-tracking" policy_type = "TargetTrackingScaling" resource_id = aws_appautoscaling_target.ecs.resource_id scalable_dimension = aws_appautoscaling_target.ecs.scalable_dimension service_namespace = aws_appautoscaling_target.ecs.service_namespace target_tracking_scaling_policy_configuration { predefined_metric_specification { predefined_metric_type = "ECSServiceAverageCPUUtilization" } target_value = 50.0 } }

실무 대화 예시

아키텍처 선택 회의
"EC2 vs Fargate 어떤 걸 써야 하나요?" "운영 부담 최소화하려면 Fargate입니다. OS 패치, 보안 업데이트, 클러스터 용량 관리 다 AWS가 해줘요. 다만 vCPU당 단가는 EC2보다 20-30% 비싸요. 운영 인력 비용까지 감안하면 소규모 팀은 Fargate가 TCO가 낮고, 대규모면 EC2가 유리합니다."
비용 최적화 논의
"Fargate 비용을 줄이는 방법이 있나요?" "세 가지 방법이 있습니다. 첫째, Fargate Spot은 최대 70% 저렴하니까 배치 작업, 개발 환경에 활용하세요. 둘째, 리소스 사이징을 정확히 하세요. 256 CPU/512MB 최소 단위부터 시작해서 실제 사용량 보고 조정하면 됩니다. 셋째, ARM64(Graviton) 사용하면 20% 추가 절감됩니다."
마이그레이션 검토
"기존 EC2 기반 ECS를 Fargate로 전환하려는데 고려사항이 있나요?" "네, 몇 가지 있어요. Docker 볼륨 마운트 대신 EFS나 S3 사용해야 하고, 호스트 네트워크 모드는 awsvpc로 변경 필요합니다. DaemonSet 패턴은 사이드카로 바꿔야 해요. 그리고 GPU 워크로드는 Fargate에서 안 됩니다."
면접 질문
"Fargate와 Lambda의 차이점은 뭔가요?" "둘 다 서버리스지만 용도가 다릅니다. Lambda는 이벤트 기반 단발성 함수 실행에 적합하고 최대 15분 제한이 있어요. Fargate는 지속 실행되는 컨테이너 워크로드용입니다. API 서버, 백그라운드 워커처럼 항상 떠 있어야 하는 서비스는 Fargate, 트리거 기반 짧은 작업은 Lambda가 맞습니다."

주의사항

⚠️
콜드 스타트: Fargate 태스크 시작에 30초~1분 소요됩니다. Scale Out 시 지연이 있으니 Scheduled Scaling으로 미리 확장하거나 최소 태스크 수를 확보하세요.
⚠️
DaemonSet 미지원: EKS Fargate에서 DaemonSet은 작동하지 않습니다. Fluent Bit 같은 로깅 에이전트는 사이드카 컨테이너로 배포하세요.
⚠️
리소스 제한: 최대 4 vCPU/30GB(EKS) 또는 16 vCPU/120GB(ECS) 제한이 있습니다. 대용량 컴퓨팅은 EC2 사용을 검토하세요.
⚠️
Fargate Spot 중단: 2분 전 SIGTERM 알림 후 종료됩니다. Graceful Shutdown 구현하고, 중요 워크로드는 일반 Fargate와 혼합 사용하세요.

관련 용어

더 배우기