프로덕션에서 Docker vs Kubernetes: 보안 우선 결정 프레임워크
Source: Dev.to
TL;DR
- Docker Compose → 작은, 예측 가능한 환경 (1‑3 호스트).
- Kubernetes → 더 큰, 다팀, 높은 변동성 환경 (5+ 노드, 하루 10+ 배포).
- 절대 선택한 플랫폼이 제공하는 보안 제어를 건너뛰지 마세요.
1. 플랫폼 선택이 실패 원인이 아닌 이유
“나는 팀들이 규모를 위해 Kubernetes를 선택하고, 그 다음 감사에서 아무도 RBAC, admission policy, 또는 로그 보존을 담당하지 않아 실패하는 것을 보았다. 플랫폼 선택이 실패를 일으킨 것이 아니다. 누락된 제어가 원인이다.”
실제 위험은 오케스트레이션 도구 자체가 아니라, 필수 제어의 부재이다.
2. 기본 위험
| 플랫폼 | 핵심 위험 | 하드닝하지 않으면 발생하는 일 |
|---|---|---|
| Docker Compose | 신뢰가 몇몇 호스트에 집중됩니다. | 공격자가 노드에 침투하면 일반적으로 해당 노드의 모든 것에 접근할 수 있습니다. 호스트를 보안 경계로 간주하고, OS와 Docker Engine을 정기적으로 패치하며, docker 명령을 실행할 수 있는 사용자를 제한하세요. |
| Kubernetes | 컨트롤 플레인은 많은 새로운 공격 표면을 추가합니다 (kube‑apiserver 인증, kubelet 노출, RBAC 확산, CNI 정책 격차, 서드‑파티 컨트롤러). | 이를 잠그지 않으면, 손상된 서비스 계정이 네임스페이스 간에 횡방향 이동을 할 수 있습니다. |
3. 업그레이드하지 않으면 어떻게 될까?
- 권고 사항은 귀하의 변경 창을 기다리지 않는다.
- 런타임, 인그레스 컨트롤러, CNI, 오퍼레이터 등 알려진 취약 구성 요소가 누적된다.
- PoC가 발표될 때까지 실제 위험을 평가하기는 어렵지만 컴플라이언스 위험은 명백하다.
- “업그레이드할 계획이다” 감사를 통과하지 못한다.
권고 사항은 귀하의 환경을 지정하지 않는다. 폭발 반경은 여러분이 책임진다. 먼저 이를 줄이고, 그 다음에 오케스트레이션 기능에 대해 논의하라.
4. 실제 현장의 문제점
- 한 팀이 클러스터를 1년 동안 “안정적”으로 유지했지만, 급하게 업그레이드하는 과정에서 API가 제거되어 배포 파이프라인이 완전히 멈췄다.
- Kubernetes 지원 윈도우: 업스트림은 최신 마이너 버전 중 소수만 지원한다. 지원되지 않는 클러스터를 운영하면 적시 보안 패치를 제공한다는 주장을 신뢰받기 어렵고, 규제 기관은 의도가 아니라 증거를 요구한다.
- Ingress 및 엣지 변동: 유지보수가 중단된 단일 Ingress 컨트롤러에 모든 것을 고정하면, 깔끔한 마이그레이션 경로 없이 보안 패치 공백이 발생한다.
- Docker Engine 29.x는 실제 동작 및 의존성 변화를 도입한다. 이를 단순 “패치” 이상으로 다루고, 단계적으로 적용하고 테스트하며, 롤백 계획을 유지하라.
5. 의사결정 루브릭
Docker Compose를 선택할 경우
- 1‑3개의 호스트를 운영할 때.
- 트래픽이 예측 가능할 때.
- 한 명의 온콜 담당자가 전체 스택을 담당할 때.
- 호스트를 빠르게 재구축하고 복구를 입증할 수 있을 때.
Kubernetes를 선택할 경우
- 5대 이상의 노드를 운영하거나 노드 변동이 잦을 때.
- 서비스 전반에 걸쳐 하루 10회 이상 배포할 때.
- 여러 팀이 강력한 격리(네임스페이스, RBAC, 쿼터, NetworkPolicy)를 필요로 할 때.
- “CI에서 확인한다”는 수준을 넘어 강제 가능한 정책이 필요할 때.
잘못 선택했을 경우:
- Compose → 스트레스 상황에서 실패할 때까지 자체 스케줄러와 정책 연결 코드를 억지로 붙여넣게 됩니다.
- Kubernetes → 약한 RBAC와 네트워크 정책이 없는 대형 컨트롤 플레인을 배포하고, 침해 후 정리하는 데 몇 주를 소비하게 됩니다.
6. 핵심 운영 규칙
- 복구를 증명한다.
- 롤백은 하나의 명령어로 수행한다:
- 불변 태그를 사용한다.
- last‑known‑good 태그를 유지한다.
:latest를 절대 배포하지 않는다. “잠시라도” 배포하지 않는다.
- 시크릿은 Git에 두지 않는다:
- Docker secrets 또는 외부 시크릿 스토어를 사용한다.
- 정기적으로 회전한다.
- 접근을 감사한다.
- 호스트 재구축은 60분 이내:
- 랜섬웨어가 발생하면, 새벽 3시의 수동 편집된 설정이 아니라 IaC를 통해 재구축한다.
7. 보안 제어 체크리스트
| 제어 | Docker Compose | Kubernetes |
|---|---|---|
| RBAC / Admission policies | 해당 없음 (호스트 수준) | 소유, 감사 및 버전 관리가 필요 |
| NetworkPolicy | 호스트 방화벽 규칙 | 네임스페이스 + NetworkPolicy |
| Audit logs | Docker 데몬 로그 | kube‑apiserver 감사 로그 + 중앙 집중식 로깅 |
| Quotas / Limits | 수동 cgroup 제한 | ResourceQuota, LimitRange |
| Secrets management | Docker 비밀 / 외부 저장소 | Secrets, 외부 비밀 연산자 |
| Rollback strategy | docker compose down && up와 불변 이미지 | Helm/Kustomize와 helm rollback 또는 kubectl rollout undo |
8. 마이그레이션 가이드라인
Compose → Kubernetes
- 단일 템플릿 도구(Helm 또는 Kustomize)를 선택하고 고수하세요.
- 무상태 서비스 하나를 엔드‑투‑엔드로 구현하세요:
- 프로브(레디니스/라이브니스)
- 리소스 제한
- 대시보드 및 알림
- 5xx 및 지연 시간 기반 롤백 트리거
- 점진적으로 마이그레이션하세요 – 절반만 진행된 다섯 개 서비스가 아니라.
Kubernetes → Compose
- Stateful 서비스가 가장 큰 마이그레이션 위험이라는 점을 인식하세요. Postgres는 “간단한 플랫폼 이동”을 데이터 손실 사후 분석으로 빠르게 전환시킵니다. 관리형 Postgres를 선호하세요(비용이 싫어도 말입니다).
If you self‑host Postgres:
- 백업을 자동화하고, 오프사이트에 저장하세요.
- 월간 복구 테스트를 실행하세요.
- RPO/RTO를 증명할 수 없다면, 백업 계획이 없는 것이 아니라 희망만 있는 겁니다.
9. Operational Best Practices
- Canary deployments for any platform change (including runtime upgrades).
- Readiness checks, rolling updates, disruption budgets – avoid “all‑at‑once” releases.
- Make today boring: immutable images, health endpoints, metrics, explicit dependencies.
- Namespace isolation, RBAC, quotas, NetworkPolicy for multi‑team production.
- Admission policies & audit logs – never rely solely on CI checks; an on‑call hot‑fix can bypass them the first time prod burns.
10. 마무리 생각
제어를 건너뛰면 Kubernetes가 위험을 증가시킵니다.
Docker Compose와 Kubernetes 사이의 선택은 운영 규모, 팀 구조, 그리고 보안 제어를 시행할 수 있는 능력에 의해 결정되어야 합니다—‘더 많은 기능’이라는 매력에 의해서가 아니라. Compose를 사용할 때는 환경을 의도적으로 작게 유지하고, Kubernetes를 도입할 때는 컨트롤 플레인 위생에 투자하십시오.
비용 개요
Kubernetes는 “무료”가 아닙니다. 숨겨진 비용은 etcd 압축 디버깅, 금요일에 깨진 admission webhook 수정, 상위 프로젝트가 베타 API를 중단할 때 마이그레이션을 수행하는 엔지니어의 시간입니다. 아래는 보다 솔직한 분류입니다.
Docker Compose on a Single VPS
- 일반 VM 비용: $20‑$100 / month
- 추가 서비스: 로드 밸런서 (TLS 종료가 필요할 경우), 필요에 따라 관리형 데이터베이스
- 소규모 SaaS에 대한 전체 인프라 비용: $50‑$200 / month
- 숨겨진 비용: 새벽 2시 VM이 죽으면, 당신이 오케스트레이터가 됩니다.
Managed Kubernetes (EKS, GKE, AKS)
| 구성 요소 | 일반 비용 |
|---|---|
| Control‑plane 비용 | $70‑$150 / month on EKS (소규모 클러스터에 대해 GKE Autopilot은 무료) |
| 노드 컴퓨트 | 다양함 (예: t3.medium, m5.large) |
| 로드 밸런서 | $0.01‑$0.02 / hour per LB |
| 영구 디스크 | $0.10 / GB‑month |
- 최소 실행 가능한 프로덕션 클러스터: $200‑$500 / month (2‑3 노드 기준).
- 실제 비용: 클러스터를 유지하는 엔지니어. 1년 차에 플랫폼 작업을 위해 **시니어 엔지니어 시간의 20‑40 %**를 예산에 포함하세요.
Self‑Hosted Kubernetes
전용 플랫폼 팀이 없는 경우에는 하지 마세요.
컴퓨팅 비용 절감은 다음과 같은 인적 시간을 고려하면 사라집니다:
- etcd 백업
- 인증서 교체
- 업그레이드 주기
스타트업은 종종 3‑6개월의 엔지니어링 시간을 k3s를 “비용 절감” 목적으로 설정하는 데 사용하고, 기능을 전혀 출시하지 못합니다.
Rule of Thumb
- 월간 AWS 비용이 $500 이하라면, Kubernetes가 비용을 절감해 주고 있지는 않을 가능성이 높습니다.
- 특정 장애 모드로부터 보호할 수는 있지만, 이는 비용과는 별개의 논점입니다.
성공 예측기
Kubernetes 성공을 가장 잘 예측하는 것은 트래픽 양이 아니라 Kubernetes를 운영하고 싶어 눈을 뜨는 사람이 있는가입니다. 팀에 그런 직감이 있는 사람이 없다면 Docker Compose가 더 나을 것입니다.
Recommendations by Team Size
| Team Size / Product Scope | Recommendation | Rationale |
|---|---|---|
| Solo founder or 1‑2 engineers | Docker Compose | 제어 플레인의 컨텍스트 전환 비용이 없으며, 기능을 배포할 시간이 더 많습니다. |
| 3‑5 engineers, single product | Docker Compose unless you deploy 20+ times per day or run in multiple regions. If you feel the itch, try a managed Kubernetes cluster for one non‑critical service first and give it 3 months before migrating anything important. | |
| 5‑15 engineers, multiple services | Managed Kubernetes (not self‑hosted) | 배포 시 팀 간 충돌이 발생하고, 강력한 리소스 격리가 필요하거나, 규정 준수 차원에서 서비스별 감사 로그가 요구됩니다. |
| 15+ engineers or a platform team exists | Kubernetes (managed or self‑hosted) | 이미 협업 비용을 지불하고 있으니, 제어 플레인, 공유 도구, 표준 경로(golden paths)로 체계화하세요. 플랫폼 팀은 클러스터를, 제품 팀은 각자의 네임스페이스를 관리합니다. |
Observability Stacks
Docker Compose Observability
- Logs: Docker logs →
stdout. Promtail 또는 Fluent Bit을 사용해 Loki 혹은 SIEM으로 전송합니다. - Metrics: 컨테이너 메트릭을 위해 cAdvisor를 추가하고,
/metrics엔드포인트를 노출시켜 Prometheus가 스크랩하도록 합니다. - Setup time: 시니어 엔지니어 기준 몇 시간 소요. 관측 대상이 적어 안정적으로 동작합니다.
Kubernetes Observability
- Built‑in telemetry: 파드 라이프사이클 이벤트, 네임스페이스별 리소스 사용량, API‑server 감사 로그.
- Platform monitoring: etcd 지연시간, API‑server 요청률, kubelet 상태, 노드 컨디션.
- Starter kit: 기본 템플릿으로 kube‑prometheus‑stack Helm 차트를 사용합니다.
- Setup time: 알림이 과도하게 발생하지 않도록 경보를 조정하는 데 하루 정도 잡아두세요.
보안 격차
Docker와 Kubernetes 모두 로그를 생성하지만, 대부분의 팀은 감사 로깅을 건너뛰고 있습니다:
- Docker: 누가 언제 어떤 컨테이너를 실행했는지에 대한 증거가 없습니다.
- Kubernetes: RBAC 위반이나 토큰 도난에 대한 흔적이 없습니다.
필요해지기 전에 감사 로그를 활성화하세요. “나중에 로깅을 추가하겠다”는 말은 종종 *“침해 범위를 파악할 수 없음”*이라고 적힌 보안 사고 보고서에 등장합니다.
Docker Compose와 Kubernetes 선택하기
- Docker Compose 선택: 시스템을 작고 감사 가능하게 유지할 수 있을 때. 호스트와 Docker Engine을 패치하고, 접근을 제한하며, 복구 연습을 수행하세요.
- Kubernetes 선택: 격리, 정책 적용, 점진적 배포가 필요하고, 제어 플레인을 추측 없이 운영할 수 있을 때.
트레이드오프를 평가하는 더 좋은 방법이 있을지도 모르지만, 이 기준은 제가 계속 목격하는 실패를 포착합니다.
자주 묻는 질문
프로덕션에 Docker와 Kubernetes 중 어느 것을 사용해야 할까요?
이는 규모와 팀에 따라 다릅니다. Docker( Docker Compose 또는 Swarm 사용)는 더 간단하고 소규모‑중간 규모 배포에 적합합니다. Kubernetes는 자동 스케일링, 자체 복구, 롤링 업데이트가 필요한 대규모 다중 서비스 아키텍처에 강점이 있습니다.
Kubernetes 없이 Docker를 사용할 수 있나요?
물론입니다. Docker Compose는 단일 호스트에서 다중 컨테이너 애플리케이션을 관리하고, Docker Swarm은 기본 클러스터링을 제공합니다. 많은 프로덕션 워크로드가 Kubernetes 없이 Docker만으로 실행됩니다.
작은 팀에게 Kubernetes는 과도한가요?
종종 그렇습니다. Kubernetes는 클러스터 관리, 네트워킹 복잡성, 높은 학습 곡선 등 상당한 운영 부담을 가져옵니다. 10개 이하의 서비스를 운영하거나 DevOps 리소스가 제한된 팀은 관리형 컨테이너 서비스나 Docker Compose가 더 실용적입니다.
Docker와 Kubernetes의 보안 차이는 무엇인가요?
- Kubernetes: 세분화된 보안 제어—네트워크 정책, RBAC, 포드 보안 표준, 시크릿 관리.
- Docker: 호스트 수준 보안, Linux 네임스페이스, 컨테이너 이미지 스캔에 더 많이 의존합니다. 두 경우 모두 프로덕션 안전을 위해 의도적인 보안 설정이 필요합니다.
Docker와 Kubernetes는 스케일링을 어떻게 다르게 처리하나요?
- Docker Swarm: 간단한 복제 수 설정으로 클러스터 전반에 컨테이너를 복제하여 스케일링합니다.
- Kubernetes: Horizontal Pod Autoscaling(CPU, 메모리, 사용자 정의 메트릭) 및 Cluster Autoscaling(노드를 자동으로 추가/제거) 기능을 제공합니다. Kubernetes 스케일링은 더 강력하지만 설정이 더 복잡합니다.
원본은 ReleaseRun에 게시되었습니다. 우리는 Docker, Kubernetes 및 관련 도구의 릴리스, EOL 날짜, 보안 업데이트를 추적합니다.
... and 11 other technologies.
Try our free **K8s Deprecation Checker** or **Dockerfile Security Linter** to audit your configs.