지금까지는 Pod를 직접 만들고 실행 설정, 상태 점검, 자원 요청량을 지정했다. 하지만 직접 만든 Pod가 삭제되면 Kubernetes가 같은 Pod를 자동으로 새로 만들지는 않는다. 애플리케이션을 지속해서 운영하려면 현재 상태를 관찰하고 원하는 상태로 되돌리는 관리자가 필요하다.

Kubernetes의 컨트롤러는 이 작업을 반복하는 제어 루프다. 이번 글에서는 여러 컨트롤러의 상세 YAML에 들어가기 전에 spec, status, 조정 과정과 워크로드 선택 기준을 먼저 정리한다.


1. 원하는 상태와 현재 상태를 구분한다

Kubernetes 오브젝트에는 사용자가 선언하는 원하는 상태와 시스템이 관찰한 현재 상태가 있다.

구분 대표 필드 의미
원하는 상태 spec 사용자가 만들고 싶은 상태
현재 상태 status 컨트롤러가 관찰한 실제 상태

예를 들어 replicas: 3을 선언한 Deployment에서 Pod가 두 개만 실행 중이라면 원하는 상태와 현재 상태가 다르다.

원하는 상태: Pod 3개
현재 상태:   Pod 2개
차이:        Pod 1개 부족

컨트롤러는 이 차이를 발견하고 Pod 하나를 추가하도록 동작한다.


2. 컨트롤러는 조정을 반복한다

컨트롤러가 원하는 상태와 현재 상태의 차이를 줄이는 과정을 조정(Reconciliation)이라고 한다.

리소스 관찰 → 원하는 상태와 비교 → 필요한 작업 수행 → 다시 관찰

Pod 하나가 사라졌을 때 사용자가 직접 복구 명령을 실행하는 방식과 달리, 컨트롤러는 상태를 계속 확인한다. 이 때문에 일시적인 장애가 발생하더라도 선언한 상태를 기준으로 스스로 복구할 수 있다.

컨트롤러는 일반적으로 Label Selector로 관리할 Pod를 찾고, Pod를 새로 만들 때는 template을 설계도로 사용한다.

spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.27

앞에서 배운 Label과 Selector가 여기서 관리 대상을 연결한다.


3. Pod를 직접 만드는 경우와 비교한다

직접 만든 Pod와 컨트롤러가 관리하는 Pod는 장애 후 동작이 다르다.

상황 직접 만든 Pod 컨트롤러가 관리하는 Pod
컨테이너 프로세스 종료 restartPolicy에 따라 kubelet이 재시작 동일
Pod 삭제 자동 재생성되지 않음 컨트롤러가 대체 Pod 생성
복제본 수 변경 Pod를 직접 추가·삭제 replicas 변경
이미지 업데이트 Pod를 다시 만들어야 함 Deployment 등이 교체 과정 관리

컨테이너 재시작과 Pod 재생성도 구분해야 한다. 실행 중인 Pod 안의 컨테이너를 재시작하는 주체는 해당 노드의 kubelet이고, Pod 자체가 사라졌을 때 새로운 Pod를 만드는 주체는 상위 컨트롤러다.


4. 목적에 따라 워크로드 리소스를 선택한다

모든 애플리케이션을 같은 컨트롤러로 운영하지는 않는다.

리소스 해결하는 문제 대표 사례
ReplicaSet 같은 Pod를 지정한 개수만큼 유지 보통 Deployment 내부에서 사용
Deployment 무상태 앱의 복제, 업데이트, 롤백 웹 서버, API 서버
DaemonSet 조건에 맞는 각 노드에 Pod 배치 로그 수집기, 노드 모니터링
StatefulSet 안정적인 이름과 개별 스토리지 제공 데이터베이스, 메시지 브로커
Job 완료해야 하는 작업 실행 데이터 변환, 일회성 배치
CronJob 일정에 따라 Job 생성 백업, 정기 집계

일반적인 서버 애플리케이션은 Deployment부터 검토한다. 각 노드에서 반드시 실행해야 하면 DaemonSet, 완료가 목적이면 Job, Pod마다 유지되는 정체성과 저장 공간이 필요하면 StatefulSet을 고려한다.

StatefulSet은 Headless Service와 PersistentVolume을 함께 이해해야 하므로 이 연재에서는 Service와 스토리지를 배운 뒤 자세히 다룬다.


5. 상위 리소스와 하위 리소스의 관계를 읽는다

Deployment를 만들면 보통 다음과 같은 계층이 만들어진다.

Deployment
└── ReplicaSet
    ├── Pod
    ├── Pod
    └── Pod

kubectl getdescribe로 각 계층을 확인할 수 있다.

kubectl get deployment,replicaset,pod
kubectl describe deployment <deployment-name>
kubectl describe replicaset <replicaset-name>

하위 오브젝트의 metadata.ownerReferences에는 자신을 관리하는 상위 오브젝트가 기록된다. 컨트롤러가 관리하는 Pod를 직접 수정하거나 삭제하기 전에 어느 리소스가 소유하고 있는지 확인해야 하는 이유다. Pod만 수정해도 상위 컨트롤러의 템플릿은 바뀌지 않으며, Pod가 교체되면 직접 수정한 내용은 사라진다.


6. 이후 학습 순서

다음 글부터는 컨트롤러를 다음 순서로 살펴본다.

  1. ReplicationController를 통해 초기 복제 컨트롤러의 원리를 이해한다.
  2. ReplicaSet에서 Selector와 복제본 유지 기능을 확인한다.
  3. Deployment에서 업데이트와 롤백을 다룬다.
  4. DaemonSet으로 노드별 Pod를 관리한다.
  5. Job과 CronJob으로 완료형 작업을 실행한다.
  6. Service와 스토리지를 학습한 뒤 StatefulSet을 구성한다.

ReplicationController는 새 애플리케이션에 권장되는 선택은 아니지만, 다음 글에서는 ReplicaSet으로 발전한 이유를 이해하기 위한 연결 단계로만 다룬다.


7. 정리

컨트롤러는 원하는 상태와 현재 상태를 반복해서 비교하고 그 차이를 줄인다. 덕분에 Pod가 사라져도 복제본 수를 복구하고, 워크로드 종류에 따라 업데이트·노드별 배치·완료형 작업·안정적인 식별자를 관리할 수 있다.

컨트롤러의 이름을 외우기보다 애플리케이션이 계속 실행되어야 하는지, 완료되어야 하는지, 모든 노드에 필요한지, 안정적인 이름과 저장 공간이 필요한지를 먼저 판단하면 알맞은 리소스를 선택하기 쉽다.


참고 자료