쿠버네티스의 본질은 'Desired State(원하는 상태)'를 유지하는 컨트롤러의 인내심에 있다는 것이다. 내가 관리할 서비스가 장애 중에도 스스로 살아남길 바란다면 컨트롤러를 완벽히 이해해야 한다.
1. 컨트롤러의 4대 핵심 역량
컨트롤러는 단순히 파드를 띄우는 도구가 아니라, 서비스의 생존과 효율을 책임지는 뇌와 같다.

- Auto Healing (자가 치유): 파드나 노드에 장애가 발생하면 이를 즉각 감지하여 다른 건강한 노드에 파드를 새로 생성한다.
- Auto Scaling (자동 확장): 부하가 몰려 리소스가 한계에 다다르면 파드를 추가로 생성해 부하를 분산함으로써 성능 장애를 막는다.
- Software Update (소프트웨어 업데이트): 여러 파드의 버전을 한 번에 업그레이드하거나, 문제 발생 시 이전 버전으로 롤백하는 기능을 지원한다.
- Job (일시적 작업): 필요한 순간에만 파드를 만들어 작업을 수행하고, 완료 후 자원을 반환하여 클러스터 비용을 최적화한다.
- 즉, 일시적인 작업이 필요할 때, 컨트롤러가 파드를 만들고 삭제한다. 자원은 잠시 사용 후에 다시 반환되는 것이다.
2. 리플리케이션 컨트롤러와 리플리카셋의 메커니즘
ReplicationController(RC)는 현재 Deprecated(사용 중단 권장) 되었으며, 이를 대체하는 것이 ReplicaSet(RS)이다.

- Template (설계도): 컨트롤러 내부에 파드 정의를 담고 있다. 파드가 죽으면 이 템플릿을 기반으로 재생성한다.
- 이 특성을 활용해서 이미지를 업그레이드 할 수 있다.
- 템플릿을 V2로 바꾼 뒤 기존 파드를 삭제하면 자연스럽게 파드가 재생성되고, 그 재생성된 건 업그레이드된 형태인 것이다.
- YAML에선 ReplicationController가 selector를 가지고, Pod의 label이 연결된다.
- Replicas (복제본 수): 원하는 파드 개수를 유지한다. 수치를 늘리면 Scale Out, 줄이면 Scale In이 발생하며, 파드가 부족하면 템플릿을 통해 즉시 채워 넣는다.
3. Selector: ReplicaSet(RS)만의 차별화된 무기
ReplicationController는 단순 키-값 일치만 확인하지만, ReplicaSet는 더욱 강력한 매치 익스프레션(MatchExpressions)을 제공한다. 또한 RC를 알아보면서 파악한 내용들은 RS에도 똑같이 기능이 존재한다.

- 먼저, label이 같은 파드만 연결이 되고, 아닌 파드는 연결을 하지 않는 ReplicationContorller과 다르게, ReplicaSet은 두 가지 추가적인 속성으로 달라진다.
- MatchLabels: RC와 똑같이 key, value가 모두 같아야지 연결을 해준다.
- YAML에는 key: value 형태로 들어간다.
- MatchExpressions: key, value를 좀 더 디테일하게 컨트롤 가능하다. 맨 오른쪽 예시를 보면 key: ver이기만 해도 파드와 연결되는 것 처럼 말이다.
- YAML에는 key: value와 더불어, operator도 존재한다.
- Exists: 특정 키가 라벨에 존재하기만 하면 선택한다.
- DoesNotExist: 특정 키가 없는 파드만 골라낸다.
- In: 지정한 '키의 value'가 목록에 포함된 경우 선택한다.
- NotIn: 지정한 '키의 value'가 목록에 없는 경우만 선택한다.
- YAML에는 key: value와 더불어, operator도 존재한다.
- MatchLabels: RC와 똑같이 key, value가 모두 같아야지 연결을 해준다.
💡꼬리 질문
Q: ReplicaSet이 ReplicationController를 완벽히 대체했음에도 불구하고, 실제 운영 환경(Production)에서 우리는 왜 ReplicaSet을 직접 배포하지 않고 'Deployment'라는 상위 오브젝트로 감싸서 사용할까?
결론: ReplicaSet은 '상태 유지'에는 강하지만 '업데이트 전략'에는 한계가 있기 때문이다.
- 배포 전략의 부재: ReplicaSet은 템플릿을 수정해도 기존 파드를 수동으로 죽여야 새 버전이 뜬다. 반면 Deployment는 롤링 업데이트(Rolling Update) 기능을 기본으로 제공하여 서비스 중단 없이 버전을 교체한다.
- 이력 관리와 롤백: Deployment는 배포 이력(Revision)을 기록한다. 새 버전 배포 중 장애가 나면 kubectl rollout undo 한 줄로 즉시 이전의 안정적인 ReplicaSet으로 되돌릴 수 있다.
- 추상화 레벨: 실무에서는 ReplicaSet을 '파드를 관리하는 하위 구현체'로 보고, 관리자는 '배포 프로세스'를 정의하는 Deployment만 바라보는 것이 IaC(코드로서의 인프라) 관점에서 훨씬 효율적이다.
ReplicaSet 실습의 핵심은 '자동화된 상태 유지'와 '정교한 타겟팅'이다. 실무에서는 이 메커니즘을 정확히 이해해야 서비스 중단 없는 운영이 가능하다. 템플릿과 복제본 관리에 맞춰 알아보자.
1. Template & Replicas: 파드의 설계도와 개수
- RC의 대체: ReplicationController는 더 이상 사용되지 않으며(Deprecated), 실습은 그 기능을 모두 포함한 ReplicaSet으로 진행한다.
apiVersion: v1
kind: Pod
metadata:
name: pod1
labels:
type: web
spec:
containers:
- name: container
image: kubetm/app:v1
terminationGracePeriodSeconds: 0
- 빠른 삭제 설정: 실습 중 대기 시간을 줄이기 위해 terminationGracePeriodSeconds: 0 옵션을 사용하여 파드를 즉시 삭제하도록 설정한다.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replica1
spec:
replicas: 1
selector:
matchLabels:
type: web
template:
metadata:
name: pod1
labels:
type: web
spec:
containers:
- name: container
image: kubetm/app:v1
terminationGracePeriodSeconds: 0
- template: ReplicaSet의 template과 Pod의 내용이 완전히 동일한 걸 볼 수 있다.

- 이름 중복 해결: 템플릿에 파드 이름을 pod-1처럼 명시하더라도, ReplicaSet은 이를 무시하고 자신의 이름 뒤에 임의의 문자열을 붙여 고유한 파드 이름을 생성한다.
- 상태 유지: 파드를 수동으로 삭제하면, ReplicaSet은 지정된 replicas 개수를 맞추기 위해 즉시 새로운 파드를 생성한다.
- Replicas 변경 (스케일링): kubectl scale --replicas=2 rs replica1 명령을 통해 실행 중인 파드 개수를 즉시 변경할 수 있다.
2. 업데이트 및 운영 팁
- 수동 버전 업데이트: 템플릿의 이미지를 V2로 수정한 후 기존 파드들을 삭제하면, 새로 생성되는 파드들은 자동으로 V2 버전을 적용받는다.
- Orphan 삭제: 컨트롤러만 지우고 파드는 남겨두고 싶을 때는 -cascade=orphan 옵션을 사용한다.
- kubectl delete rs replica1 --cascade=orphan
- 왜냐하면, 컨트롤러를 삭제하면 연결된 파드들 또한 모두 삭제되기 때문이다.
3. Selector: 정교한 파드 선택 규칙
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replica2
spec:
replicas: 1
selector:
matchLabels:
type: web
ver: v1
matchExpressions:
- {key: type, operator: In, values: [web]}
- {key: ver, operator: Exists}
template:
metadata:
labels:
type: web
ver: v1
location: dev
spec:
containers:
- name: container
image: kubetm/app:v1
terminationGracePeriodSeconds: 0
- !!매칭 규칙!!: selector에 명시된 모든 라벨은 반드시 template.metadata.labels에 포함되어 있어야 한다. 일치하지 않으면 에러가 발생한다.
- v1, v3 등과 같은 세밀한 조건도 같아야함
- MatchExpressions: matchLabels보다 세밀한 조건(In, Exists 등)을 지원하며, 주로 노드 스케줄링 시 강력하게 사용된다. 내가 원하는 오브젝트만 세밀하게 조정 및 선택한다.
- 그래서, 일반적으로는 MatchLabels만 쓰지 MatchExpressions는 잘 안쓴다.
- 나중에 알아볼 예정이지만 Pod YAML 안에 MatchExpressions를 쓸 수 있다. 즉, 굳이 어렵게 컨트롤러 selector에 사용하지 않고, 명시적으로 MatchLabels를 쓰는 경우가 많은 것이다.
- 다중 조건: matchLabels와 matchExpressions를 동시에 사용할 수 있으며, 나열된 모든 조건이 파드의 라벨과 부합해야만 정상적으로 연결된다.
- 즉, MatchExpressions 또한 매칭 규칙을 엄수하여 labes에 동일하게 설정해줘야함.
💡꼬리 질문
Q: ReplicaSet의 템플릿을 수정했는데 왜 기존에 실행 중인 파드들은 새 버전으로 바뀌지 않을까? 그리고 이를 해결하기 위해 실무에서는 무엇을 사용하는가?
결론: ReplicaSet은 '현재 실행 중인 파드'를 감시할 뿐, '기존 파드를 교체'하는 로직은 없기 때문이다.
- 동작 방식의 한계: ReplicaSet은 파드의 개수가 부족할 때만 템플릿을 보고 새로 만든다. 이미 개수가 맞다면 템플릿이 바뀌어도 기존 파드를 건드리지 않는다.
- 실무의 해결책 (Deployment): 이전에도 언급했듯, 실제 운영 환경에서는 Deployment를 사용한다. Deployment는 템플릿이 변경되면 자동으로 새로운 ReplicaSet을 만들고 기존 것을 단계적으로 삭제하는 롤링 업데이트(Rolling Update)를 수행하여 이 문제를 해결한다.
위 학습용 정리 내용 및 사진 자료는 "인프런_대세는 쿠버네티스(https://inf.run/Lv5RV)" 강의를 소스로 작성하였습니다.
'Cloud Native > Kubernetes' 카테고리의 다른 글
| 8. DaemonSet, Job, CronJob (1) | 2026.01.24 |
|---|---|
| 7. Deployment - Recreate, RollingUpdate (0) | 2026.01.23 |
| 5. Namespace, ResourceQuota, LimitRange (0) | 2026.01.18 |
| 4. ConfigMap, Secret - Env, Mount (0) | 2026.01.18 |
| 3. Volume - emptyDir, hostPath, PV/PVC (0) | 2026.01.16 |