Kube-controller-manager의 역할: 클러스터의 상태를 유지하는 핵심 루프
1. 선언적 아키텍처의 심장: 조정 루프 (Reconciliation Loop)
쿠버네티스는 선언적(Declarative) 시스템입니다. 사용자가 "파드를 3개 실행해라"라고 절차적으로 명령하는 것이 아니라, "파드가 3개 실행 중인 상태를 원한다(Desired State)"라고 API 서버에 선언합니다. 이때 시스템의 현재 상태(Current State)를 지속적으로 관찰하고, 사용자가 선언한 원하는 상태와 차이가 발생할 경우 이를 일치시키기 위해 끊임없이 작동하는 무한 루프 메커니즘이 필요합니다. 이를 조정 루프(Reconciliation Loop)라고 부르며, 이 루프를 실행하는 주체가 바로 컨트롤러(Controller)입니다. Kube-controller-manager는 이러한 핵심 컨트롤러들을 하나의 바이너리로 묶어 백그라운드에서 구동하는 클러스터의 마에스트로 역할을 수행합니다.

2. Kube-controller-manager의 아키텍처적 특징
쿠버네티스 초기 설계에서는 각 컨트롤러가 독립적인 프로세스로 실행될 수도 있었으나, 수십 개의 컨트롤러를 개별적으로 관리하고 배포하는 것은 운영상의 복잡도를 극도로 증가시킵니다. 따라서 쿠버네티스 코어 팀은 시스템 유지에 필수적인 기본 컨트롤러들을 단일 프로세스인 Kube-controller-manager로 통합했습니다.
이 단일 프로세스 내부에서는 각각의 컨트롤러가 별도의 고루틴(Goroutine)으로 실행되며, API 서버와 통신할 때 공유된 Informer 캐시를 사용하여 메모리와 네트워크 리소스 낭비를 최소화합니다. 각각의 컨트롤러는 다른 컨트롤러의 존재를 알지 못하며, 오직 API 서버를 통해서만 간접적으로 상호작용하는 철저한 디커플링(Decoupling) 구조를 가집니다.
3. 내장된 핵심 컨트롤러들의 역할
Kube-controller-manager 내부에는 클러스터의 생명 유지를 위한 수많은 컨트롤러가 탑재되어 있습니다. 대표적인 핵심 컨트롤러들의 동작 원리는 다음과 같습니다.
- 노드 컨트롤러 (Node Controller): 워커 노드의 상태를 모니터링하고 장애에 대응합니다. Kubelet으로부터 일정 시간(기본 40초) 동안 하트비트(Heartbeat)가 오지 않으면 해당 노드를 'NotReady' 상태로 변경합니다. 이후에도 노드가 복구되지 않으면(기본 5분), 해당 노드에 할당되어 있던 파드들을 안전하게 다른 건강한 노드로 축출(Eviction)하기 위해 API 서버에 파드 삭제를 요청합니다.
- 레플리카셋 컨트롤러 (ReplicaSet Controller): 특정 레이블 셀렉터(Label Selector)와 일치하는 파드의 개수를 지속적으로 카운트합니다. 노드 장애나 파드의 크래시(Crash)로 인해 실행 중인 파드 수가 선언된 개수보다 적어지면 즉각 API 서버에 새로운 파드 생성을 요청합니다. 반대로 사용자가 스케일 다운을 명시하여 파드가 너무 많아지면 잉여 파드를 삭제하여 정확한 수량을 맞춥니다.
- 엔드포인트 컨트롤러 (Endpoint Controller): 서비스(Service)와 파드(Pod)를 네트워크적으로 연결하는 중매쟁이 역할을 합니다. 서비스의 레이블 셀렉터와 일치하는 파드가 생성되거나 삭제될 때마다 엔드포인트(Endpoints) 오브젝트를 업데이트합니다. 이 정보는 이후 Kube-proxy에 의해 읽혀져 실제 트래픽 라우팅 룰을 생성하는 기초 데이터가 됩니다.
- 서비스 어카운트 및 토큰 컨트롤러 (ServiceAccount & Token Controller): 새로운 네임스페이스가 생성될 때마다 기본 서비스 어카운트를 자동으로 생성해 주며, 해당 계정이 API 서버와 통신할 때 사용할 인증 토큰 및 시크릿을 발급하고 관리하는 보안 인프라의 핵심 역할을 수행합니다.
- 가비지 컬렉터 (Garbage Collector): 부모-자식 관계(OwnerReference)를 가진 리소스들을 추적합니다. 예를 들어 Deployment가 삭제되면 그 하위의 ReplicaSet과 Pod들이 고아 상태로 남지 않도록 연쇄적으로 삭제(Cascading Deletion)하여 클러스터의 리소스 누수를 방지합니다.
4. 컨트롤러의 통신 메커니즘: Informer와 Workqueue
수십 개의 컨트롤러가 동시에 수만 개의 리소스 상태를 확인하기 위해 API 서버에 직접 쿼리를 날린다면 클러스터는 즉각 마비될 것입니다. Kube-controller-manager는 이를 방지하기 위해 client-go 라이브러리의 Informer 메커니즘을 적극 활용합니다.
API 서버가 백엔드의 변경 이벤트를 Watch 스트림으로 밀어내면, Kube-controller-manager 내의 SharedInformer가 이를 수신하여 로컬 메모리 캐시를 동기화합니다. 동시에 변경된 리소스의 식별자를 각 컨트롤러의 안전한 작업 대기열(Workqueue)에 삽입합니다. 컨트롤러의 워커 스레드는 이 Workqueue에서 식별자를 하나씩 꺼내어 캐시에서 최신 상태를 읽고, 선언된 상태와 비교한 뒤 필요한 API 서버 요청을 수행합니다. 이 과정에서 발생하는 일시적인 API 서버 통신 실패는 Workqueue의 지수 백오프(Exponential Backoff) 재시도 로직에 의해 안전하게 처리됩니다.
5. 고가용성(HA) 아키텍처와 리더 선출 (Leader Election)
프로덕션 환경에서는 컨트롤 플레인의 장애에 대비해 다수의 마스터 노드를 두고 Kube-controller-manager를 여러 대 실행합니다. 하지만 다수의 노드 컨트롤러나 레플리카셋 컨트롤러가 동시에 활성화되어 동일한 장애 노드에 대해 파드 축출을 시도하거나 파드 생성을 요청한다면, 엄청난 충돌과 데이터 정합성 파괴 현상이 발생합니다.
이러한 경쟁 상태(Race Condition)를 방지하기 위해 Kube-controller-manager는 리더 선출(Leader Election) 메커니즘을 사용합니다. 여러 대의 Kube-controller-manager 프로세스들은 실행 직후 쿠버네티스의 Lease 리소스에 대한 락(Lock)을 획득하기 위해 경쟁합니다. 락을 획득한 단 하나의 인스턴스만이 '리더'가 되어 내부의 모든 컨트롤러 조정 루프를 활성화하고 실제 작업을 수행합니다. 나머지 인스턴스들은 대기(Standby) 상태로 머물며 리더의 하트비트를 지속적으로 감시합니다. 만약 리더 노드에 장애가 발생하여 하트비트가 끊기면, 대기 중이던 인스턴스 중 하나가 즉시 락을 탈취하고 새로운 리더로 승격되어 클러스터의 상태 유지 작업을 중단 없이 이어받습니다.
'1. K8s Core & Architecture > 1.1. 컨트롤 플레인 (Control Plane) 심층 분석' 카테고리의 다른 글
| Kube-scheduler의 구조: 파드가 노드에 할당되기까지의 여정 (0) | 2026.03.16 |
|---|---|
| 컨트롤러 패턴(Controller Pattern) 완벽 이해: Reconcile 루프의 마법 (0) | 2026.03.16 |
| etcd의 Watcher 메커니즘과 Kube-apiserver의 실시간 동기화 원리 (0) | 2026.03.16 |
| etcd 고가용성(HA) 클러스터 구성과 백업/복구 베스트 프랙티스 (0) | 2026.03.15 |
| etcd 심층 분석: 쿠버네티스의 모든 상태 데이터는 어떻게 저장되는가? (0) | 2026.03.15 |