본문 바로가기
Framework and Tool/Kubernetes

Kubernetes - ReplicaSet, DaemonSet

by ocwokocw 2022. 10. 14.

- 출처: Kubernetes in action

- 레플리카 셋

초기에는 레플리케이션 컨트롤러(이하 "rc") 만이 파드를 복제하고 노드에 장애가 발생하면 재 스케줄링 하는 유일한 쿠버네티스 구성요소였다. 이후 등장한 레플리카 셋은 차세대 구성요소이며, rc는 사장될 예정이다. 현재 쿠버네티스 rc 문서(https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/) 에서도 레플리케이션을 세팅할 때는 디플로이먼트를 사용할것을 권고하고 있다.
 
rc와 레플리카셋은 거의 동일해서 하나만 알면 다른 하나를 사용하는데 무리가 없다. 일반적으로 레플리카셋 리소스를 직접 생성 하지는 않으며 상위 수준의 디플로이먼트 리소스를 이용한다.
 
레플리카셋은 rc 보다 풍부한 표현식을 갖는 파드 셀렉터를 소유하고 있다.
 
  • rc의 레이블 셀렉터: 특정 레이블이 있는 파드만 매칭 가능
  • 레플리카셋의 셀렉터: 특정 레이블이 없는 파드, 레이블 값과 상관없이 키를 갖는 파드 매칭 가능
 
또한 rc는 레이블 키의 값이 단일만 가능하지만 레플리카 셋은 복수개가 가능하다. 예를 들어 env=prod와 env=dev 레이블이 있다고 했을 때 rc는 둘 중 하나만 선택할 수 있지만 레플리카셋은 둘 다 선택이 가능하다.

- 레플리카셋 생성

레플리카셋을 생성하기 전에 rc로 파드를 생성할 때 사용했던 kubia-rc.yaml 로 rc 리소스를 생성한 다음 파드는 남기고 rc만 삭제하도록 하자. (rc 삭제시 --cascade 옵션 이용)
 
위의 작업을 완료 했으면 레플리카 셋을 정의하는 kubia-replicaset.yaml 파일을 만들어보자.
 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: kubia
spec:
  replicas: 3
  selector:
    matchLabels:
      app: kubia
  template:
    metadata:
      labels:
        app: kubia
    spec:
      containers:
      - name: kubia
        image: ocwokocw/kubia
        ports: 
        - containerPort: 8080
 
apiVersion 을 보면 rc 생성시에는 v1으로 했는데 레플리카 셋은 apps/v1 (API 그룹/API 버전) 으로 해야 한다. coreAPI에 그룹에 속하는 리소스들은 버전만 지정하면 된다.
 
rc와의 차이점은 셀렉터 부분인데 selector 속성 아래 바로 정의하는게 아니라 selector.matchLabels 아래에 정의한다.
 
 
 
레플리카셋 리소스를 생성했지만 추가적인 파드는 생성하지 않는다. 이전에 app=kubia로 생성된 파드가 남아있기 때문에 해당 파드를 자신이 관리하게 될 뿐이다.
 

- 레플리카셋의 셀렉터

레플리카셋은 rc의 레이블 셀렉터보다 더 강력한 matchExpression을 사용한다. kubia-replicaset-matchExpression.yaml 파일을 만들어보자.
 
selector:
    matchExpressions:
    - key: app
      operator: In
      values:
      - kubia
 
yaml 정의 중 selector 부분만 표시하였다. matchExpressions에는 key, operator, values 값이 포함된다. operator 이름을 보면 짐작할 수 있겠지만 values에는 여러 값이 나열될 수 있다.
 
연산자의 종류에는 In, NotIn, Exists, DoesNotExists 가 존재하며 만약 여러 표현식을 사용할 경우 해당 표현식들을 모두 만족해야 한다.
 

- 데몬셋

rc나 레플리카 셋은 클러스터 내 어딘가에 지정된 수만큼 파드를 실행하며 특정 노드는 지정하지 않는다. 만약 모든 노드에 노드당 하나의 파드만 실행하고 싶다면 어떻게 할까? 초반에 쿠버네티스는 이런 인프라 세부사항을 신경쓰지 않게 해준다고 했는데 갑자기 왜 특수한 요구사항을 만족해야 할까?
 
만약 앱 개발자나 운영자는 이런 특수한 요구사항이 필요 없겠지만 인프라 관리자는 모든 노드에 log 수집기와 리소스 모니터와 같은 인프라 관련 파드를 실행하고 싶을 수 있다. kube-proxy 프로세스도 그 예중 하나이다.
 
만약 쿠버네티스 환경이 아니라면 노드 부팅시 초기 스크립트를 실행하거나 systemd 데몬을 실행해야 하것이다.

- 데몬셋을 이용한 모든 노드에서의 파드 실행

데몬셋으로 생성하는 파드는 타겟 노드가 지정되어 있고, 쿠버네티스 스케줄러를 건너 띄는것만 빼면 rc나 레플리카 셋과 유사하다. 데몬셋은 복제본 개념이 없는데 파드 셀렉터와 일치하는 파드 1개가 모든 노드에서 실행되는지만 확인하기 때문이다.
 
특정 노드 다운시에는 별다른 동작을 하지 않지만 새로운 노드가 추가되면 파드를 생성한다.

- 특정 노드 지정

특정 노드를 지정하려면 데몬셋 정의의 일부인 파드 템플릿에서 node-Selector 속성을 지정한다. 이런 기능은 SSD가 있는 모든 노드에 ssd-monitor 데몬을 실행하고 싶을 때 유용하게 사용할 수 있다. 클러스터 관리자는 대상이 되는 노드에 disk=ssd 레이블을 추가하고 해당 레이블이 태깅된 노드만 선택하는 노드 셀렉터를 적용하면 된다.
 
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ssd-monitor
spec:
  selector:
    matchLabels:
      app: ssd-monitor
  template:
    metadata:
      labels:
        app: ssd-monitor
    spec:
      nodeSelector:
        disk: ssd
      containers:
      - name: main
        image: luksa/ssd-monitor
 
"kubectl create -f" 명령어를 이용하여 데몬셋을 생성해주자. 
 
 
 
생성 후 데몬셋을 조회하면 의도한 대로 되지 않았음을 알 수 있다. 예상하고 있겠지만 노드에 레이블을 아직 태깅하지 않았기 때문이다. 나중에 노드에 레이블을 추가해도 데몬셋은 변경을 감지하고 해당 레이블이 태깅된 노드에 파드를 배포한다.
 
 
 
"kubectl label" 명령어를 통해 노드에 레이블을 추가해주도록 하자. minikube를 사용하지 않는 경우 파드를 배포 하고 싶은 노드에 레이블을 추가한다.
 
만약 해당 노드가 SSD에서 HDD로 장비를 변경했다면 레이블의 키 값도 변경해줘야 할것이다. 노드의 레이블을 변경했을 때 데몬셋이 어떻게 반응하는지 살펴보자.
 
 
 
데몬셋이 변경을 감지하고 반응함을 알 수 있다.
 
 

'Framework and Tool > Kubernetes' 카테고리의 다른 글

Kubernetes - Service intro  (0) 2022.10.21
Kubernetes - job and cron job  (0) 2022.10.21
Kubernetes - Replication controller  (0) 2022.10.11
Kubernetes - Liveness probe  (0) 2022.10.10
Kubernetes - Namespace  (0) 2022.10.09

댓글