☁️
클라우드
Fargate
AWS Fargate
서버리스 컨테이너 실행 서비스. 인프라 관리 없이 컨테이너 운영.
AWS Fargate
서버리스 컨테이너 실행 서비스. 인프라 관리 없이 컨테이너 운영.
AWS Fargate는 서버리스 컨테이너 컴퓨팅 엔진으로, EC2 인스턴스를 관리하지 않고도 컨테이너를 실행할 수 있습니다. ECS(Elastic Container Service)와 EKS(Elastic Kubernetes Service) 모두에서 사용 가능하며, 태스크/Pod 단위로 리소스를 할당하고 과금합니다.
Fargate의 핵심 특징:
리소스 구성 옵션:
# 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
}
}