Chapter 5. 클러스터란 무엇인가
서버 여러 대를 하나처럼 쓰기
용어: 클러스터(Cluster) — 여러 대의 서버(머신)를 묶어서 하나의 시스템처럼 사용하는 것이다. K8s에서는 이 서버 한 대 한 대를 노드(Node)라고 부른다.
K8s 클러스터는 크게 두 종류의 노드로 구성된다:
- 컨트롤 플레인 노드(Control Plane Node): 클러스터의 “두뇌” 역할. 명령을 받고, 상태를 관리하고, 스케줄링을 결정한다. 예전에는 “마스터 노드”라고 불렀는데 최근에는 “컨트롤 플레인”이라는 용어를 선호한다.
- 워커 노드(Worker Node): 실제로 컨테이너(Pod)가 돌아가는 노드. 일꾼이다.
비유하자면 이렇다. 건설 현장에서 감독관(컨트롤 플레인)이 도면을 보고 “이 건물은 여기에, 저 건물은 저기에 지어”라고 지시한다. 실제로 건물을 짓는 건 작업자(워커 노드)들이다.
K8s 클러스터
┌─────────────────────────────────────────────┐
│ │
│ ┌─────────────────────────────────────┐ │
│ │ Control Plane Node │ │
│ │ ┌──────────┐ ┌──────────────┐ │ │
│ │ │API Server│ │ etcd │ │ │
│ │ └──────────┘ └──────────────┘ │ │
│ │ ┌──────────┐ ┌──────────────┐ │ │
│ │ │Scheduler │ │Controller Mgr│ │ │
│ │ └──────────┘ └──────────────┘ │ │
│ └─────────────────────────────────────┘ │
│ │
│ ┌───────────────┐ ┌───────────────┐ │
│ │ Worker Node 1 │ │ Worker Node 2 │ │
│ │ ┌───┐ ┌───┐ │ │ ┌───┐ ┌───┐ │ │
│ │ │Pod│ │Pod│ │ │ │Pod│ │Pod│ │ │
│ │ └───┘ └───┘ │ │ └───┘ └───┘ │ │
│ │ kubelet │ │ kubelet │ │
│ │ kube-proxy │ │ kube-proxy │ │
│ └───────────────┘ └───────────────┘ │
└─────────────────────────────────────────────┘
Chapter 6. 컨트롤 플레인 컴포넌트
컨트롤 플레인에는 4개의 핵심 컴포넌트가 있다. 각각의 역할을 하나씩 살펴보자.
1) kube-apiserver — 모든 통신의 관문
API 서버는 K8s 클러스터의 정문이다. 모든 요청은 반드시 API 서버를 통해야 한다.
- kubectl 명령을 치면? API 서버로 간다.
- Pod이 생성되어야 하면? API 서버가 받는다.
- 노드가 자기 상태를 보고하면? API 서버로 보낸다.
API 서버는 요청을 받으면 먼저 인증(Authentication) → 인가(Authorization) → 유효성 검사(Admission Control)를 거친 후 처리한다.
용어: 인증 vs 인가 — 인증(Authentication)은 “너 누구야?”를 확인하는 것이고, 인가(Authorization)는 “너 이거 할 권한 있어?”를 확인하는 것이다. 카페 출입(인증)과 금고 접근 권한(인가)의 차이다.
API 서버의 중요한 특징: 상태를 직접 저장하지 않는다. 모든 상태는 etcd에 저장한다. API 서버는 etcd와 대화하는 유일한 컴포넌트이기도 하다.
2) etcd — 클러스터의 기억 장치
용어: etcd — 분산형 키-값(key-value) 저장소다. 이름은 UNIX의 /etc 디렉토리(설정 파일 저장소)에서 “d”(distributed)를 붙인 것이다.
etcd는 클러스터의 모든 상태 정보를 저장한다:
- 어떤 Pod들이 존재하는지
- 어떤 Service들이 정의되어 있는지
- ConfigMap, Secret 데이터
- 노드 정보
- 현재 상태와 원하는 상태(desired state)
etcd가 죽으면? 클러스터의 “기억”이 사라진다. 그래서 프로덕션 환경에서는 etcd를 보통 3대 이상으로 클러스터링하여 고가용성을 확보한다. 또한 주기적으로 백업하는 것이 운영의 기본이다.
용어: 키-값 저장소(Key-Value Store) — 데이터를 “키 = 값” 형태로 저장하는 데이터베이스다. 예: "/registry/pods/default/nginx-abc" = {Pod 정보 JSON}. 관계형 DB(MySQL, PostgreSQL)와 달리 테이블, 스키마 없이 단순한 구조로 빠르게 읽고 쓸 수 있다.
3) kube-scheduler — 어디에 배치할지 결정
새로운 Pod이 만들어져야 할 때, 스케줄러가 “이 Pod을 어느 노드에 올릴까?”를 결정한다.
스케줄러의 결정 과정은 두 단계다:
Step 1 — 필터링(Filtering): 조건을 충족하지 못하는 노드를 제외한다.
- “이 Pod은 CPU 2코어가 필요한데, 노드 A는 1코어만 남아있으니 탈락”
- “이 Pod은 SSD가 필요한데, 노드 B에는 HDD만 있으니 탈락”
- 특정 노드에만 배치하라는 제약(nodeSelector, taints)이 있으면 그것도 여기서 처리
Step 2 — 점수 매기기(Scoring): 필터링을 통과한 노드들에 점수를 매겨서 최적의 노드를 선택한다.
- 자원 여유가 많은 노드에 높은 점수
- 이미 해당 이미지를 가지고 있는 노드에 높은 점수 (이미지 다운로드 시간 절약)
- Pod들을 여러 노드에 골고루 분산하는 쪽에 높은 점수
실무 포인트: 스케줄러는 “결정”만 한다. “이 Pod은 노드 C에 올려”라고 결정하면, 실제로 컨테이너를 띄우는 건 해당 노드의 kubelet이 한다.
4) kube-controller-manager — 상태를 맞추는 감시자
컨트롤러 매니저는 여러 개의 컨트롤러를 묶어서 실행하는 프로세스다. 각 컨트롤러는 특정 리소스를 감시하면서 “원하는 상태”와 “현재 상태”를 비교하고, 차이가 있으면 조치한다.
주요 컨트롤러들:
- ReplicaSet Controller: “nginx Pod 3개를 유지해”라고 했는데 2개만 돌고 있으면 → 1개 더 생성 요청
- Deployment Controller: 새 버전 배포 시 ReplicaSet을 만들고 롤링 업데이트를 조율
- Node Controller: 노드가 응답을 안 하면 일정 시간 후 해당 노드의 Pod들을 다른 노드로 재배치
- Job Controller: 일회성 작업(Job)이 완료될 때까지 관리
- EndpointSlice Controller: Service와 Pod을 연결하는 엔드포인트 관리
앞서 배운 Reconciliation Loop(조정 루프)가 바로 여기서 돌아간다. 현재 상태 확인 → 원하는 상태와 비교 → 차이가 있으면 조치 → 다시 현재 상태 확인 → … 이 루프가 끊임없이 반복된다.
5) cloud-controller-manager (클라우드 환경에서만)
NHN Cloud, AWS, GCP 같은 클라우드에서 K8s를 쓸 때, 클라우드 고유의 기능(로드밸런서 생성, 볼륨 프로비저닝 등)을 K8s와 연동해주는 컴포넌트다. 온프레미스(자체 서버) 환경에서는 없을 수도 있다.
Chapter 7. 워커 노드 컴포넌트
워커 노드에는 3개의 핵심 컴포넌트가 있다.
1) kubelet — 노드의 관리인
kubelet은 각 워커 노드에서 돌아가는 에이전트(agent)다.
용어: 에이전트(Agent) — 중앙 시스템의 명령을 받아 로컬에서 실행하는 프로그램이다. 비유하자면 본사(컨트롤 플레인)에서 지시를 받아 현장(노드)에서 일하는 현장 감독이다.
kubelet이 하는 일:
- API 서버로부터 “이 노드에서 이 Pod을 실행해”라는 지시를 받는다.
- 컨테이너 런타임(containerd, CRI-O 등)에 컨테이너 생성을 요청한다.
- 컨테이너가 잘 돌고 있는지 헬스체크(Health Check)를 수행한다.
- 노드의 상태(CPU, 메모리 사용량 등)를 주기적으로 API 서버에 보고한다.
용어: 컨테이너 런타임(Container Runtime) — 실제로 컨테이너를 생성하고 실행하는 소프트웨어다. Docker도 컨테이너 런타임의 하나였지만, K8s 1.24부터 Docker를 직접 지원하지 않고 containerd나 CRI-O 같은 경량 런타임을 사용한다. Docker로 만든 이미지는 여전히 사용 가능하다. 이미지 형식(OCI 표준)과 런타임은 별개이기 때문이다.
2) kube-proxy — 네트워크 규칙 관리
kube-proxy는 각 노드에서 네트워크 규칙을 관리한다. Pod끼리, 또는 외부에서 Pod으로 통신할 때 트래픽이 올바른 곳으로 전달되도록 하는 역할이다.
구체적으로:
- K8s의 Service 리소스(뒤에서 자세히 배운다)가 정의되면, kube-proxy가 해당 Service로 오는 트래픽을 적절한 Pod으로 라우팅하는 규칙을 만든다.
- 보통 Linux의 iptables나 IPVS를 사용한다.
3) Container Runtime — 컨테이너를 실제로 실행
앞서 설명한 containerd, CRI-O 등이다. kubelet이 “이 컨테이너 띄워줘”라고 하면, 실제로 이미지를 가져오고 컨테이너 프로세스를 시작하는 소프트웨어다.
Chapter 8. 전체 흐름으로 이해하기
kubectl apply -f nginx-deployment.yaml을 실행했을 때 내부에서 일어나는 일을 순서대로 따라가 보자.
사용자 → kubectl → API Server → etcd (저장)
│
├→ Scheduler: "노드 B에 배치"
│ └→ API Server에 결과 기록
│
├→ Controller Manager: 감시 & 조정
│
└→ kubelet(노드 B):
└→ Container Runtime: 컨테이너 실행
Step 1: 사용자가 kubectl apply를 실행한다. kubectl이 YAML을 읽어서 API 서버에 HTTP 요청을 보낸다.
Step 2: API 서버가 요청을 인증·인가·검증한 후, etcd에 “이런 Deployment가 필요하다”고 저장한다.
Step 3: Controller Manager의 Deployment Controller가 이를 감지한다. “새 Deployment가 생겼네? ReplicaSet을 만들어야지.” → ReplicaSet을 만들고 API 서버에 등록한다.
Step 4: ReplicaSet Controller가 “Pod 3개가 필요한데 0개야” → Pod 3개 생성을 요청한다.
Step 5: Scheduler가 아직 노드가 배정되지 않은 Pod들을 발견한다. 필터링·점수 매기기를 거쳐 “이 Pod은 노드 B에”라고 결정하고 API 서버에 기록한다.
Step 6: 노드 B의 kubelet이 자기 노드에 배정된 새 Pod을 감지한다. Container Runtime에 컨테이너 생성을 요청한다.
Step 7: 컨테이너가 실행된다. kubelet이 주기적으로 상태를 API 서버에 보고한다.
이 모든 과정이 이벤트 기반(Event-driven)으로 일어난다. 각 컴포넌트는 서로 직접 호출하지 않고, API 서버(정확히는 etcd)를 중앙 허브로 써서 상태 변화를 감지(watch)하고 반응한다. 이것이 K8s 아키텍처의 핵심 설계 원칙이다.
Chapter 9. kubectl — 관리자의 도구
용어: kubectl — “큐브 컨트롤” 또는 “큐브 시티엘”이라고 읽는다. K8s 클러스터를 조작하는 CLI(명령줄) 도구다.
kubectl은 사용자가 K8s 클러스터와 대화하는 주된 수단이다. 자주 쓰는 명령 패턴:
# 리소스 조회
kubectl get pods # Pod 목록
kubectl get pods -o wide # 상세 정보 (IP, 노드 등)
kubectl get all # 주요 리소스 전부 보기
kubectl get nodes # 노드 목록
# 리소스 생성/적용
kubectl apply -f 파일.yaml # 선언적 방식 (추천)
kubectl create -f 파일.yaml # 명령적 방식
# 상세 정보 조회
kubectl describe pod 파드이름 # 이벤트, 상태 등 상세 정보
# 로그 확인
kubectl logs 파드이름 # 컨테이너 로그
kubectl logs -f 파드이름 # 실시간 로그 (tail -f 같은)
# 디버깅
kubectl exec -it 파드이름 -- bash # 컨테이너 안으로 들어가기
# 삭제
kubectl delete -f 파일.yaml # YAML로 정의한 리소스 삭제
kubectl delete pod 파드이름 # 특정 Pod 삭제
실무 포인트: kubectl apply와 kubectl create의 차이 — create는 “없으면 만들어, 있으면 에러”, apply는 “없으면 만들고, 있으면 업데이트해”. 선언적 관리의 철학에 맞는 건 apply다.
'k8s 이론 공부' 카테고리의 다른 글
| 부록: 핵심 용어 사전 (가나다순) (0) | 2026.04.02 |
|---|---|
| Part 5 — 운영과 확장 (0) | 2026.04.02 |
| Part 4 — 네트워킹과 스토리지 (0) | 2026.04.02 |
| Part 3 — 핵심 리소스 (0) | 2026.04.02 |
| Part 1 - 왜 k8s 인가? (0) | 2026.04.02 |