[Kubernetes 시작하기] 11. 데몬셋

2023. 12. 29. 16:30Infrastructure/Kubernetes

반응형
  1. 데몬셋
    1. 데몬셋
    2. 데몬셋 스케쥴러
  2. 데몬셋 생성
    1. 모든 노드에 데몬셋 생성하기
    2. 특정 노드에만 데몬셋 생성
  3. 데몬셋 업데이트
  4. 데몬셋 삭제

파드 집합을 복제하는 이유는 크게 두가지 이유가 있습니다.

  1. 중복성을 위해
    • 중복성: 여러개의 복제본 설정으로, 장애 발생되더라도 그에 대한 대비가 가능하게 하는 성질
    • 관련 쿠버네티스 객체: 레플리카셋, 디플로이먼트
  2. 각 노드에 에이전트나 데몬을 실행하기 위해
    • 클러스터 내의 모든 노드에 단일 파드를 스케쥴링하기 위해
    • 관련 쿠버네티스 객체: 데몬셋

이번 포스팅에서는, 위에서 소개한 파드 집합 복제 이유의 2번째에 해당하는, 데몬 실행을 위한 데몬셋에 대해 알아볼 것입니다.


1. 데몬셋

1.1. 데몬셋

파드의 복사본이 쿠버네티스 클러스터 노드 집합에서 실행되게 합니다.
일반적으로 (클러스터 스토리지나 로그 수집기나 노드 모니터링 에이전트와 같이) 모든 노드에서 실행되어야하는 시스템 데몬을 배포하는데에 사용합니다.

데몬셋을 사용하면 클라우드 기반 클러스터 노드에 소프트웨어를 쉽게 설치할 수 있습니다.

클러스터 확장시, 특정 소프트웨어를 새로 추가한 노드에 설치하는 것도 데몬셋을 이용하여 설치하면 됩니다.


장시간 실행되는 서비스를 실행하는 파드를 생성하고, 클러스터의 원하는 상태와 현재(관찰된) 상태를 동일하게 만든다는 점에서 레플리카셋과 유사점이 있습니다.

사용목적에 따라 레플리카셋과 데몬셋 중 선택해야합니다.

  • 레플리카셋
    • 애플리케이션을 노드에서 완전히 분리할 때 사용
  • 데몬셋
    • 모든 노드(또는 특정 노드집합)에서 단일 파드 복사본이 실행되어야하는 경우에 사용
      • 데몬셋 설정에서 label을 설정하면, 특정 노드 집합에서만 데몬셋을 실행할 수 있습니다.

1.2. 데몬셋 스케쥴러

별도의 설정을 하지 않을 경우, 기본적으로 모든 노드에 파드의 복제본을 설치합니다.

데몬셋을 일부 노드에만 설치하고 싶다면 node selector을 설정하면 됩니다.
node selector는 설정한 라벨 목록으로 노드를 필터링하여 파드를 복제해줍니다.

조정 루프에 의해 관리되며, 측정된 정보를 바탕으로 데몬셋 컨트롤러는 일치하는 파드가 없는 각노드에 파드를 생성합니다.
이에 의해, 클러스터에 새로운 노드가 추가되었을 경우에도 데몬셋 컨트롤러가 해당 노드에 파드를 추가해줍니다.

조정 루프: 조정 루프는 지속적으로 파드의 상태를 관찰하고, 현재(관찰된) 상태가 원하는 상태와 일치할 수 있도록 동작합니다.


레플리카셋이 자신이 관리하는 파드를 소유하고 있었다면,(파드가 레플리카셋의 하위 리소스)
데몬셋의 경우, 데몬셋에 의해 관리되는 각 파드들이 데몬셋을 소유하고 있습니다. (파드가 데몬셋의 상위 리소스)


2. 데몬셋 생성

2.1. 모든 노드에 데몬셋 생성하기

별도의 필터링 없이, 모든 노드에 데몬셋 파드를 생성해봅니다.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  labels:
    app: fluentd
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluent/fluentd:v0.14.10
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

정의해둔 데몬셋 구성파일을 이용하여 데몬셋을 생성해봅니다.

kubectl apply -f fluentd.yml
daemonset.apps/fluentd created

데몬셋 목록 조회

kubectl get ds                                                          
NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
fluentd   3         3         3       3            3           <none>          64s

파드 목록 조회

데몬셋은 특정 조건에 맞는 노드에 설치되는 파드이기 때문에 파드 목록 조회를 이용하여 조회할 수 있습니다.
파드 전체 목록을 조회해보면 데몬셋이 조회되는 것을 확인할 수 있습니다.

kubectl get pods -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP           NODE           NOMINATED NODE   READINESS GATES
fluentd-dn4sc   1/1     Running   0          98s   10.244.5.2   kind-worker    <none>           <none>
fluentd-wwf8k   1/1     Running   0          98s   10.244.3.2   kind-worker3   <none>           <none>
fluentd-xh69t   1/1     Running   0          98s   10.244.4.2   kind-worker2   <none>           <none>
kuard-fk5dg     1/1     Running   0          5s    10.244.3.3   kind-worker3   <none>           <none>
kuard-w7qxr     1/1     Running   0          5s    10.244.5.3   kind-worker    <none>           <none>

라벨을 이용하여 app이 fluentd인 파드만 조회하면 아래와 같이 fluentd 파드만 조회할 수 있습니다.

kubectl get pods -o wide -l app=fluentd
NAME            READY   STATUS    RESTARTS   AGE     IP           NODE           NOMINATED NODE   READINESS GATES
fluentd-dn4sc   1/1     Running   0          2m12s   10.244.5.2   kind-worker    <none>           <none>
fluentd-wwf8k   1/1     Running   0          2m12s   10.244.3.2   kind-worker3   <none>           <none>
fluentd-xh69t   1/1     Running   0          2m12s   10.244.4.2   kind-worker2   <none>           <none>

fluentd 데몬셋에 대한 현재상태 조회

kubectl describe daemonset fluentd
Name:           fluentd
Selector:       app=fluentd
Node-Selector:  <none>
Labels:         app=fluentd
Annotations:    deprecated.daemonset.template.generation: 1
Desired Number of Nodes Scheduled: 3
Current Number of Nodes Scheduled: 3
Number of Nodes Scheduled with Up-to-date Pods: 3
Number of Nodes Scheduled with Available Pods: 3
Number of Nodes Misscheduled: 0
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=fluentd
  Containers:
   fluentd:
    Image:      fluent/fluentd:v0.14.10
    Port:       <none>
    Host Port:  <none>
    Limits:
      memory:  200Mi
    Requests:
      cpu:        100m
      memory:     200Mi
    Environment:  <none>
    Mounts:
      /var/lib/docker/containers from varlibdockercontainers (ro)
      /var/log from varlog (rw)
  Volumes:
   varlog:
    Type:          HostPath (bare host directory volume)
    Path:          /var/log
    HostPathType:
   varlibdockercontainers:
    Type:          HostPath (bare host directory volume)
    Path:          /var/lib/docker/containers
    HostPathType:
Events:
  Type    Reason            Age    From                  Message
  ----    ------            ----   ----                  -------
  Normal  SuccessfulCreate  2m28s  daemonset-controller  Created pod: fluentd-wwf8k
  Normal  SuccessfulCreate  2m28s  daemonset-controller  Created pod: fluentd-xh69t
  Normal  SuccessfulCreate  2m28s  daemonset-controller  Created pod: fluentd-dn4sc

데몬셋 삭제

kubectl delete -f fluentd.yml
daemonset.apps "fluentd" deleted

2.2. 특정 노드에만 데몬셋 생성

특정 노드에만 데몬셋을 실행하고 싶다면, 라벨을 활용하면 됩니다.
데몬셋을 실행하고자하는 노드에 라벨을 설정한 후, 특정 라벨이 있는 노드에게만 데몬셋이 생성되도록 제한할 수 있습니다.

기존에 생성했던 kind 클러스터 노드에는 아래와 같이 2개의 worker노드에 tier: backend 라벨이 설정되어있었습니다.

  • -l, --selector: 특정 라벨 필터링을 위한 옵션
kubectl get nodes -l tier=backend
NAME           STATUS   ROLES    AGE     VERSION
kind-worker    Ready    <none>   5m45s   v1.27.3
kind-worker2   Ready    <none>   5m45s   v1.27.3

이전에 생성했던 데몬셋을 삭제한 후, 필터링에 활용할 label을 nodeSelector에 설정해봅니다.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  labels:
    app: fluentd
    tier: backend
spec:
  selector:
    matchLabels:
      app: fluentd
      tier: backend
  template:
    metadata:
      labels:
        app: fluentd
        tier: backend
    spec:
      nodeSelector:
        tier: backend
      containers:
      - name: fluentd
        image: fluent/fluentd:v0.14.10
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

fluentd-2.yml


그리고, 위의 데몬셋 구성파일을 이용하여 데몬셋을 생성해봅니다.

kubectl apply -f fluentd.yml

그러면, 2개의 worker노드에만 fluentd 파드가 설치된 것을 확인할 수 있습니다.

kubectl get pods -o wide -l app=fluentd
NAME            READY   STATUS    RESTARTS   AGE   IP           NODE           NOMINATED NODE   READINESS GATES
fluentd-5nzhm   1/1     Running   0          20s   10.244.3.6   kind-worker    <none>           <none>
fluentd-sfgdz   1/1     Running   0          20s   10.244.4.5   kind-worker2   <none>           <none>

3. 데몬셋 업데이트

데몬셋은 전체 클러스터에 서비스를 배포하고자할 때 유용합니다.

쿠버네티스 1.6 버전 이전에는, 데몬셋을 업데이트하고자 할때, 데몬셋이 관리하는 각 파드들을 수동으로 삭제한 후, 수정한 데몬셋 구성파일을 이용하여 새로 파드를 생성하는 것이 유일한 방법이었습니다.

쿠버네티스 1.6 이후 버전부터는, 클러스터 내에서 레플리카셋 롤아웃 관리를 하는 디플로이먼트 객체와 동일한 기능이 생겼습니다.

롤링 업데이트 전략을 사용하면 데몬셋에 대한 롤아웃을 수행할 수 있습니다

데몬셋의 롤아웃 정책은 spec 하위에 정의합니다.

  • minReadySeconds
    • 롤링업데이트가 다음 파드의 업그레이드 전에 파드를 준비상태로 두는 시간
  • updateStrategy.rollingUpdate.maxUnavailable
    • 동시에 롤링업데이트할 수 있는 최대 파드 수
    • 속도는 느리겠지만, 안전한 서비스 배포를 위해서는 1로 설정하는 것이 좋습니다.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  labels:
    app: fluentd
    tier: backend
spec:
  selector:
    matchLabels:
      app: fluentd
      tier: backend
  minReadySeconds: 10
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: fluentd
        tier: backend
    spec:
      nodeSelector:
        tier: backend
      containers:
      - name: fluent
        image: fluent/fluentd:v0.14.10
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

fluentd-3.yml


이전에 생성했던 데몬셋은 롤아웃 정책이 적용되어있지 않기 때문에 제거후 진행해야합니다.
새로, 데몬셋을 실행 한후,

kubectl apply -f fluentd-3.yml
daemonset.apps/fluentd created

현재 설치되어있는 fluentd 버전을 확인해봅니다.

kubectl get pods -o jsonpath="{.items[*].spec.containers[*].image}" -l app=fluentd
fluent/fluentd:v0.14.10 fluent/fluentd:v0.14.10%  

fluentd 이미지를 fluent/fluentd:v0.14.10 -> fluent/fluentd:v0.14.14로 업데이트한 후, 새로 적용해봅니다.

kubectl apply -f fluentd-3.yml
daemonset.apps/fluentd configured

그리고, 데몬셋의 롤아웃 상태를 확인해봅니다.

Waiting for daemon set "fluentd" rollout to finish: 0 out of 2 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 0 out of 2 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 1 out of 2 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 1 out of 2 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 1 out of 2 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 1 out of 2 new pods have been updated...
Waiting for daemon set "fluentd" rollout to finish: 1 of 2 updated pods are available...
Waiting for daemon set "fluentd" rollout to finish: 1 of 2 updated pods are available...
daemon set "fluentd" successfully rolled out

다시 이미지 버전을 조회해보면 아래와 같이 버전이 업데이트 된 것을 확인할 수 있습니다.

kubectl get pods -o jsonpath="{.items[*].spec.containers[*].image}" -l app=fluentd
fluent/fluentd:v0.14.14 fluent/fluentd:v0.14.14%

4. 데몬셋 삭제

기본적으로, 데몬셋과 그 데몬셋이 관리하고 있던 파드를 함께 삭제하지만,
--cascade=false 설정을 하면, 파드는 그대로 남기고 데몬셋만 삭제됩니다.


4.1. 데몬셋 구성파일을 이용한 삭제

kubectl delete -f fluentd.yml
daemonset.apps "fluentd" deleted

4.2. 데몬셋 이름을 이용한 삭제

kubectl delete ds fluentd
daemonset.apps "fluentd" deleted
728x90
반응형