Kubernetes/05. 컨트롤러 종류 및 설명

[쿠버네티스] k8s 레플리카셋(ReplicaSet) 이란? & 레플리케이션 컨트롤러와의 비교

Jaden Park 2021. 6. 27. 23:56

들어가며: 레플리카셋를 왜 쓰는걸까요?

레플리카셋과 레플리케이션 컨트롤러의 비교

레플리카셋 생성

레플리카셋 확인

레플리카셋의 레이블 셀렉터 사용

  • matchLabels 레이블 셀럭터
  • matchExpressions 레이블 셀럭터

 

matchExpressions를 사용한 레플리카셋 생성

파드의 수평 스케일링

레플리케이션 컨트롤러 및 파드 삭제

 

 


들어가며 : 레플리카셋(replicaSet)를 왜 쓰는걸까요?

쿠버네티스의 기본 단위인 Pod는 여러 개의 컨테이너를 추상화해 하나의 애플리케이션으로 동작하도록 만드는 훌륭한 컨테이너 묶음입니다. 그러나 YAML에 포드만 정의해 생성하게 되면 이 Pod의 생애 주기(Lifecycle)은 컨테이너 삭제 시 영원히 사라지게 됩니다.

 

이처럼 yaml 파일에 포드만 정의해 생성할 경우 해당 포드는 오직 쿠버네티스 사용자에 의해 관리합니다. 실제로 외부 사용자의 요청을 처리해야 하는 마이크로 서비스 구조의 포드라면 이러한 방식을 사용하기 어렵습니다.

 

여러 개의 포드를 직접 생성하는 방법은 여러 가지 이유로 적절하지 않습니다. 우선 동일한 포드의 개수가 많아질수록 일일이 정의하는 것은 매우 비효율적인 작업이며, 포드가 어떠한 이유로든지 삭제되거나, 포드가 위치한 노드에 장애가 발생해 더 이상 포드에 접근하지 못하게 됐을 때, 직접 포드를 삭제하고 다시 생성하지 않는 한 해당 포드는 다시 복구되지 않습니다.

 

이러한 경우 레플리카셋이라는 쿠버네티스 오브젝트를 함께 사용하는 것이 일반적입니다.

레플리카셋이 수행하는 역할을 간단하게 설명하면 다음과 같습니다.

 

  • 정해진 수의 동일한 포드가 항상 실행되도록 관리합니다.
  • 노드 장애 등의 이유로 포드를 사용할 수 없다면 다른 노드에서 포드를 다시 생성합니다.

 

 

이전 포스팅에서 레플리케이션 컨트롤러에 대해 설명하였습니다. 이전 글과 함께 읽는다면 도움이 될 것입니다.

 

 

쿠버네티스가 처음 나왔을 때 파드를 복제하고 파드가 실패했을 때 새 파드를 만드는 컨트롤러는 앞서 살펴본 레플리케이션 컨트롤러가 유일한 컨트롤러였습니다. 그러나 레플리케이션 컨트롤러의 몇몇 문제점 및 기능 개선을 위해 레플리카셋 이라는 컨트롤러를 추가했습니다.

 

레플리카셋(replicaSet)은 레플리케이션 컨트롤러가 제공하는 기능과 거의 비슷합니다. 기본적으로 요구하는 복제본 개수만큼 파드를 복제하고 모니터링하고 관리합니다.

 

현재는 레플리케이션 컨트롤러보다 레플리카셋 또는 디플로이먼트를 사용하는 것을 권장합니다.

 


 

레플리카셋과 레플리케이션 컨트롤러의 비교

레플리카셋의 기본 목적은 레플리케이션 컨트롤러와 같지만, 레플리카셋은 레이블 셀렉터"집합성 기준" 레이블 셀렉터를 지원합니다. (레플리케이션 컨트롤러는 "일치성 기준" 레이블 셀렉터만 지원)

 

"일치성 기준" 레이블 셀렉터는 "키=값" 모두 일치해야 하지만 "집합성 기준" 레이블 셀렉터는 "키=값" 모두 일치하거나, "키"만 일치하는 것도 지원합니다.

- 레플리케이션 컨트롤러: 일치성 기준 레이블 셀렉터 지원

- 레플리카셋: 일치성 및 집합성 기준 레이블 셀렉터 지원

 


 

레플리카셋 생성

지금까지 생성한 오브젝트(파드 및 레플리케이션 컨트롤러)의 API 버전은 v1이었지만, 지금 생성하는 레플리카셋은 apps/v1 API를 사용합니다. 즉, 레플리카셋은 apps API 그룹에 속하며 v1 버전을 사용합니다.

 

// 그룹과 버전 확인
$ kubectl api-resources
$ kubectl api-versions

 

 

레플리케이션 컨트롤러에서 생성한 myapp-rc.yaml 파일과 똑같은 기능을 하는 레플리카셋을 생성해보겠습니다.

 

//myapp-rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp-rs
  template:
    metadata:
      labels:
        app: myapp-rs
    spec:
      containers:
      - name: myapp
        image: ghcr.io/c1t1d0s7/go-myweb
        ports:
        - containerPort: 8080

앞서 설명한 대로 apiVersion은 apps/v1 를 사용하여 생성할 종류는 ReplicaSet 입니다. 또한 레플리케이션 컨트롤러에서는 레이블 셀렉터 항목에 레이블을 직접 지정했지만, 레플리카셋 matchLabels 및 matchExpressions 필드로 레이블을 선택합니다.

 

.spec.selector.matchLabels: 일치성 기준 레이블 셀렉터 지정

.spec.selector.matchExpressions: 집합성 기준 레이블 셀렉터 지정

 

matchLabels는 레플리케이션 컨트롤러와 같이 특정 레이블의 키=값을 매칭하게 됩니다. 기능상 완전하게 똑같이 작동합니다.

 

 


레플리카셋 확인

레플리카셋을 생성한 뒤 확인해보겠습니다.

레플리카셋에 의해 파드가 생성되어 실행중인 것을 확인할 수 있습니다.


레플리카셋의 레이블 셀렉터 사용

 

matchLabels 레이블 셀렉터

spec:
  selector:
    matchLabels:
      key: value

matchlabels로 레이블 셀렉터를 사용하는 경우는 레플리케이션 컨트롤러와 똑같이 동작합니다.

 

 

matchExpressions 레이블 셀렉터

spec:
  selector:
    matchExpressions:
    - key: <string>
      operator: <In | NotIn | Exists | DoesNotExist>
      values:
      - <string>

matchExpressions 필드는 집합성 기반 레이블 셀렉터를 지원합니다.

.spec.selector.matchExpressions.key: 선택할 레이블의 키 이름을 지정

.spec.selector.matchExpressions.values: 레이블의 값을 지정

.spec.selector.matchExpressions.operator: 연산자

 

연산자의 종류는 다음과 같습니다.

- In: 레이블의 키와 값이 지정된 값으로 일치해야 합니다

- NotIn: 레이블의 키와 값이 지정된 값과 일치하지 않아야 합니다

- Exists: 레이블의 키가 포함되어야 합니다 (값은 해당사항 없음)

- DoesNotExist: 레이블의 키가 포함되지 않아야 합니다

- Exists와 DoesNotExist는 레이블의 키값만 매칭합니다. 즉, values 항목을 설정하지 않습니다.

 


matchExpressions를 사용한 레플리카셋 생성

 

//myapp-rs-exp.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp-rs-exp
spec:
  replicas: 3
  selector:
    matchExpressions:
      - key: app
        operator: In
        values:
          - myapp-rs-exp
      - key: env
        operator: Exists
  template:
    metadata:
      labels:
        app: myapp-rs-exp
        env: dev
    spec:
      containers:
      - name: myapp
        image: ghcr.io/c1t1d0s7/go-myweb
        ports:
        - containerPort: 8080

 

matchExpressions 레이블 셀렉터는 반드시 YAML의 리스트로 표현해야 합니다.

매칭하고자 하는 셀렉터는 app 키에 myapp-rs-exp 값이 있어야 하며, env키가 있어야 합니다. 두 조건 다 만족해야하는 AND 연산입니다.

 

파드 템플릿의 레이블은 app=myapp-rs-exp 및 env=dev로 설정하였습니다.

 

생성 후 레플리카셋을 확인해보겠습니다.

 

-o wide 옵션을 사용하면 조금 더 자세한 정보를 확인할 수 있습니다.

--show-labels 옵션을 사용하면 레이블 셀렉터 필드를 볼 수 있습니다.

 

결론적으로 레플리카셋을 정리하면 레플리케이션 컨트롤러와 기능이 같지만, 집합성 기반의 레이블을 지원합니다.

 

추후 레플리케이션 컨트롤러는 더 이상 사용되지 않을 것으로, 레플리카셋을 사용할 것은 권장합니다.