쿠버네티스 vs 서버리스 2026: 아무도 안 알려주는 솔직한 선택 가이드
해커뉴스에서 몇 달 간격으로 반복되는 패턴 있잖아요. "서버리스 접고 쿠버네티스로 돌아왔습니다" — 추천 500개. 일주일 뒤에 "쿠버네티스 접고 서버리스로 갔더니 비용 60% 줄었습니다" — 또 추천 500개. 둘 다 맞는 말이고, 둘 다 틀린 말이에요.
이 논쟁 2018년부터 계속됐는데, 2026년은 진짜 판이 달라졌어요. Wasm 기반 서버리스(Serverless 2.0)가 콜드 스타트 문제를 거의 없애버렸고, 쿠버네티스 오토스케일링은 드디어 제대로 돌아가고, 하이브리드 아키텍처가 둘 사이 경계를 허물고 있거든요.
이 글에서 "뭐가 더 좋다" 같은 결론은 안 내릴 거예요. 그 대신 여러분 상황에 딱 맞는 판단 기준을 알려드릴게요. 팀이 몇 명인지, 트래픽이 어떻게 생겼는지, 예산은 얼마인지, 새벽 3시 장애 알림을 얼마나 견딜 수 있는지까지 다 따져요.
핵심 트레이드오프 (아무도 명확히 말 안 해주는 것)
한 줄로 요약하면:
쿠버네티스는 복잡한 만큼 내가 다 컨트롤할 수 있어요. 서버리스는 컨트롤을 포기하는 만큼 단순해요.
나머지는 전부 디테일인데, 이 디테일이 진짜 중요해요. 하나씩 뜯어볼게요.
실제로 뭘 선택하는 건지
쿠버네티스: 서버리스:
┌─────────────────────────┐ ┌─────────────────────────┐
│ 내가 관리하는 것: │ │ 내가 관리하는 것: │
│ ├── 노드 │ │ ├── 함수/코드 │
│ ├── 네트워킹 │ │ └── 설정 │
│ ├── 스케일링 정책 │ │ │
│ ├── 서비스 메시 │ │ 클라우드가 관리: │
│ ├── 인그레스 │ │ ├── 서버 │
│ ├── 스토리지 │ │ ├── 스케일링 │
│ ├── 모니터링 │ │ ├── 네트워킹 │
│ └── 보안 패치 │ │ ├── 패치 │
│ │ │ └── 가용성 │
│ 클라우드가 관리: │ │ │
│ └── 물리 머신 │ │ 대신 잃는 것: │
│ │ │ ├── 런타임 통제권 │
│ 대신 얻는 것: │ │ ├── 실행 시간 제한 │
│ ├── 완전한 통제권 │ │ ├── 로컬 환경 동일성 │
│ ├── 아무 런타임이나 │ │ └── 벤더 이식성 │
│ ├── 로컬 환경 동일 │ └─────────────────────────┘
│ └── 벤더 이식성 │
└─────────────────────────┘
기술을 고르는 게 아니라 조직이 어떻게 일할지를 고르는 거예요.
2026년 쿠버네티스: 뭐가 달라졌나
쿠버네티스 많이 성숙해졌어요. "너무 복잡하다"는 비판, 2년 전엔 할 말 없었는데 이제는 좀 다릅니다.
좋아진 점: 진짜 쉬워졌어요
1. 매니지드 쿠버네티스가 거의 고통 없는 수준
대형 클라우드들이 운영 부담을 엄청 줄여놨어요:
# EKS Auto Mode (AWS) - 2024년 말 출시 # 노드 그룹, AMI, 인스턴스 타입 관리 안 해도 됨 apiVersion: eks.amazonaws.com/v1 kind: NodeClass metadata: name: default spec: # EKS가 다 해줌: 인스턴스 선택, AMI 업데이트, # 스케일링, OS 패치, GPU 스케줄링 role: arn:aws:iam::123456789:role/eks-node-role
- EKS Auto Mode: AWS가 노드, AMI, 스케일링, 네트워킹 관리. 우리는 파드만 배포.
- GKE Autopilot: 구글의 풀매니지드 K8s. 노드가 아니라 파드 단위로 과금.
- AKS Automatic: 애저 버전. 베스트 프랙티스 자동 적용, 오토 스케일링, 오토 패치.
2. 생태계가 정리됨
2022년에는 서비스 메시, 인그레스, 모니터링 스택 고르는 게 연구 프로젝트였어요. 2026년에는:
| 컴포넌트 | 사실상 표준 | 이유 |
|---|---|---|
| 서비스 메시 | Istio (ambient mode) | 사이드카 없어짐, 성능 개선 |
| 인그레스 | Gateway API | 공식 K8s 표준 |
| 모니터링 | OpenTelemetry + Grafana | 벤더 중립, 통합 추적/메트릭/로그 |
| GitOps | ArgoCD | 성숙함, 선언적, UI 좋음 |
| 보안 | Kyverno | Policy-as-code, OPA보다 쉬움 |
3. 스케일링이 이제 진짜 동작함
# KEDA (Kubernetes Event-Driven Autoscaling) # CPU가 아니라 실제 수요에 따라 스케일 apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: order-processor spec: scaleTargetRef: name: order-processor minReplicaCount: 0 # 제로까지 스케일! maxReplicaCount: 100 triggers: - type: kafka metadata: topic: orders lagThreshold: "10" # 큐 깊이 기반 스케일 - type: prometheus metadata: query: rate(http_requests_total{service="orders"}[2m]) threshold: "100" # 파드당 100 req/s에서 스케일
KEDA 진짜 게임 체인저예요. 쿠버네티스 배포를 0대까지 줄일 수 있고, CPU/메모리가 아니라 카프카 랙이나 SQS 깊이, 프로메테우스 메트릭 같은 실제 이벤트 기준으로 스케일해요. 서버리스 최대 장점 중 하나인 "안 쓰면 0원"이 쿠버네티스에서도 되기 시작한 거죠.
아픈 점: 여전히 고통스러운 것들
1. 쿠버네티스의 "숨은 세금"
쿠버네티스 실제 비용? 아무도 솔직하게 안 알려줘요. 클라우드 청구서에 찍히는 숫자가 전부가 아니거든요:
쿠버네티스의 진짜 비용:
┌───────────────────────────────────────────────────┐
│ │
│ 클라우드 청구서 (보이는 것): $5,000/월 │
│ ────────────────────────────────────────────── │
│ 플랫폼 엔지니어 인건비 (1명): $12,000/월 │
│ 네트워킹 플러그인/도구: $800/월 │
│ 모니터링 (Datadog/Grafana Cloud): $1,200/월 │
│ 보안 스캔 (Snyk/Trivy): $400/월 │
│ CI/CD 파이프라인 유지: $600/월 │
│ 장애 대응 시간: $1,000/월 │
│ 교육/스킬업: $500/월 │
│ ────────────────────────────────────────────── │
│ 실제 총합: $21,500/월 │
│ │
│ $5K 쓰고 있다고 생각하지만 │
│ 실제로는 $21.5K 쓰고 있어요. │
└───────────────────────────────────────────────────┘
2. YAML 산맥
서비스 하나를 프로덕션에 올리려면 YAML을 얼마나 써야 하는지 보면 기가 차요:
# 마이크로서비스 하나에 필요한 것: # - Deployment (파드 템플릿, 레플리카, 리소스, 프로브) # - Service (네트워킹) # - Ingress/Gateway (외부 접근) # - HPA 또는 KEDA ScaledObject (오토스케일링) # - PodDisruptionBudget (가용성) # - NetworkPolicy (보안) # - ServiceAccount + RBAC (권한) # - ConfigMap + Secret (설정) # - PersistentVolumeClaim (상태 저장이면) # # 마이크로서비스 하나에 YAML 파일 9개 이상. # 마이크로서비스 20개면 YAML 파일 180개 이상 유지.
3. 디버깅은 아직 고통
# "파드가 왜 안 뜨지?" # 1단계: 파드 상태 확인 kubectl get pods -n production | grep -v Running # 2단계: 문제 파드 상세 확인 kubectl describe pod order-service-7d8f9c-x2k4n -n production # 3단계: 이벤트 확인 kubectl get events -n production --sort-by='.lastTimestamp' | tail -20 # 4단계: 로그 확인 kubectl logs order-service-7d8f9c-x2k4n -n production --previous # 5단계: 리소스 쿼터 확인 kubectl describe resourcequota -n production # 6단계: 노드 압박 확인 kubectl describe node | grep -A5 "Conditions" # 7단계: 포기하고 다 재시작 (다 해봤잖아요) kubectl rollout restart deployment order-service -n production
2026년 서버리스: 뭐가 달라졌나
서버리스가 "5분짜리 256MB 람다 함수" 시대에서 엄청 진화했어요.
좋아진 점: 이제 람다만 있는 게 아님
1. Serverless 2.0: WebAssembly가 판을 바꿈
서버리스 발명 이래 가장 큰 변화: Wasm 기반 서버리스 런타임.
기존 서버리스(AWS Lambda, Cloud Functions)에는 근본적인 문제가 있었어요:
- 콜드 스타트: 새 컨테이너 뜨는 데 100ms~3초
- 벤더 종속: 람다 코드가 Cloud Functions에서 안 돌아감
- 런타임 제한: 클라우드가 지원하는 언어만 가능
Wasm 기반 서버리스가 세 가지 다 해결:
기존 서버리스: Wasm 기반 서버리스:
┌─────────────────────────┐ ┌──────────────────────────┐
│ 콜드 스타트: 100ms-3s │ │ 콜드 스타트: <1ms │
│ 런타임: Node/Python │ │ 런타임: 아무 언어나 │
│ 바이너리: ~200MB │ │ 바이너리: ~2MB │
│ 벤더: AWS 전용 │ │ 벤더: 이식 가능 │
│ 격리: 컨테이너 │ │ 격리: Wasm 샌드박스 │
│ 스케일: 초 단위 │ │ 스케일: 마이크로초 단위 │
└─────────────────────────┘ └──────────────────────────┘
Cloudflare Workers가 2018년부터 이걸 해왔어요. 2026년에는 Fermyon Spin, Fastly Compute, 심지어 AWS Lambda with Wasm으로 본격 주류가 됐어요:
// Spin 서버리스 함수 (Fermyon) // 콜드 스타트: <1ms. 바이너리 크기: ~2MB. use spin_sdk::http::{IntoResponse, Request, Response}; use spin_sdk::http_component; #[http_component] fn handle_request(req: Request) -> anyhow::Result<impl IntoResponse> { let uri = req.uri().to_string(); // HTTP 서버, 파일 접근, 아웃바운드 HTTP 다 됨 // 2MB 미만 Wasm 바이너리에서 Ok(Response::builder() .status(200) .header("content-type", "application/json") .body(format!(r#"{{"path": "{}","runtime": "wasm"}}"#, uri)) .build()) }
2. Step Functions와 워크플로우
장시간 실행 프로세스는 서버리스의 약점이었어요. 이제는:
// AWS Step Functions - 복잡한 워크플로우 오케스트레이션 { "StartAt": "ValidateOrder", "States": { "ValidateOrder": { "Type": "Task", "Resource": "arn:aws:lambda:validate-order", "Next": "CheckInventory", "Retry": [{"ErrorEquals": ["ServiceUnavailable"], "MaxAttempts": 3}] }, "CheckInventory": { "Type": "Choice", "Choices": [ { "Variable": "$.inStock", "BooleanEquals": true, "Next": "ProcessPayment" } ], "Default": "NotifyBackorder" }, "ProcessPayment": { "Type": "Task", "Resource": "arn:aws:lambda:process-payment", "TimeoutSeconds": 300, "Next": "ShipOrder" }, "ShipOrder": { "Type": "Task", "Resource": "arn:aws:lambda:ship-order", "End": true } } }
3. 쓴 만큼만 과금, 이게 진짜로 됨
가끔만 돌아가는 워크로드? 서버리스 비용 구조를 이길 방법이 없어요:
시나리오: 월 10만 건 처리하는 API
평균 실행: 200ms
메모리: 256MB
AWS Lambda 비용:
컴퓨트: 100,000 × 0.2s × 256MB = $0.33/월
요청: 100,000 × $0.20/백만 = $0.02/월
합계: $0.35/월
Kubernetes (EKS) 비용:
컨트롤 플레인: $73/월
t3.medium 노드 2개: $60/월
로드 밸런서: $16/월
합계: $149/월
쿠버네티스가 425배 더 비쌈!
아픈 점: 숨은 비용이 진짜라는 것
1. 서버리스 청구서 쇼크
쓴 만큼 내는 과금 모델, 잘 될 때는 완벽한데 터지면 한 번에 터져요:
시나리오: 월 5천만 건 처리하는 API
평균 실행: 500ms
메모리: 1024MB
AWS Lambda 비용:
컴퓨트: 5천만 × 0.5s × 1GB = $417/월
요청: 5천만 × $0.20/백만 = $10/월
API Gateway: 5천만 × $3.50/백만 = $175/월 ← 숨은 비용!
CloudWatch 로그: ~50GB = $25/월 ← 숨은 비용!
NAT Gateway (VPC 쓸 때): $45/월 + 데이터 ← 숨은 비용!
합계: ~$672/월 (선형으로 계속 증가)
Kubernetes 비용:
c5.xlarge 노드 3개: $370/월
컨트롤 플레인: $73/월
로드 밸런서: $16/월
합계: $459/월 (고정)
서버리스가 46% 더 비쌈!
2. 로컬 개발이 아직 고통
# 쿠버네티스: 로컬에서 똑같이 실행 docker-compose up # 또는 minikube start && kubectl apply -f k8s/ # 서버리스: 행운을 빕니다 # 옵션 A: SAM Local (느림, 불완전) sam local start-api # 옵션 B: serverless-offline (Node.js 전용, 기능 부족) npx serverless offline # 옵션 C: LocalStack (무거움, 어차피 Docker 필요) docker run localstack/localstack # 옵션 D: 그냥 dev 스테이지에 배포하고 기도 serverless deploy --stage dev # 어느 것도 프로덕션이랑 똑같이 동작 안 함.
3. 벤더 종속이 생각보다 깊음
# 이렇게 보면 이식성 있어 보이죠... def handler(event, context): return {"statusCode": 200, "body": "Hello"} # ...실제로 작성한 건 이거예요: import boto3 # AWS SDK from aws_lambda_powertools import Logger # AWS 전용 from aws_lambda_powertools.event_handler import APIGatewayRestResolver app = APIGatewayRestResolver() logger = Logger() dynamodb = boto3.resource('dynamodb') # AWS DynamoDB table = dynamodb.Table('orders') # AWS 전용 sns = boto3.client('sns') # AWS SNS # "이식 가능한 함수"라고 생각했는데 실제로 엮인 것들: # - API Gateway 이벤트 포맷 # - DynamoDB # - SNS # - CloudWatch Logs # - IAM 역할 # - VPC 설정 # 이거 GCP로 옮기려고요? 80% 새로 짜야 해요.
의사결정 프레임워크: 실전 가이드
마케팅 용어 다 빼고, 실무에서 어떻게 결정하는지 알려드릴게요.
팩터 1: 팀 규모와 역량
팀 규모: 추천:
────────────── ────────────────────────────────
1-3명 서버리스 (플랫폼 팀 인건비 감당 못 함)
4-8명 다른 팩터에 따라 다름
8-15명 둘 다 가능, 플랫폼 엔지니어 있으면 K8s
15명+ 쿠버네티스 (통제권 필요하고 감당 가능)
역량 매트릭스:
──────────────────────────────────────────────────
DevOps/인프라 팀 있음? → 쿠버네티스
대부분 프로덕트 엔지니어? → 서버리스
둘 다 섞여 있음? → 하이브리드
팩터 2: 트래픽 패턴
트래픽 패턴: 적합한 선택:
────────────────────────────────── ──────────────
24/7 안정적 (이커머스, SaaS) 쿠버네티스
스파이크 (마케팅 캠페인) 서버리스
이벤트 기반 (IoT, 웹훅) 서버리스
배치 처리 (ETL, ML) 둘 다 가능
실시간 (WebSocket, 게이밍) 쿠버네티스
예측 불가 (스타트업, MVP) 서버리스
팩터 3: 애플리케이션 아키텍처
# 여러분 앱에 점수를 매겨보세요: def should_use_kubernetes(app): score = 0 # 아키텍처 if app.has_stateful_services: score += 3 if app.needs_persistent_connections: score += 3 # WebSocket, gRPC if app.needs_gpu: score += 5 if app.has_long_running_tasks: score += 2 # 15분 이상 if app.microservices_count > 10: score += 2 if app.needs_custom_networking: score += 3 # 운영 if app.team_has_platform_eng: score += 3 if app.needs_multi_cloud: score += 4 if app.needs_on_premise: score += 5 if app.has_strict_compliance: score += 2 # 경제성 if app.requests_per_month > 50_million: score += 3 if app.execution_time_avg > 10_seconds: score += 2 if app.budget_predictability_required: score += 2 return score # 점수 해석: # 0-8: 서버리스로 가세요 # 9-15: 하이브리드 접근 # 16+: 쿠버네티스로 가세요
팩터 4: 비용 역전 포인트 분석
제일 많이 받는 질문이에요. "트래픽 얼마부터 쿠버네티스가 더 싸요?"
월 요청 Lambda 비용 EKS 비용 승자
───────────────── ─────────── ───────── ──────────
10만 $0.35 $149 Lambda (425배)
100만 $3.50 $149 Lambda (42배)
1000만 $35 $149 Lambda (4배)
5000만 $672 $459 EKS (1.5배)
1억 $1,340 $459 EKS (2.9배)
5억 $6,700 $920 EKS (7.3배)
크로스오버 포인트: 월 ~3000-4000만 요청
(평균 200ms 실행, 256MB 메모리 기준)
⚠️ 이 숫자는 조건에 따라 크게 바뀌어요:
- 실행 시간 (오래 걸릴수록 Lambda가 비싸짐)
- 메모리 (많이 쓸수록 Lambda가 비싸짐)
- API Gateway 비용 (이것만으로 Lambda 비용이 2배)
- Reserved Concurrency 가격
- EKS 노드를 얼마나 빡빡하게 쓰느냐
하이브리드 아키텍처: 둘 다 쓰기
실제로 2026년에 대부분의 팀은 하나만 올인하지 않아요. 둘 다 써요.
잘 동작하는 패턴
┌──────────────────────────────────────────────────────┐
│ 여러분의 앱 │
│ │
│ ┌─────────────────────┐ ┌────────────────────────┐ │
│ │ 쿠버네티스 코어 │ │ 서버리스 엣지 │ │
│ │ │ │ │ │
│ │ ● API Gateway │ │ ● 이미지 프로세싱 │ │
│ │ ● 유저 서비스 │ │ ● PDF 생성 │ │
│ │ ● 주문 서비스 │ │ ● 이메일 발송 │ │
│ │ ● 결제 서비스 │ │ ● 웹훅 핸들러 │ │
│ │ ● 데이터베이스 │ │ ● 크론 작업 │ │
│ │ ● 캐시 (Redis) │ │ ● 인증 콜백 │ │
│ │ ● 검색 (ES) │ │ ● 파일 업로드 처리 │ │
│ │ ● WebSocket 서버 │ │ ● 데이터 ETL 파이프 │ │
│ │ │ │ ● 로그 집약 │ │
│ │ (안정적, 상태 있음, │ │ │ │
│ │ 장기 실행) │ │ (스파이크, 상태 없음, │ │
│ │ │ │ 단기 실행) │ │
│ └─────────────────────┘ └────────────────────────┘ │
│ │ │ │
│ └──── Event Bridge ──────┘ │
└──────────────────────────────────────────────────────┘
하이브리드 실전 구현 예시
# 쿠버네티스: 핵심 주문 처리 서비스 # 24/7 실행, WebSocket 연결 유지, 상태 필요 apiVersion: apps/v1 kind: Deployment metadata: name: order-service namespace: production spec: replicas: 3 selector: matchLabels: app: order-service template: metadata: labels: app: order-service spec: containers: - name: order-service image: myapp/order-service:v2.3.1 resources: requests: cpu: "500m" memory: "512Mi" limits: cpu: "1000m" memory: "1Gi" ports: - containerPort: 8080 readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 15 env: - name: DATABASE_URL valueFrom: secretKeyRef: name: db-credentials key: url
# 서버리스: S3 업로드 트리거 이미지 처리 # 시간당 0-1000번. Lambda에 딱이에요. import boto3 from PIL import Image import io def handler(event, context): s3 = boto3.client('s3') bucket = event['Records'][0]['s3']['bucket']['name'] key = event['Records'][0]['s3']['object']['key'] # 원본 이미지 다운로드 response = s3.get_object(Bucket=bucket, Key=key) image = Image.open(io.BytesIO(response['Body'].read())) # 썸네일 생성 sizes = [(150, 150), (300, 300), (600, 600)] for width, height in sizes: thumb = image.copy() thumb.thumbnail((width, height)) buffer = io.BytesIO() thumb.save(buffer, 'JPEG', quality=85) buffer.seek(0) s3.put_object( Bucket=bucket, Key=f"thumbnails/{width}x{height}/{key}", Body=buffer, ContentType='image/jpeg' ) return {"statusCode": 200, "generated": len(sizes)}
하이브리드가 복잡해지는 순간
하이브리드도 공짜가 아니에요. 이것도 나름의 고통이 있거든요:
하이브리드 복잡성 함정:
1. 배포 시스템을 두 개 유지해야 함
K8s: ArgoCD + Helm 차트
서버리스: SAM/CDK + CloudFormation
→ CI/CD 파이프라인이 2배로 복잡해짐
2. 모니터링 시스템도 두 개
K8s: Prometheus + Grafana
서버리스: CloudWatch + X-Ray
→ 둘 사이에 걸친 이슈 추적이 고통
3. 네트워킹 연결
K8s 파드 → Lambda: VPC 설정 또는 API Gateway 필요
Lambda → K8s 서비스: VPC, NAT Gateway ($$$)
→ NAT Gateway만으로 월 $100+
4. 팀의 멘탈 모델이 두 개
"이 코드 어디서 돌아가는 거지?"
"이 Lambda가 K8s 서비스 호출할 때 왜 타임아웃이야?"
→ 엔지니어한테 컨텍스트 스위칭 세금
해결법: 이벤트 버스(EventBridge, Kafka)를 K8s랑 서버리스 사이에 끼우세요. 직접 호출 대신 이벤트로 연결하면 네트워킹 복잡성이 확 줄어요.
2026년의 와일드카드: Wasm 기반 서버리스
제일 재밌는 흐름은 WebAssembly가 서버리스 런타임으로 자리 잡고 있다는 거예요. 쿠버네티스도 서버리스도 아닌 세 번째 길이 열린 거죠.
작동 원리
기존 클라우드:
요청 → API Gateway → 콜드 스타트 컨테이너 → 코드 실행 → 응답
지연: 100ms - 3000ms (콜드) / 5ms - 50ms (웜)
Wasm 서버리스:
요청 → 엣지 노드 → Wasm 인스턴스화 → 코드 실행 → 응답
지연: <1ms (항상 콜드 스타트 속도)
누가 하고 있나
| 플랫폼 | 런타임 | 상태 (2026년 2월) |
|---|---|---|
| Cloudflare Workers | V8 Isolates + Wasm | 프로덕션, 300+ 데이터 센터 |
| Fermyon Spin | Wasmtime | 프로덕션, Fermyon Cloud GA |
| Fastly Compute | Wasmtime | 프로덕션 |
| Cosmonic (wasmCloud) | wasmtime | 프로덕션, CNCF 프로젝트 |
| AWS Lambda | 커스텀 Wasm 런타임 | 프리뷰 |
양쪽 최고만 모은 것
쿠버네티스 서버리스 Wasm 서버리스
────────── ────────── ───────────────
콜드 스타트 N/A 100ms-3s <1ms
벤더 종속 낮음 높음 낮음 (Wasm 표준)
로컬 개발 쉬움 어려움 쉬움
제로 스케일 KEDA로 네이티브 네이티브
최대 실행 시간 무제한 15분 다양 (1-30분)
상태 유지 완전 없음 제한적
저규모 비용 높음 매우 낮음 매우 낮음
고규모 비용 보통 높음 낮음
바이너리 이식성 Docker 이미지 없음 Wasm 컴포넌트
GPU 지원 가능 제한적 불가
같은 함수를 세 플랫폼에서
// 이 Rust 코드는 Wasm으로 컴파일돼서 이것들 위에서 돌아감: // - Fermyon Spin (서버리스) // - wasmCloud (오케스트레이션, K8s 비슷) // - Cloudflare Workers (엣지) // - 내 노트북 (wasmtime) // // 바이너리 하나. 벤더 종속 제로. use spin_sdk::http::{IntoResponse, Request, Response}; use spin_sdk::http_component; #[http_component] fn handle_api(req: Request) -> anyhow::Result<impl IntoResponse> { match req.uri().path() { "/api/orders" => handle_orders(req), "/api/health" => Ok(Response::builder() .status(200) .body("ok") .build()), _ => Ok(Response::builder() .status(404) .body("not found") .build()), } }
여기가 진짜 변곡점이에요. 2024년까지는 "이식성을 원하면 복잡한 쿠버네티스", "단순함을 원하면 종속되는 서버리스" 이 둘 중 하나였거든요. 2026년에는 Wasm 기반 서버리스가 이식성이랑 단순함 둘 다 가져가요.
흔한 실수 (그리고 피하는 법)
실수 1: "마이크로서비스 하니까 쿠버네티스 필요해"
아니에요. 마이크로서비스는 조직 패턴이지 배포 선택이 아니에요. 서버리스에서 마이크로서비스 완벽하게 돌리는 회사 많아요.
흔한 가정:
마이크로서비스 → 컨테이너 오케스트레이션 필요 → 쿠버네티스
현실:
마이크로서비스 → 독립 배포와 스케일링 필요
→ K8s 파드든, Lambda 함수든, Wasm 컴포넌트든 가능
실수 2: "서버리스가 항상 더 싸다"
위에서 계산해봤잖아요. 서버리스가 싼 건 트래픽 적을 때뿐이에요. 월 3000~4000만 요청 넘어가면 호출당 과금에 숨은 비용(API Gateway, NAT Gateway, 로깅)까지 더해져서 잘 굴리는 쿠버네티스 클러스터보다 오히려 비싸져요.
서버리스 비용 함정:
1개월: $50 (좋아!)
3개월: $200 (아직 괜찮아)
6개월: $800 (흠)
12개월: $3,500 (절감 효과는 어디 갔지?)
무슨 일이 있었냐면:
- 트래픽 10배 증가 (좋은 일!)
- API Gateway 비용이 선형으로 증가
- CloudWatch 로그 비용 폭발
- DB 접근에 VPC 추가 (NAT Gateway: 월 $100+)
- 동시 실행 한도 도달 (Reserved Concurrency: $$$)
실수 3: "나중에 마이그레이션 안 하려고 처음부터 쿠버네티스"
전형적인 과잉 설계예요. 스타트업이나 소규모 팀이면 생각해보세요:
- 트래픽이 어떻게 생길지 아직 아무도 몰라요
- 플랫폼 엔지니어 뽑을 여유가 없어요
- 인프라 깔끔하게 만드는 것보다 빨리 출시하는 게 먼저예요
- 진짜 필요해지면 서버리스에서 K8s로 넘어가는 건 이미 잘 닦인 길이에요
스타트업 타임라인:
1-180일: 기능 출시 (서버리스)
180-365일: PMF 찾기 (아직 서버리스)
365-730일: 스케일이 서버리스 한계에 도달 (K8s 검토)
730일+: 핫 패스만 K8s, 비동기는 서버리스 유지
시기상조 K8s:
1-90일: K8s 클러스터, CI/CD, 모니터링 세팅 (기능 0개)
90-180일: 네트워킹 이슈 디버깅, Helm 배우기 (아직 기능 0개)
180-365일: 드디어 기능 개발 (서버리스 팀보다 6개월 뒤처짐)
실수 4: "콜드 스타트 때문에 서버리스 못 써"
2026년에 이건 거의 해결된 문제예요:
콜드 스타트 해결 전략:
─────────────────────────────────────────────────
1. Provisioned Concurrency (Lambda):
N개 인스턴스 상시 웜 유지. 비용 들지만 콜드 스타트 없음.
2. Wasm 기반 서버리스:
콜드 스타트 <1ms. 문제 자체가 사라짐.
3. SnapStart (Java 람다):
초기화된 JVM 스냅샷. ~200ms 콜드 스타트.
4. 응답 스트리밍:
헤더 즉시 전송, 본문 스트림.
사용자는 즉각 응답으로 체감.
5. 아키텍처 패턴:
콜드 스타트 민감한 경로를 캐시 뒤에 배치.
커넥션 풀링 사용 (RDS Proxy).
함수는 작고 집중되게.
의사결정 체크리스트
다음 아키텍처 미팅 전에 이 10가지 질문에 답해보세요:
□ 1. 엔지니어가 몇 명?
5명 미만: 서버리스 쪽
5-15명: 둘 다 가능
15명+: 쿠버네티스 쪽
□ 2. 전담 플랫폼/DevOps 팀이 있나?
있음: 쿠버네티스 가능
없음: 서버리스 또는 매니지드 K8s (GKE Autopilot)
□ 3. 트래픽 패턴은?
안정적: 쿠버네티스
스파이크/예측불가: 서버리스
□ 4. 영구 연결 필요? (WebSocket, gRPC 스트리밍)
필요: 쿠버네티스
불필요: 둘 다 가능
□ 5. 프로세스 실행 시간은?
15분 미만: 둘 다 가능
15분 이상: 쿠버네티스
□ 6. 벤더 이식성이 얼마나 중요?
매우: 쿠버네티스 또는 Wasm 서버리스
별로: 기존 서버리스도 OK
□ 7. 월 요청 볼륨은?
3000만 미만: 서버리스가 아마 더 쌈
3000만 이상: 비용 분석 해보기
□ 8. GPU 접근이 필요?
필요: 쿠버네티스
불필요: 둘 다 가능
□ 9. 컴플라이언스 요건은? (데이터 거주지 등)
엄격: 쿠버네티스 (통제권)
보통: 둘 다 가능
□ 10. 우선순위는?
빠르게 출시: 서버리스
완전한 통제: 쿠버네티스
둘 다: 하이브리드 또는 Wasm 서버리스
앞으로 뭐가 올까
2026년 Q1-Q2 (지금)
- ✅ EKS Auto Mode 정식 출시
- ✅ Fermyon Spin 3.5 WASI P3 및 HTTP/2 지원
- ✅ KEDA 2.19 스케일링 트리거 확장
- 🔄 AWS Lambda Wasm 런타임 프리뷰
2026년 Q3-Q4
- GKE에 Wasm 워크로드 네이티브 통합
- 서버리스-쿠버네티스 컨버전스 (함수를 K8s 파드로 원활히 배포)
- 컴포넌트 모델로 크로스 플랫폼 함수 조합
2027년 이후
- Wasm 기반 서버리스가 주류가 됨
- 쿠버네티스 복잡성이 더 나은 추상화 뒤에 숨겨짐
- "쿠버네티스 vs 서버리스" 질문이 의미 없어짐. 다 그냥 "컴퓨트"가 됨
마무리
2026년 쿠버네티스 vs 서버리스, 뭐가 더 좋은 기술이냐를 따지는 건 의미가 없어요. 핵심은 우리 팀이 어떤 고통을 감당할 수 있느냐예요.
쿠버네티스를 선택할 때:
- 운영할 팀이 있을 때 (또는 GKE Autopilot/EKS Auto Mode 사용)
- 네트워킹, 런타임, 스케일링 완전 제어가 필요할 때
- 안정적이고 상태 있고 장기 실행하는 워크로드일 때
- 스케일이 클 때 (월 3000만+ 요청)
- 벤더 이식성이 중요할 때
서버리스를 선택할 때:
- 작은 팀이 빠르게 출시해야 할 때
- 이벤트 기반이고 트래픽이 들쭉날쭉할 때
- 저규모에서 비용이 고규모보다 중요할 때
- 벤더 종속을 수용할 수 있을 때
- 영구 연결이 필요 없을 때
Wasm 기반 서버리스를 선택할 때:
- 서버리스의 단순함에 콜드 스타트 없는 걸 원할 때
- 벤더 이식성은 중요하지만 K8s 복잡성은 싫을 때
- 엣지에서 구축할 때
- 2026년 새 프로젝트고 Rust/Go가 스택에 있을 때
하이브리드를 선택할 때:
- 안정적인 것과 들쭉날쭉한 워크로드가 둘 다 있을 때
- 워크로드 유형별 비용 최적화가 필요할 때
- 팀이 둘 다 관리할 만큼 클 때 (또는 좋은 도구 사용)
최고의 인프라 결정은 팀이 제품에만 집중할 수 있게 해주는 거예요. 인프라 자체가 프로덕트가 되는 순간, 뭔가 잘못된 거예요.
진짜 질문은 "쿠버네티스냐 서버리스냐?"가 아니에요. "우리가 더 빨리 가치를 만들면서도 밤에 편히 잘 수 있는 건 뭐냐?" 이거예요.
관련 도구 둘러보기
Pockit의 무료 개발자 도구를 사용해 보세요