ReplicaSet이란?
ReplicaSet은 항상 정해진 수의 Pod 복제본을 안정적으로 유지하는 데 목적이 있습니다. 쉽게 말해, 동일한 Pod가 지정한 개수만큼 언제나 실행되도록 보장하는 역할을 합니다.
ReplicaSet은 어떻게 동작할까?
ReplicaSet은 세 가지 핵심 요소로 정의됩니다
1. Selector : 어떤 Pod를 관리 대상으로 삼을지 정하는 기준
2.복제본 수 : 유지해야 할 Pod의 개수
3. Pod Template : 새 Pod를 만들 때 사용할 설계도
ReplicaSet은 이 요소들을 바탕으로 필요한 만큼 Pod를 생성하거나 삭제합니다. Pod는 `Metadata.ownerReferences` 필드를 통해 ReplicaSet과 연결되는데, 이 덕분에 ReplicaSet이 자신이 관리하는 Pod의 상태를 파악하고 적절히 대처할 수 있습니다.
ReplicaSet과 Deployment의 관계
Deployment는 ReplicaSet을 한 단계 위에서 관리하며 Pod에 대한 선언적인 업데이트를 지원하는 상위 개념입니다. 보통은 ReplicaSet을 직접 다루기보다 Deployment를 쓰는 걸 추천하는데, 이유는 다음과 같습니다
– Deployment가 ReplicaSet을 알아서 관리해줌
– 롤링 업데이트 같은 고급 기능 제공
– 복잡한 업데이트 조정이 필요 없는 경우 더 간편함
ReplicaSet 사용 예시
아래는 3개의 Pod를 실행하는 간단한 ReplicaSet 예제입니다.
apiVersion: apps/v1 kind: ReplicaSet metadata: name: frontend labels: app: guestbook tier: frontend spec: replicas: 3 selector: matchLabels: tier: frontend template: metadata: labels: tier: frontend spec: containers: - name: php-redis image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5
NOTE. 적용 명령어 kubectl get rs NOTE. Pod 소유권 ReplicaSet은 단순히 Pod Template에 명시된 Pod만 관리하는 게 아니라, 하기 조건을 만족하는 모든 Pod 도 관리 할 수 있습니다. |
ReplicaSet Manifest 작성 시 주의점
1. apiVersion, kind, metadata 필드는 필수입니다 (kind는 당연히 `ReplicaSet`)
2. .spec 섹션에는 하기 3가지가 반드시 포함돼야 합니다
– Pod Template : Pod를 만들 때 사용할 템플릿 (`.spec.template`)
– Pod Selector : 관리할 Pod를 찾는 라벨 셀렉터 (`.spec.selector`)
– Replicas : 유지할 Pod 개수 (기본값은 1)
추가적으로 .spec.template.metadata.labels와 .spec.selector가 일치해야 하며, restartPolicy는 Always만 가능합니다 (기본값임).
밑에 명령어는 replicaset 을 관리할때 유용한 명령어 입니다.
# ReplicaSet과 그에 속한 모든 Pod를 함께 삭제 kubectl delete rs/frontend # 이 명령어는 frontend라는 이름의 ReplicaSet과 그에 의해 생성된 모든 Pod를 삭제합니다. # 기본적으로 ReplicaSet을 삭제하면, 해당 ReplicaSet이 관리하는 Pod들도 함께 제거됩니다. # ReplicaSet만 삭제하고 Pod는 남기기 kubectl delete rs/frontend --cascade=orphan # --cascade=orphan 옵션을 사용하면 ReplicaSet만 삭제되고, # 기존에 생성된 Pod들은 계속 남아 있습니다. # 이를 통해 ReplicaSet과의 연결을 끊고, Pod를 유지하면서 상태를 확인하거나 별도로 관리할 수 있습니다. # Pod를 ReplicaSet에서 제외하기 kubectl label pod <pod-name> app- # 특정 Pod의 라벨을 변경하여 ReplicaSet에서 제외할 수 있습니다. # ReplicaSet은 특정 라벨을 기준으로 Pod를 관리하므로, # 해당 라벨을 제거하면 ReplicaSet의 관리 대상에서 벗어나게 됩니다. # 예를 들어, 디버깅을 위해 특정 Pod를 유지하고 싶을 때 유용합니다. # ReplicaSet의 Pod 개수를 조정하기 (확장/축소) kubectl scale rs/frontend --replicas=5 # frontend라는 ReplicaSet의 복제본 개수를 5개로 변경합니다. # 즉, 현재 3개라면 2개를 추가 생성하고, 현재 7개라면 2개를 제거하여 총 5개가 되도록 조정합니다.
Pod 삭제 우선순위
ReplicaSet이 축소될 때 Kubernetes는 특정 기준을 바탕으로 어떤 Pod를 우선적으로 삭제할지 결정합니다. 삭제 우선순위는 다음과 같습니다.
1. 보류 중이거나 예약되지 않은 Pod
– 스케줄링이 되지 않아 Pending 상태인 Pod가 가장 먼저 삭제됩니다.
– 리소스 부족, 노드 할당 문제 등으로 인해 실행되지 못한 Pod가 우선적으로 제거됩니다.
2. controller.kubernetes.io/pod-deletion-cost 값이 낮은 Pod
– controller.kubernetes.io/pod-deletion-cost 어노테이션을 사용하면 특정 Pod의 삭제 우선순위를 조정할 수 있습니다. 이 값이 낮을수록 해당 Pod는 먼저 삭제됩니다. 반대로 높은 값을 설정하면 다른 Pod가 먼저 삭제되고, 해당 Pod는 최대한 유지됩니다. 예를 들어, 중요한 애플리케이션이 실행 중인 Pod의 삭제를 지연시키려면 높은 값을 설정할 수 있습니다.
3. 복제본이 많은 노드에 있는 Pod
– 여러 개의 노드에 동일한 ReplicaSet의 Pod가 분산되어 있을 경우, 클러스터 전체의 부하 균형을 유지하고, 특정 노드에 불필요한 리소스 집중을 방지하기 위해서 특정 노드에 과도하게 많은 복제본부터 우선적으로 삭제합니다.
4. 최근에 생성된 Pod
– 위 조건이 모두 동일한 경우, 가장 최근에 생성된 Pod가 먼저 삭제됩니다.
Pod 삭제 우선순위 조정하기
controller.kubernetes.io/pod-deletion-cost 주석을 활용하면 삭제 순서를 직접 제어할 수 있습니다. 특정 Pod가 더 중요하거나 덜 중요할 때 어떤 걸 먼저 지울지 정할 수 있는 기능이죠.
실제 예시
3개의 Pod가 있는 ReplicaSet을 가정해 봅시다.
# 중요한 Pod - 나중에 삭제되길 원함 apiVersion: v1 kind: Pod metadata: name: critical-pod annotations: controller.kubernetes.io/pod-deletion-cost: "1000" # 높은 값 # 평범한 Pod apiVersion: v1 kind: Pod metadata: name: normal-pod annotations: controller.kubernetes.io/pod-deletion-cost: "100" # 중간 값 # 덜 중요한 Pod - 먼저 지워져도 괜찮음 apiVersion: v1 kind: Pod metadata: name: low-priority-pod annotations: controller.kubernetes.io/pod-deletion-cost: "-100" # 낮은 값
ReplicaSet을 3개에서 1개로 줄이면 삭제 순서는
1. low-priority-pod (-100)
2. normal-pod (100)
3. critical-pod는 남음 (1000)
순서로 삭제됩니다.
활용 사례
이 기능은 이런 상황에서 빛을 발합니다.
1. 상태 기반 앱 : 중요한 데이터나 상태를 가진 Pod를 보호할 때
2. 트래픽 관리 : 핵심 트래픽을 처리 중인 Pod를 남길 때
3. 리소스 활용 : 사용량이 높은 Pod를 유지하고 낮은 Pod를 먼저 제거할 때
4. 초기화 비용 : 시작 시간이 긴 Pod를 보호할 때
중요한 Pod를 지키면서 앱의 안정성과 성능을 유지할 수 있는 방법입니다.
ReplicaSet의 대안
Deployment (추천)
대부분의 경우 Deployment를 쓰는 게 낫습니다. ReplicaSet을 관리하며 롤링 업데이트 같은 기능도 제공하니까요.
Job
일회성 작업처럼 스스로 종료되는 Pod라면 Job을 사용하는것이 더 좋을 수 있습니다.
DaemonSet
모든 노드에서 실행해야 하는 모니터링이나 로깅 Pod라면 DaemonSet이 적합합니다.
ReplicaSet은 일정 개수의 Pod 복제본을 유지하며 앱의 가용성을 보장하는 핵심 리소스입니다. 다만, 직접 관리하기보다는 Deployment를 통해 다루는 게 더 효율적이죠. 이후에는 Deployment 와 다른 리소스를 소개함과 동시에 클러스터운영에대한 내용을 작성하러 찾아오도록 하겠습니다.