도커와 쿠버네티스를 처음 접하면 둘 다 “컨테이너 돌리는 도구”처럼 보여서 경계가 흐려지기 쉽습니다. 이 글에서는 Docker는 패키징, **Kubernetes는 오케스트레이션(운영/관리)**이라는 핵심 구분을 기준으로, 언제 무엇을 선택하면 좋은지 제 경험 관점의 판단 기준까지 정리해봅니다.
1) Docker와 Kubernetes를 한 문장으로 구분하기
- Docker: 애플리케이션 코드 + 의존성 + 설정을 컨테이너 이미지로 패키징(packaging) 해서 “어디서나 동일하게 실행”되게 만드는 도구입니다.
- Kubernetes: 여러 컨테이너(정확히는 컨테이너로 구성된 워크로드)를 클러스터에서 스케줄링/배포/확장/복구/트래픽 분산하며 안정적으로 운영하는 오케스트레이션(orchestration) 플랫폼입니다.
정리하면 이렇게 기억하면 편합니다.
Docker는 “만들고(빌드) 담고(이미지) 실행(run)하는” 쪽,
Kubernetes는 “여러 개를 안정적으로 굴리는(운영) ” 쪽입니다.
2) 흔한 오해: “Kubernetes가 Docker로 컨테이너를 실행한다?”
예전에는 Kubernetes가 Docker 엔진을 런타임으로 많이 썼기 때문에 “K8s는 Docker 위에서 돈다”라는 표현이 널리 퍼졌습니다. 하지만 지금은 관점이 조금 달라졌습니다.
- Kubernetes는 내부적으로 CRI(Container Runtime Interface) 를 통해 런타임과 연동합니다.
- 실제 런타임은 containerd, CRI-O 같은 구현체가 흔히 사용됩니다.
- 그렇다고 Docker가 무의미해진 건 아닙니다. 우리가 흔히 만드는 Docker 이미지가 OCI(Open Container Initiative) 이미지 표준을 따르기 때문에, Kubernetes에서도 동일한 이미지를 그대로 실행할 수 있습니다.
즉,
- “Kubernetes가 Docker 엔진에 직접 의존한다” → 이제는 부정확한 표현일 수 있고,
- “Docker로 만든 OCI 이미지가 Kubernetes에서도 잘 돈다” → 이게 핵심입니다.
3) 각각이 잘하는 일: 패키징 vs 오케스트레이션
Docker가 잘하는 것(패키징/실행 단위 확립)
- 환경 차이를 줄이는 재현 가능한 실행 단위(이미지) 만들기
- 로컬 개발/테스트에서 운영까지 동일한 형태로 전달
- 단일 서버 또는 소규모 환경에서 빠른 배포(특히 Docker Compose 조합)
예: 간단한 앱을 이미지로 패키징
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "start"]
이 Dockerfile의 핵심 가치는 “이 앱을 실행하기 위한 조건(런타임/의존성/실행 명령)을 이미지로 고정”한다는 점입니다.
Kubernetes가 잘하는 것(운영/관리 자동화)
- 여러 서비스(여러 컨테이너)를 노드들에 스케줄링
- 트래픽 증가에 따라 오토스케일링
- 장애 발생 시 자가치유(재시작/재스케줄링)
- 로드밸런싱, 롤링 업데이트, 배포/롤백 같은 운영 기능을 기본 제공
예: 최소한의 배포/확장 느낌을 보는 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: myrepo/web:1.0.0
ports:
- containerPort: 3000
여기서 중요한 건 “컨테이너를 어떻게 실행하느냐”가 아니라, 원하는 상태(replicas=3)를 선언하면 Kubernetes가 그 상태를 맞추도록 계속 관리한다는 운영 모델입니다.
4) Docker Swarm은 어디쯤에 있을까? (단순한 오케스트레이션)
대화에서 나왔던 포인트처럼, Docker Swarm은 Docker 생태계 안에서 “오케스트레이션을 더한” 선택지입니다.
- 장점:
- Kubernetes보다 학습/설정이 단순하고 Docker CLI 경험을 그대로 가져갈 수 있습니다.
- 빠르게 클러스터를 구성하고 스케일링/롤링 업데이트를 적용할 수 있습니다.
- 트레이드오프:
- 대규모 운영에서 필요한 생태계(관측/정책/확장성)나 복잡한 워크로드 모델링, 고급 배포 전략(카나리/블루그린 등)에서 Kubernetes가 유리한 경우가 많습니다.
결국 “복잡한 기능을 못 써서 생길 손해” vs “복잡한 플랫폼을 운영해서 생길 비용” 중 어디가 더 큰지의 문제입니다.
5) “우리 서비스는 Kubernetes가 필요할까?” 판단 기준
대화에서 핵심으로 잡힌 기준은 서비스 플로우의 복잡성과 배포 빈도, 그리고 “동적 변화”였습니다. 여기에 제가 자주 같이 보는 운영 관점 체크리스트를 붙이면 판단이 더 선명해집니다.
Kubernetes 쪽으로 기우는 신호
- 트래픽 스파이크가 잦고 수평 확장이 자주 필요합니다.
- 잦은 배포/실험/설정 변경 등 운영 이벤트가 빈번합니다.
- 장애 복구를 자동화하고 싶고, 다운타임 허용이 낮습니다(SLO가 빡빡).
- 멀티서비스가 늘어나면서 서비스 디스커버리/롤아웃/관측/권한/정책이 중요해집니다.
- “동적 변화”가 단순 트래픽 증가를 넘어 노드 장애/지역 이동/배포 전략 고도화까지 포함됩니다.
Docker(또는 Docker Compose/PaaS)로 충분한 신호
- 단일/소수 서버에서 충분하고, 수동 대응 비용이 감당 가능합니다.
- 배포 빈도가 낮고, 장애 대응도 정해진 절차로 처리 가능합니다.
- 운영 인력/시간이 제한되어 “플랫폼 운영” 자체가 부담입니다.
- 필요한 스케일링이 있다면 Kubernetes 이전에 관리형 PaaS/서버리스/오토스케일 같은 더 단순한 대안이 먹힙니다.
제가 느끼는 결론은 이렇습니다.
“시스템이 복잡하지 않다면 Kubernetes가 과투자일 수 있다”는 말은 대체로 맞지만, ‘복잡함’은 앱 로직이 아니라 운영 요구사항에서 급격히 커진다는 점을 같이 봐야 합니다.
마무리
Docker는 애플리케이션을 표준화된 실행 단위로 패키징하는 데 강하고, Kubernetes는 그 컨테이너들을 대규모로 안정적으로 운영하는 데 강합니다. 결국 선택은 “기술의 멋”이 아니라 변화(트래픽/배포/장애/정책)를 얼마나 자주, 얼마나 자동으로 다뤄야 하는가에서 갈립니다.
