Kubernetes ReplicaSet — 직접 만들지 않지만 알아야 하는 이유
Deployment가 알아서 ReplicaSet을 관리해주는데 왜 ReplicaSet을 알아야 할까. 디버깅 시 ReplicaSet을 보는 순간이 반드시 온다.
Kubernetes ReplicaSet — 직접 만들지 않지만 알아야 하는 이유
ReplicaSet의 역할
ReplicaSet은 지정된 수의 Pod 복제본을 항상 유지하는 컨트롤러다.
원하는 상태: 3개 → 현재 2개 → 1개 새로 만든다
원하는 상태: 3개 → 현재 5개 → 2개 죽인다이게 끝이다. Deployment보다 훨씬 단순하다.
그런데 왜 직접 만들지 않는가
Deployment를 쓰면 ReplicaSet을 직접 만들 일이 없다. 그러나:
- 장애 디버깅 시 어떤 ReplicaSet이 문제인지 봐야 한다
- 롤백 가능 여부는 옛 ReplicaSet 보존 개수에 달려있다
- HPA(Horizontal Pod Autoscaler)가 직접 조작하는 객체가 ReplicaSet의
replicas필드다
직접 만들지 않더라도 존재를 알고 읽을 줄 알아야 디버깅이 된다.
기본 YAML
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web-rs
spec:
replicas: 3
selector:
matchLabels:
app: web
tier: frontend
template:
metadata:
labels:
app: web
tier: frontend
spec:
containers:
- name: app
image: nginx:1.27Deployment YAML과 거의 같다. 차이는 kind와 RollingUpdate 같은 배포 전략 필드가 없다는 점.
ReplicaSet과 Pod의 연결 — Selector와 Label
ReplicaSet은 자기 selector에 매칭되는 Pod를 자기 것으로 인식한다.
selector:
matchLabels:
app: web
# 이 Pod도 자기 것으로 흡수된다
apiVersion: v1
kind: Pod
metadata:
labels:
app: web # 같은 label이 동작은 의도하지 않은 흡수를 일으킬 수 있다. 그래서 Deployment는 자동으로 pod-template-hash라는 추가 라벨을 붙여서 ReplicaSet 간 Pod가 섞이지 않게 한다.
kubectl get pods --show-labels
# web-7d4f5-abcde app=web,pod-template-hash=7d4f5
# web-6c2e8-xyz12 app=web,pod-template-hash=6c2e8각 ReplicaSet의 selector에는 해당 hash가 자동 추가된다.
ReplicaSet의 Reconciliation
1. ReplicaSet Controller가 etcd에서 ReplicaSet 객체를 watch
2. 실제 Pod 수 < spec.replicas → 새 Pod 생성
3. 실제 Pod 수 > spec.replicas → 가장 적합한 Pod 삭제
(중단 영향 적은 순서: Pending → Unhealthy → Younger → ...)
4. 무한 반복이 루프가 Kubernetes의 Reconciliation Loop 패턴의 가장 단순한 예시다.
ReplicationController와의 관계
Kubernetes 초창기에는 ReplicationController(rc)가 있었다. ReplicaSet은 그 후속 버전으로:
matchLabels만 지원하던 rc와 달리matchExpressions(In, NotIn, Exists 등)도 지원
selector:
matchExpressions:
- key: tier
operator: In
values: [frontend, mobile]지금은 ReplicationController를 쓸 일이 없다. ReplicaSet도 직접 쓸 일이 거의 없다. Deployment를 통해 간접적으로 만나는 게 정상이다.
정리
ReplicaSet은 "Pod 개수 유지" 한 가지 일을 한다. 직접 만들지는 않더라도 Deployment의 내부 구현으로 항상 같이 다닌다. kubectl get rs가 디버깅의 시작점이 되는 순간이 분명히 온다.
Related Posts
같이 읽으면 좋은 글
Kubernetes CronJob — 정해진 시간마다 Job을 만드는 스케줄러
CronJob은 Job을 직접 실행하지 않는다. 스케줄에 따라 Job 객체를 만들 뿐이다. concurrencyPolicy와 startingDeadlineSeconds를 잘못 쓰면 같은 작업이 중복 실행되는 사고가 난다.
Kubernetes Job — 한 번 실행되고 끝나는 워크로드
DB 마이그레이션, 배치 처리처럼 '성공할 때까지 한 번만' 실행해야 하는 일에 Job을 쓴다. completions, parallelism, backoffLimit 세 필드의 조합이 핵심이다.
Kubernetes DaemonSet — 모든 노드에 정확히 하나씩 떠야 하는 워크로드
로그 수집, 모니터링 에이전트, CNI 플러그인은 왜 Deployment가 아니라 DaemonSet으로 떠야 하는가. 노드 추가/제거 시 자동 대응 메커니즘과 스케줄링 차이를 정리한다.