[k8s 기초 2편] 쿠버네티스 뼈대 파헤치기: 마스터 노드와 워커 노드
jay
지난 1편에서는 도커의 한계를 넘어 쿠버네티스를 도입해야 하는 이유에 대해 정리했다.
홈서버에 구축한 k3s 클러스터에 접속해 kubectl get nodes 명령어를 입력하면 Ready 상태의 노드가 조회된다. 겉보기엔 단순한 서버 한 대 같지만, 내부에서는 수많은 컴포넌트들이 유기적으로 통신하며 시스템을 지탱하고 있다.
이번 편에서는 쿠버네티스 클러스터가 어떻게 구성되어 있는지, 그 아키텍처(Architecture)를 살펴보려고 한다.
이 구조를 이해해야 나중에 트러블슈팅을 할 때 “어디가 문제인지” 파악할 수 있기 때문이다.
1. 큰 그림: 클러스터(Cluster) 구조
쿠버네티스를 관통하는 핵심 멘탈 모델은 “여러 대의 서버를 하나의 거대한 컴퓨터처럼 다룬다”는 것이다. 이 서버들의 집합을 클러스터(Cluster)라고 부른다.
클러스터는 크게 두 가지 영역으로 나뉜다.
- Control Plane (마스터 노드): 시스템 전체를 제어하고 관리하는 컨트롤 타워.
- Worker Node (워커 노드): 실제 애플리케이션(컨테이너)이 실행되는 작업 공간.
참고: 실제 운영 환경(Production)에서는 마스터와 워커를 물리적으로 분리하지만, 내가 사용 중인 k3s나 Minikube 같은 학습용 환경은 하나의 서버 안에 이 두 가지 역할이 모두 포함되어 있다.

2. 컨트롤 타워: 컨트롤 플레인 (Control Plane)
클러스터의 ‘두뇌’ 역할을 하는 곳이다. 컨테이너를 배치하고, 상태를 관리하며, 설정을 저장하는 4가지 핵심 컴포넌트로 구성된다.
① API Server: 클러스터의 관문
쿠버네티스 클러스터로 들어오는 모든 요청의 진입점이다.
개발자(kubectl)나 워커 노드 내부의 컴포넌트들은 서로 직접 통신하지 않고, 반드시 API Server를 거쳐서 정보를 주고받는다.
- 역할: 사용자 인증(Auth), 권한 확인, 요청 유효성 검사 등 문지기 역할을 수행한다.
② etcd: 클러스터의 데이터 저장소
모든 클러스터 상태 데이터가 저장되는 고가용성 Key-Value 저장소다.
쿠버네티스에서 API Server를 제외한 그 어떤 컴포넌트도 etcd에 직접 접근할 수 없다. 오직 API Server만이 etcd와 통신한다.
- 역할: “현재 어떤 파드가 어디에 떠 있는지”, “설정값은 무엇인지” 등 모든 정보를 영구적으로 저장한다. 서버가 재부팅되어도 상태가 유지되는 것은 etcd 덕분이다.
③ Scheduler: 리소스 관리 및 배치
새로 생성된 파드(Pod)를 감지하고, 어떤 노드(Node)에서 실행할지 결정한다.
노드들의 CPU/Memory 상태를 파악하여 가장 적절한 곳에 배정하는 역할을 한다.
- 역할: “노드 A는 CPU 사용률이 높으니, 여유가 있는 노드 B에 이 파드를 할당하자”는 식의 스케줄링 의사결정을 내린다.
④ Controller Manager: 상태 유지 관리
클러스터의 현재 상태(Current State)를 끊임없이 확인하고, 원하는 상태(Desired State)와 일치시키는 역할을 한다.
- 역할: 예를 들어 “웹 서버 파드를 3개 유지하라”고 설정했는데 현재 2개뿐이라면, 이를 감지하고 API Server에 새로운 파드 생성을 요청한다. 논리적인 제어 루프를 담당한다.
3. 작업 공간: 워커 노드 (Worker Node)
컨트롤 플레인의 명령을 받아 실제로 워크로드를 수행하는 노드다.
① Kubelet: 노드의 에이전트
모든 워커 노드에 설치되어 실행되는 에이전트다.
API Server로부터 “이 노드에 파드를 실행하라”는 명령을 받으면, 컨테이너 런타임(Docker 등)을 제어하여 컨테이너를 생성하고 관리한다.
- 역할: 파드의 상태를 주기적으로 체크하여 API Server에 보고한다. 명령을 수행하는 실무자라고 볼 수 있다.
② Kube-proxy: 네트워크 프록시
클러스터 내부의 네트워크 규칙을 관리한다.
- 역할: 외부에서 들어오는 트래픽이나 내부 파드 간의 통신이 올바른 목적지로 갈 수 있도록, 노드의 네트워크 규칙(iptables 등)을 설정한다.
③ Container Runtime
실제로 컨테이너를 실행하는 엔진이다.
- 종류: 과거엔 도커(Docker)를 주로 썼으나, 최근엔 containerd, CRI-O 등 다양한 런타임을 지원한다. (k3s는 기본적으로 containerd를 사용한다.)
4. 워크플로우: 파드가 생성되는 과정
이 컴포넌트들이 어떻게 협력하는지, “Nginx 파드 하나를 생성해 줘”라는 요청을 예시로 흐름을 정리해 본다.
- User:
kubectl run nginx명령을 입력한다. - API Server: 요청을 받아 검증 후, etcd에 “Nginx 생성 요청됨” 정보를 저장한다.
- Scheduler: 할당되지 않은 새로운 파드를 감지하고, 적절한 노드(예: Node 2)를 선정하여 API Server에 알린다.
- API Server: 해당 정보를 etcd에 업데이트한다.
- Kubelet (Node 2): 자신의 노드에 할당된 파드 정보를 API Server를 통해 확인하고, Container Runtime에게 실행을 명령한다.
- Kubelet: 실행이 완료되면 상태를 API Server에 보고한다.

5. 마치며: 분산 시스템의 미학
쿠버네티스의 구조가 다소 복잡해 보이는 이유는 역할의 분리(Decoupling) 때문이다.
각 컴포넌트가 자신의 역할에만 집중함으로써, 특정 부분에 장애가 발생해도 전체 시스템이 멈추지 않고, 수천 대의 노드로 확장할 수 있는 유연성을 갖게 된다. 홈서버(k3s)는 이 거대한 구조를 경량화하여 한 대의 머신 안에 담아둔 것이다.
이제 쿠버네티스의 뼈대를 이해했으니, 다음 편에서는 쿠버네티스에서 애플리케이션을 배포하는 가장 기본 단위인 ‘Pod(파드)’와 이를 관리하는 ‘Deployment(디플로이먼트)’에 대해 정리해 보겠다.
왜 컨테이너를 그대로 쓰지 않고 ‘파드’라는 개념을 한 번 더 감싸서 사용하는 걸까?
이 글은 개인 학습을 위해 정리한 내용이며, 오류가 있다면 피드백 부탁드립니다!
궁금한 점은 언제든 질문해 주세요!