본문으로 건너뛰기

Replication Controller & ReplicaSet


Replication Controller가 필요한 이유

High Availability (고가용성)

replicaset1

  • Pod가 하나이더라도, Replication Controller는 기존 Pod에 장애가 생기면, 자동으로 새로운 Pod를 생성해서 고가용성을 유지한다. 즉, Replication Controller는 정해진 갯수의 Pod가 항상 실행되도록 보장한다.

Load Balancing & Scaling

replicaset2

  • 처음에 단일 Pod라고 가정하자.
  • 트래픽이 증가하면 추가 Pod를 배포한다.
  • 트래픽이 더 증가하고 첫번째 Node의 자원이 부족해지면 새로운 Node에 추가 Pod를 배포한다.
  • 위의 예시처럼 Replication controller는 여러 Node에 걸쳐서 존재하며, 서로 다른 Node에서 여러 Pod에 걸쳐 Load Balancing을 하고 애플리케이션을 확장하는데 도움을 준다.
경고

ReplicaSet은 직접적으로 Load Balancing을 하는 주체가 아니다. 단지 지정된 갯수의 Pod가 실행되고 있도록 보장하며, Service가 Load Balancing의 주체이다.

위의 설명은 Service가 실행하는 Load Balancing을 ReplicaSetPod의 갯수를 유지하며 돕는다는 뜻이다.


ReplicaSet vs Replication Controller

  • Replication Controller는 현재 운영환경에서 거의 사용되지 않는 레거시 기술이며, ReplicaSet으로 대체되었다.
  • 왜냐하면, Replication Controller는 '지정된 수의 Pod를 유지하는 역할'은 수행할 수 있지만, 이전 버전으로의 Rollback, 새로운 버전으로의 Rolling 등의 배포 전략 기능이 없기 때문이다.
  • 이에 기존의 Replication Controller의 기능을 ReplicaSet으로 대체하고, ReplicaSet을 자동으로 생성하고 관리하는 Deployment를 도입해 해당 기능들을 지원하게 되었다.
    • 새로운 버전 배포 -> Deployment가 새로운 ReplicaSet을 생성하고 Rolling 업데이트로 Pod 순차적 교체
    • 이전 버전 롤백 -> 이전 ReplicaSetPod 수를 0으로 하고 오브젝트 자체를 유지하면서, 롤백을 해야할 경우 이전 ReplicaSetPod 수를 늘리면서 복구한다.
  • 즉, DeploymentReplicaSet을 관리하느 컨트롤러이고, ReplicaSetPod를 관리하는 컨트롤러이다.

YAML

Replication Controller

# rc_definition.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myapp-rc
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
  • apiVersion, kind, metadataPod와 크게 다른 점 없음
    • apiVersion의 경우 Replication Controllerv1 이다.
    • kindReplicationController
  • spec
    • template(Dictionary): Replication Controller에서 사용할 Pod의 정보를 작성한다.
      • Pod의 Yaml 작성에서 apiVersionkind를 제외한 다른 모든 것을 그대로 작성하면 된다.
    • replicas: 유지할 Pod의 갯수
kubectl create -f rc-defination.yaml
  • Replication Controller 생성
kubectl get replicationcontroller
  • default 네임스페이스에 있는 모든 Replication Controller 조회

ReplicaSet

사실 Deployment yaml 을 작성하고 적용하면 이에 맞는 ReplicaSet이 자동으로 생성되기 때문에, ReplicaSet yaml을 작성할 일은 거의 없다.

# replicaset-definition.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-replicaset
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector:
matchLabels:
type: front-end
  • apiVersion, kind, metadataPod와 크게 다른 점 없음
    • apiVersion의 경우 ReplicaSetapps/v1 이다.
    • kindReplicaSet
  • spec
    • template(Dictionary): Replication Controller에서 사용할 Pod의 정보를 작성한다.
      • Pod의 Yaml 작성에서 apiVersionkind를 제외한 다른 모든 것을 그대로 작성하면 된다.
    • replicas: 유지할 Pod의 갯수
    • selector(Dictionary): ReplicaSet에 속하는 Pod를 식별하는데 사용한다.
      • matchLabels: labels 필드의 하위 타입들(type, app, role 등의 사용자 지정 필드)을 지정하여 관리할 Pod의 집합을 식별한다.
      • Replication Controller와의 가장 큰 차이점 중 하나이다. (selector 필드의 경우 ReplicaSet에서는 필수이지만, Replcation Controller에서는 Optional하게 사용한다)
      • 이에 spec.selector.matchLabels에 정의된 모든 key-value 쌍은spec.template.metadata.labels에 포함되어 있어야 한다. (즉, spec.selector.matchLabelsspec.template.metadata.labels의 부분집합이어야 한다.)
정보

template에서 Pod를 정의했는데 selector가 왜 필요할까? -> ReplicaSet은 해당 ReplicaSet이 생성되기 이전의 Pod도 관리하는 경우가 있기 때문이다.

  • Use Case) ReplicaSet이 생성되기 이전에 typefront-end인 단일 Pod가 존재했다고 가정해보자. 이때, replicas가 3인 ReplicaSet을 생성하면서 typefront-end로 설정했다면, 기존의 Pod를 고려하면서 새로운 Pod는 2개만 생성한다.

그럼 이미 같은 3개의 Podtype을 같게해서 배포해둔 뒤에, 이를 관리하기 위해 ReplicaSetreplicas를 3으로 지정해서 실행한다면, 새로운 Pod를 더이상 배포하지 않기 때문에 ReplicaSet의 yaml에 template를 작성하지 않아도 될까?

-> 아니다 작성해야한다. 왜냐하면, 어떠한 Pod가 종료되었을 때, 새로운 Pod를 생성하는데 필요하기 때문이다.

kubectl apply -f replicaset-definition.yaml
  • ReplicaSet 생성
kubectl get replicaset
  • default 네임스페이스의 모든 ReplicaSet 조회

ReplicaSet 확장

방법1: yaml 수정 및 적용

...
replicas: 6
kubectl apply -f replicaset-definition.yaml

방법2: scale 명령어 사용 (yaml 대상)

kubectl scale --replicas=6 -f replicaset-definition.yaml
  • 현재 실행되고 있는 ReplicaSetPod 수는 6개로 바뀌지만, yaml 파일의 replica 필드의 값이 바뀌는 것은 아니다.

방법3: sclae 명령어 사용 (type, name 대상)

kubectl scale --replicas=6 replicaset myapp-replicaset

추가 명령어

kubectl delete replicaset myapp-replicaset
  • pod들도 함께 종료된다.
kubectl replace -f replicaset-definition.yaml
  • 수정한 yaml 파일을 적용한다.

레퍼런스