쿠버네티스 1일차 — 컨테이너 오케스트레이션 + 클러스터 아키텍처
쿠버네티스 학습 첫 날에는 “왜 필요한가” 와 “클러스터 안에서 누가 무슨 일을 하는가” 두 가지만 잡으면 절반은 끝났습니다. 이 글은 그 두 가지를 입문자 눈높이로 정리한 1일차 노트입니다.
이 글에서 다루는 것
- 도커만으론 왜 부족한가 (컨테이너 오케스트레이션의 필요성)
- 쿠버네티스가 등장한 배경과 해결한 6가지 문제
- 마스터 노드 / 워커 노드 / Control Plane 구성
- 마스터 노드 HA 구성과 “왜 홀수 개여야 하는가”
1. 왜 도커만으론 부족한가
도커가 컨테이너로 “어디서든 똑같이 돌아간다” 는 약속을 만들어줬지만, 실제 운영 규모로 가면 다음 5가지가 한꺼번에 터집니다.
| 상황 | 도커만 쓰면 | 쿠버네티스가 있으면 |
|---|---|---|
| 앱이 갑자기 죽음 | 사람이 수동 재시작 | 자동 감지 + 재시작 |
| 트래픽 폭주 | 서버 1대 한계, 수동 복제 | 명령 한 번으로 N대로 확장 |
| 배포 중 다운타임 | 재시작 시 서비스 중단 | 무중단 롤링 업데이트 |
| 서버 여러 대 | 어디 띄울지 사람이 결정 | 여유 있는 노드에 자동 배치 |
| 설정값 관리 | 서버마다 직접 수정 | 중앙에서 한 번에 배포 |
컨테이너 오케스트레이션 = 컨테이너 100개를 사람 손 안 타고 굴리는 시스템. 쿠버네티스는 그 오케스트레이션의 사실상 표준입니다.
“k8s” 라고 줄여 부르는 이유
Kubernetes 의 첫 글자 k 와 마지막 글자 s 사이에 글자가 8개 있어서 k8s 입니다. 같은 식으로 Internationalization → i18n, Localization → l10n 같은 약어가 만들어집니다. 마치 “한 줄로 줄이는 IT 업계의 별명 짓기 규칙” 같은 거죠.
2. 쿠버네티스가 해결하려는 6가지 문제
쿠버네티스 공식 문서가 첫 페이지에서 자랑하는 기능들을 입문자 언어로 풀면 다음과 같습니다.
- 자동화된 롤아웃 / 롤백 — 배포 실패 시 이전 버전으로 즉시 되돌리기 (canary, blue/green 자동화)
- 로드 밸런싱 + 서비스 디스커버리 — 내부 DNS 로 서비스끼리 찾고, 트래픽 자동 분산
- 스토리지 오케스트레이션 — Pod 가 옮겨가도 따라다니는 디스크 (PV/PVC)
- 빈 패킹 (bin packing) — CPU/메모리 요구량 보고 가장 적합한 노드에 자동 배치
- 자동 복구 — 컨테이너 죽으면 재시작, 노드 죽으면 다른 노드로 이전
- 시크릿 + 구성 관리 — 비밀번호 / 환경변수를 클러스터 차원에서 안전하게 (
Secret,ConfigMap)
이 6개는 모두 “사람이 할 일을 시스템이 대신한다” 는 한 줄로 묶입니다.
3. 클러스터 안에는 누가 사나
쿠버네티스 클러스터는 두 종류의 노드로 이루어집니다.
┌─────────────────────────────────────────────────────┐
│ Control Plane (마스터) │
│ │
│ ┌──────────┐ ┌────────┐ ┌─────────────┐ ┌──────┐ │
│ │ API │ │ etcd │ │ Controller │ │Sched-│ │
│ │ server │ │ │ │ Manager │ │uler │ │
│ └──────────┘ └────────┘ └─────────────┘ └──────┘ │
└─────────────────────────────────────────────────────┘
│
┌─────────────────┼──────────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Worker 1 │ │ Worker 2 │ │ Worker N │
│ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │
│ │kubelet │ │ │ │kubelet │ │ │ │kubelet │ │
│ │k-proxy │ │ │ │k-proxy │ │ │ │k-proxy │ │
│ │runtime │ │ │ │runtime │ │ │ │runtime │ │
│ └────────┘ │ │ └────────┘ │ │ └────────┘ │
│ [Pod] │ │ [Pod] │ │ [Pod] │
│ [Pod] │ │ [Pod] │ │ [Pod] │
└────────────┘ └────────────┘ └────────────┘
마스터 노드 (Control Plane) — 클러스터의 두뇌
| 컴포넌트 | 역할 |
|---|---|
| kube-apiserver | 모든 명령이 들어오는 정문. 인증/권한/검증 후 etcd 에 저장 |
| etcd | 클러스터의 모든 상태를 보관하는 분산 키-값 저장소 |
| kube-scheduler | 새 Pod 를 어느 워커 노드에 올릴지 결정 (CPU/메모리 보고) |
| kube-controller-manager | “원하는 상태 vs 현재 상태” 차이를 계속 메우는 자동 복구 엔진 |
워커 노드 — 실제 컨테이너가 돌아가는 곳
| 컴포넌트 | 역할 |
|---|---|
| kubelet | 마스터 명령을 받아 Pod 를 실제로 실행/감시 |
| kube-proxy | 네트워크 규칙 (iptables/IPVS) 으로 서비스 트래픽 라우팅 |
| container runtime | Docker / containerd / CRI-O — 실제 컨테이너를 띄우는 엔진 |
한 번의 kubectl apply 가 흐르는 길
사용자 ──▶ kubectl apply -f deploy.yaml
│
▼
kube-apiserver (인증, 검증)
│
▼
etcd (상태 저장)
│
▼
kube-scheduler (어느 노드?)
│
▼
해당 노드의 kubelet (실행 명령)
│
▼
container runtime (실제 컨테이너 띄우기)
(이 동안 kube-controller-manager 가 백그라운드에서
"현재 = 원하는 상태?" 를 계속 체크하며 자동 복구)
4. 마스터 노드는 왜 “홀수 개” 인가
운영 환경에서는 마스터를 3대 이상, 그리고 반드시 홀수 로 둡니다. 이유는 한 줄입니다.
etcd 가 의사결정에 “과반수(quorum)” 가 필요하기 때문.
짝수의 함정
마스터를 4대로 늘리면 더 안전해 보이지만, 사실은 3대일 때와 똑같이 1대만 죽어도 견딜 수 있습니다.
- 4대 중 2대가 죽으면 남은 2대는 50%, 과반수가 아닙니다.
- etcd 는 데이터 오염을 막으려고 스스로 정지합니다.
- 결과: 비용은 1대 늘었는데 내결함성은 그대로 → “함정”.
홀수 표
| 마스터 | 견딜 수 있는 장애 | 비고 |
|---|---|---|
| 1 | 0 | 단일 장애점 |
| 3 | 1 | 표준 (실무 기본) |
| 5 | 2 | 큰 가용성 필요 시 |
| 7 | 3 | 매우 큰 클러스터 |
Active-Active vs Leader Election
마스터가 여러 대일 때 컴포넌트마다 동작 방식이 다릅니다.
- kube-apiserver — 전부 Active. 앞에 HAProxy 같은 로드밸런서를 두고 트래픽 분산.
- kube-scheduler / kube-controller-manager — Leader Election. 한 대만 일하고 나머지는 대기 (standby).
물리 서버에 직접 구축할 때 — Keepalived + HAProxy
가상의 IP (VIP) 를 마스터들이 공유하게 만들어 외부에는 항상 한 주소만 보입니다.
[VIP 192.168.0.100]
│
┌──────────┼──────────┐
▼ ▼ ▼
Master 1 Master 2 Master 3
(Active) (Standby) (Standby)
▲ HAProxy + Keepalived 가
"Master 1 죽었네? VIP 를 Master 2로 넘기자"
를 자동으로 처리
워커 노드들은 항상 192.168.0.100 만 바라보면 되므로, 마스터가 한 대 죽어도 워커 입장에서는 IP 가 바뀌지 않아 끊김 없이 통신 유지됩니다.
5. 학습 환경 — 무엇을 깔까?
| 환경 | 추천 도구 | 특징 |
|---|---|---|
| 노트북 학습 | minikube | Docker Desktop 위에서 단일 노드 클러스터, 명령어 학습 최적 |
| 작은 서버 | k3s | 라즈베리파이/가벼운 VM. 메모리 ~512MB 수준에서 동작 |
| 운영 클러스터 | kubeadm / kops / EKS / GKE | 본격적인 멀티 노드 환경 |
오늘은 minikube 만 깔아 보면 됩니다. macOS 기준:
brew install minikube kubectl
minikube start --driver=docker
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# minikube Ready control-plane 30s v1.34.x
Ready 가 뜨면 로컬 1노드 클러스터 완성. 1일차 끝.
핵심 한 줄 정리
- 쿠버네티스 = 컨테이너 자동 관리 시스템 (재시작 / 스케일링 / 무중단 배포 / 자동 복구)
- 클러스터 = Control Plane (지휘관) + Worker Node (실행 부대)
- Pod = 컨테이너를 담는 최소 실행 단위 (다음 글에서 자세히)
- 마스터는 3대(홀수). 짝수는 함정
- 학습 시작은 minikube 한 줄 설치
다음 글에서는 Pod / Deployment / Service / Ingress 4종 세트를 손으로 만들어 보면서 “쿠버네티스 yaml 한 통의 인생” 을 따라가 봅니다.
이 글은 르무엘 사내 K8s 1일차 학습 자료를 입문자 시점에서 다시 풀어쓴 노트입니다. 같은 시리즈로 운영 중인
/blog의 Settlement Option D 풀스택 글도 함께 보시면 도움이 됩니다.