당신에게는 k8s가 필요하지 않습니다
당신의 서비스에 Kubernetes가 필요할까요? 아마 아닐 겁니다.
새 프로젝트를 시작하면 인프라부터 고민하게 됩니다. 마이크로서비스, 서비스 메시, GitOps — 검색하면 K8s가 정답처럼 나옵니다. 하지만 사용자가 100명도 안 되는 서비스에 Netflix급 인프라가 필요할까요? Helm 차트 작성하는 시간에 기능 하나를 더 만드는 게 낫습니다.
K8s를 운영하다 보면 깨닫게 됩니다. 가장 많은 시간을 쓰는 건 서비스가 아니라 클러스터 자체라는 걸요. 인증서 갱신, 노드 업그레이드, RBAC 설정, 스토리지 클래스 관리, 모니터링 스택 유지. 서비스 몇 개 띄우려고 치르는 비용이 점점 목적을 넘어섭니다.
Docker Compose로도 충분히 멀리 갈 수 있습니다. 생각보다 훨씬 멀리요.
Docker Compose는 어디까지 버틸 수 있는가¶
로그 수집 서비스 Logtide는 Docker Compose 하나로 하루 50만 건의 로그를 처리하면서 99.8% 가용성을 유지하고 있습니다1. 서버는 Hetzner CX33 (4vCPU, 8GB RAM) 딱 한 대, 월 €12.50입니다2.
| 항목 | 수치 |
|---|---|
| 일일 로그 처리 | 500,000건 |
| 피크 처리량 | 50 logs/sec |
| P50 응답 지연 | 45ms |
| P95 응답 지연 | 120ms |
| 배포 시간 | 30초 |
| 장애 복구 시간 | 2분 |
| 월 비용 | €12.50 |
같은 워크로드를 Datadog에 맡기면 $800~1,200/월3. 관리형 K8s로 구성해도 $150~300/월입니다. 연간으로 따지면 $1,600~9,600 차이예요. 같은 금액으로 개발자 한 명이 한 달 더 제품에 집중할 수 있습니다.
Logtide의 확장 계획도 K8s가 아니라 Compose 위에서 시작합니다1.
| 규모 | 구성 | 비용 |
|---|---|---|
| 50만/일 (현재) | 서버 1대, Docker Compose | ~$14/월 |
| 500만/일 | 서버 3대 (primary 1 + read replica 2), 수동 페일오버 | ~$50/월 |
| 5,000만/일 | 서버 10대+, K8s 또는 Swarm 검토 시점 | $500+/월 |
K8s가 해결하는 문제, 당신에게는 없는 문제¶
K8s는 좋은 도구입니다. 다만 특정 규모의 특정 문제를 풀기 위한 도구예요.
| K8s가 필요한 조건 | Compose로 충분한 경우 |
|---|---|
| 5개 이상의 서비스 오케스트레이션 | 서비스가 몇 개 안 된다 |
| 예측 불가능한 트래픽에 자동 스케일링 | 트래픽이 예측 가능하다 |
| 멀티 리전 / 멀티 클라우드 배포 | 단일 리전으로 충분하다 |
| 여러 팀의 독립적 배포 | 소규모 팀이 함께 운영한다 |
오른쪽에 해당하는 항목이 더 많다면, K8s는 오버엔지니어링입니다.
기본 구성¶
| |
핵심은 restart: unless-stopped입니다. 컨테이너가 죽으면 Docker 데몬이 알아서 재시작해줍니다. K8s의 파드 재시작 정책을 이 한 줄로 대체할 수 있어요.
헬스체크¶
컨테이너가 떠 있다고 서비스가 정상은 아닙니다. K8s의 liveness/readiness probe 같은 기능이 Compose에도 있어요.
| |
depends_on에 condition: service_healthy를 걸면 DB가 준비된 뒤에 앱이 뜹니다. initContainers 같은 우회 없이 기동 순서를 잡을 수 있어요.
리소스 제한¶
K8s의 resources.limits와 같은 개념이 Compose에도 있습니다. 컨테이너 하나가 메모리를 독점하면 다른 서비스까지 같이 죽으니 걸어두는 게 좋습니다.
| |
무중단 배포¶
bash 스크립트로 K8s의 롤링 업데이트를 어느 정도 대체할 수 있습니다.
| |
완벽한 블루-그린 배포는 아니지만, 대부분의 서비스에는 이 정도면 충분합니다.
시크릿 관리¶
K8s Secrets는 base64 인코딩이라 사실상 평문입니다. Compose의 secrets 기능이 오히려 나을 수 있어요.
| |
컨테이너 안에서 /run/secrets/db_password로 접근하면 됩니다. 환경변수와 달리 docker inspect에 노출되지 않고, .env보다 한 단계 안전하면서 K8s Secrets보다 설정이 단순합니다.
| |
모니터링¶
K8s에서는 모니터링이 사실상 필수입니다. 클러스터 자체의 상태를 봐야 하니까요. Compose에서는 필요할 때 붙이면 됩니다.
| |
같은 docker-compose.yml에 넣으면 docker compose up -d 한 번으로 전체 스택이 올라갑니다. kube-prometheus-stack 설치하다 반나절 날려본 적 있다면, 이 단순함이 얼마나 좋은지 아실 거예요.
백업¶
K8s에서 PersistentVolume 백업은 꽤 귀찮습니다. CSI 스냅샷 드라이버, VolumeSnapshot 리소스, 스토리지 클래스 설정… Compose는 호스트 디렉토리에 바인드 마운트되어 있으니 이걸로 끝입니다.
| |
cron에 걸어두면 됩니다. Velero 설치하고 S3 버킷 연결하고 백업 스케줄 CRD 만들 필요 없어요.
그래도 K8s가 필요한 순간¶
Docker Compose에도 한계는 있습니다.
- 자동 스케일링 — 트래픽에 따라 인스턴스를 자동으로 늘리고 줄이는 건 안 됩니다
- 노드 페일오버 — 서버가 죽으면 서비스도 같이 죽습니다. 다중 노드 HA는 Compose의 영역이 아니에요
- 서비스 디스커버리 — 서비스가 수십 개로 늘어나면 Compose의 DNS 기반 네트워킹만으로는 부족합니다
- 멀티 테넌시 — 여러 팀이 독립적으로 배포하고 격리가 필요하다면 K8s의 네임스페이스가 맞습니다
다만 이런 요구사항이 실제로 생기는 시점은 대부분 생각보다 훨씬 늦습니다.
결론¶
기술 선택은 현재의 문제를 푸는 거지, 미래의 문제를 대비하는 게 아닙니다.
K8s를 도입하기 전에 스스로에게 물어보세요.
- 서비스가 10개 넘는가?
- 서버가 5대 넘는가?
- 다중 리전이 필요한가?
- 자동 스케일링 없이는 안 되는가?
전부 No라면, Docker Compose면 충분합니다. 남는 시간에 제품을 만드세요. 인프라는 제품이 아닙니다.