• ABOUT
  • PORTFOLIO
  • POSTS
  • GUESTBOOK

© 2025 BlueCool12 All rights reserved.

2026.05.02Kubernetes

⚖️ ReplicaSet으로 파드 관리하기 - YAML부터 운영까지

1. 레플리카셋이 필요한 이유

마이크로서비스 환경에서는 같은 역할을 하는 파드를 여러 개 동시에 운영해야 한다. 트래픽을 나눠 받기 위해서이기도 하고, 일부 인스턴스가 실패해도 나머지가 요청을 계속 처리하도록 가용성을 확보하기 위해서이기도 하다.

따라서 쿠버네티스에서 실제로 다루는 단위는 단일 파드가 아니라 동일한 스펙의 파드 N개가 된다. 이를 직접 정의하기 위해 YAML 매니페스트 안에서 ---를 구분자로 두어 동일한 파드 여러 개를 한 번의 kubectl apply로 생성할 수도 있지만, 이는 비효율적인 방법이다.

또한 파드가 위치한 노드에 장애가 생기면 해당 노드에 있던 파드는 자동으로 다른 노드에서 다시 만들어지지 않는다는 한계도 있다.

즉 사용자가 직접 삭제하고 새로 생성하지 않는 한, 정해진 개수를 유지할 수 없다. 레플리카셋은 이 문제를 두 가지 방식으로 해결한다.

  1. 정의된 수만큼의 동일한 파드가 항상 실행되도록 개수를 유지한다.
    누군가 파드를 삭제하면 부족해진 만큼 즉시 새 파드를 만들어 채운다.
  2. 노드 장애 등으로 기존 파드가 제거되면, 줄어든 개수를 인지하고 정상 노드에서 새 파드를 띄운다.
    동일한 스펙의 파드 N개를 항상 유지하는 보장이 사람이 아닌, 컨트롤러의 책임으로 옮겨간다.


2. 레플리카셋 매니페스트 구조

레플리카셋 매니페스트는 다른 쿠버네티스 리소스와 같은 구조(apiVersion, kind, metadata, spec)를 따른다.

의미가 모이는 곳은 spec이고, 그 안에 세 개의 핵심 필드가 들어간다. 유지할 파드 개수(replicas), 관리할 파드를 식별하는 기준(selector), 그리고 파드를 구성하는 기본 틀(template)이다.

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: example-rs
spec:
replicas: 3
selector:
matchLabels:
app: pods-label
template:
metadata:
labels:
app: pods-label
spec:
containers:
- name: nginx
image: nginx:1.25

spec의 세 필드의 역할은 다음과 같다.

  • spec.replicas: 항상 유지되어야 할 동일한 파드의 개수로, 숫자가 실제 파드 수와 어긋나면 컨트롤러가 그 차이를 메운다.
  • spec.template: 생성할 파드의 모양을 정의한다. 일반 파드 매니페스트와 같은 구조를 가지지만, 그 자체로 실행되는 파드는 아니고 레플리카셋이 관리하는 파드 템플릿으로만 사용된다.
  • spec.selector.matchLables: 레플리카셋이 관리할 파드를 찾을 때 사용하는 라벨로, template.metadata.labels와 일치해야 한다. (selector가 template의 라벨을 매칭)


3. 레플리카셋 정의를 바꾸는 방법

레플리카셋이 한 번 만들어진 뒤에 replicas를 늘리거나 이미지 태그를 바꿔야 할 경우가 생기는데, 이때 클러스터에 적용된 정의를 갱신하는 방법이 세 가지 있다.

1. kubectl apply -f
원본 YAML 파일을 고친 뒤 같은 명령으로 다시 적용한다. 동일 이름의 객체가 이미 존재하는 경우, API 서버가 마지막에 적용된 정의와 새 정의를 비교해 변경분만 반영한다.

결과 메시지가 어떤 동작이 일어났는지를 구분해 준다. (새로 만들어졌으면 created, 갱신되면 configured, 변경이 없으면 unchanged)

매니페스트가 단일 진실 공급원으로 유지되기 때문에 GitOps, 형상관리 관점에서 권장되는 방식이다.

2. kubectl edit rs <name>
명령을 실행하면 현재 객체의 정의가 임시 파일로 편집기에 열린다. 값을 고치고 저장하면 클러스터에 반영되며, 1회성 빠른 수정에 편리하다.

다만 변경 내용이 로컬의 원본 매니페스트에는 반영되지 않기 때문에 이후 kubectl apply -f로 원본 파일을 다시 적용하면 edit으로 한 변경이 되돌아갈 수 있다.

3. kubectl patch rs <name>
필드 하나만 명령줄에서 바꾸는 방법이다. 예를 들어 replicas만 5로 변경하려면 다음과 같다.

kubectl patch rs example-rs -p '{"spec":{"replicas":5}}'

자동화 스크립트나 CI에서 한 줄로 특정 필드만 갱신할 때 적합하다. edit과 마찬가지로 로컬 매니페스트와의 정합성은 운영자가 따로 챙겨야 한다.


4. 레플리카셋과 파드의 결합

레플리카셋과 관리되는 파드는 직접 연결돼 있지 않다. 대신 spec.selector.matchLabels에 정의된 라벨 조건을 매 시점 클러스터에 던져, 그 조건에 맞는 파드를 그때그때 관리 대상으로 본다. 이런 연결 방식을 느슨한 결합(loose coupling)이라고 한다.

레플리카셋이 동작하는 방식도 이 결합 모델 위에서 정해진다. 컨트롤러는 selector에 매칭되는 파드의 개수를 세고, 그 수가 replicas보다 적으면 부족분만큼 template에 정의된 모양으로 새 파드를 만들고 반대로 많으면 일부를 지운다.

즉 "지금 이 라벨에 맞는 파드가 몇 개냐" 가 모든 결정의 기준이 된다.

같은 라벨을 가진 파드가 클러스터에 미리 존재하는 상태에서 레플리카셋을 새로 만들면, 그 파드는 처음부터 자기 관리 대상으로 잡히며 레플리카셋은 부족분만 추가로 띄운다.

반대로 이미 관리 중인 파드의 라벨을 바꾸면, 그 파드는 selector 조건에서 벗어나 관리 대상에서 제외된다. 레플리카셋은 줄어든 개수를 채우려 새 파드를 띄우고, 라벨이 바뀐 파드는 그대로 살아남는다.


5. 레플리카셋과 레플리케이션 컨트롤러

레플리카셋이 등장하기 전에 같은 역할을 하던 리소스는 레플리케이션 컨트롤러(ReplicationController)였다. 둘 다 파드 개수를 유지한다는 같은 목적을 갖지만, 쿠버네티스 초기에 레플리카셋이 도입된 이후 신규 작성되는 워크로드는 거의 모두 레플리카셋 계열로 옮겨 갔다.

핵심 차이는 라벨 셀렉터의 표현력이다. 레플리케이션 컨트롤러의 셀렉터는 key=value 형태의 동등 비교만 지원했다. 레플리카셋은 여기에 더해 표현식 기반 셀렉터, 즉 matchExpressions를 지원한다.

matchExpressions는 한 키에 대해 여러 값을 묶거나, 키의 존재 유무로 매칭하는 등 동등 비교만으로는 만들 수 없는 조건을 표현할 수 있다.

이전 글
👵🏻 쥬디 할머니 | 박완서
다음 글
다음 글이 없습니다 ( · . ·)
장식용 로고