쿠버네티스 패턴 - 9장 데몬 서비스

오정재·2021년 5월 2일
4

쿠버네티스 패턴

목록 보기
10/12
post-thumbnail

👉 데몬 서비스

데몬 서비스 패턴 은 노드에 특화된 파드를 실행하는 데 사용됩니다.

이에 따라서 클러스터 관리자는 노드 모니터링과 같이 노드에 대한 상태를 확인할 수 있으며
어플리케이션 개발자는 로그 수집과 같이 노드에 배치 된 모든 파드의 로그를 수집할 수 있습니다.

🍏 문제점

소프트웨어에서 Daemon 이라는 개념은 백그라운드에서 돌면서 여러 작업을 하는 프로그램을 말합니다.
쿠버네티스에서는 로그를 수집하거나 노드에 대한 모니터링을 수집해야할 때 Daemon 을 사용하면 좋을 것 입니다.

이를 위해서 두 가지의 대안이 있습니다.

1) Init Scripts

  • 단순히 각 노드에 Daemon 을 시작하는 스크립트를 실행
  • 예시로 init, upstartd, systemd 를 사용

2) Static Pods

  • kubelet 이 감시하는 특정 디렉토리에 파일을 작성하여 파드를 실행
  • kubelet 또는 다른 kubernetes API 로 관리할 수 없음
  • 클러스터의 bootstraping 에 유용

하지만 이 두 가지 대안에는 몇 가지 문제점이 있습니다.

  • 어플리케이션과 동일한 방법으로 데몬을 모니터링하고 로그 관리를 할 수 없음
  • kubectl 이나 Pod Template 로 관리할 수 없음

따라서 Daemon 을 관리하기 위한 더 나은 방법이 필요해졌습니다.

🍏 해결책

쿠버네티스는 이를 해결하기 위해서 Daemon Set 을 지원합니다.
Daemon Set 은 원하는 노드에 정의한 파드를 실행하도록 합니다.

이러한 특징은 노드가 클러스터에 추가되면 파드도 추가되며
노드가 클러스터에서 제거되면 파드도 함께 제거됩니다.

Daemon Set 은 다음과 같은 용도로 많이 사용합니다.

  • 모든 노드에서 클러스터 스토리지 데몬 실행
  • 모든 노드에서 로그 수집 데몬 실행
  • 모든 노드에서 노드 모니터링 데몬 실행

따라서 이번 글에서는 Daemon Set 에 대해서 자세히 알아보도록 하겠습니다.

Daemon Set 사용

Daemon Set 은 다른 쿠버네티스 Resource 와 거의 동일하게 생성할 수 있습니다.

따라서 다른 쿠버네티스 설정과 마찬가지로 apiVersion, kind, metadata 필드가 필요하며
이를 Yaml 파일로 정의한 후 kubectl apply 로 사용하면 됩니다.

👌 참고사항으로 Daemon SetRestartPolicyAlways 를 가져야 하며 명시하지 않으면 Always 가 기본값으로 지정됩니다.

다음은 fluentd-elasticsearch 도커 이미지를 실행하는 Daemon Set yaml 예시입니다.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # this toleration is to have the daemonset runnable on master nodes
      # remove it if your masters can't run pods
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        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

Daemon Set Scheduling

일반적으로 파드는 kubernetes Scheduler 에 의해서 스케줄됩니다.
하지만 Daemon SetDaemon Set Controller 에 의해서 스케줄됩니다.

따라서 다음과 같은 내용을 주의해야합니다.

1) Pod 동작의 불일치

일반적으로 Pod 가 생성될 때 Pending 상태에서 생성이 됩니다.
하지만 Daemon Set PodPending 상태에서 생성되지 않기 때문에 주의해야합니다.

2) Pod Preemption

Daemon Set의 Pod 의 선점Kubernetes Controller 에서 처리합니다.
따라서 선점이 활성화되어도 Daemon Set Controller 는 Pod 의 우선순위와 선점을 고려하지 않고 스케줄 합니다.

이에 따라서 쿠버네티스는 Daemon Set PodKubernetes Scheduler 가 스케줄 하도록 할 수 있습니다.
다음은 Kubernetes Scheduler 가 스케줄 하게 만들기 위한 yaml 예시입니다.

nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchFields:
      - key: metadata.name
        operator: In
        values:
        - target-host-name

해당 yaml에서 처럼 .spec.nodeName 대신에 NodeAffinity 를 추가합니다.
만약 Daemon Set PodNodeAffinity 가 이미 존재한다면 대체됩니다.

3) Taints & Tolerations

Daemon Set PodTaintsTolerations 를 사용할 수 있으며
다음과 같이 관련 기능에 따라 자동적으로 Daemon Set PodToleration 을 추가합니다.

Toleration KeyEffectVersionDescription
node.kubernetes.io/not-readyNoExecute1.13+네트워크 파티션과 같은 노드 문제가 발생해도 데몬셋 파드는 축출되지 않는다.
node.kubernetes.io/unreachableNoExecute1.13+네트워크 파티션과 같은 노드 문제가 발생해도 데몬셋 파드는 축출되지 않는다.
node.kubernetes.io/disk-pressureNoSchedule1.8+데몬셋 파드는 기본 스케줄러에서 디스크-압박(disk-pressure) 속성을 허용한다.
node.kubernetes.io/memory-pressureNoSchedule1.8+데몬셋 파드는 기본 스케줄러에서 메모리-압박(memory-pressure) 속성을 허용한다.
node.kubernetes.io/unschedulableNoSchedule1.12+데몬셋 파드는 기본 스케줄러의 스케줄할 수 없는(unschedulable) 속성을 극복한다.
node.kubernetes.io/network-unavailableNoSchedule1.12+호스트 네트워크를 사용하는 데몬셋 파드는 기본 스케줄러에 의해 이용할 수 없는 네트워크(network-unavailable) 속성을 극복한다.

Daemon Set Pod 의 통신

Daemon Set Pod 와 통신할 수 있는 몇 가지 방법을 설명하도록 하겠습니다.

1) Service

  • 파드 셀렉터가 동일한 Service 를 생성하여 통신

2) DNS

  • 동일한 파드 셀렉터로 Headless Service 생성
  • Endpoint 를 사용해서 Daemon Set 을 찾거나 DNS 에서 A recode 를 조회

3) hostPort를 사용한 NodeIP

  • Daemon Set PodhostPort 를 지정하여 NodeIP 로 통신
  • hostIp, hostPort, protocol 의 결합은 유일해야 하기 때문에 파드의 위치가 제한적

4) Push

  • Daemon Set Pod 의 데이터를 Pod 외부의 위치나 서비스로 전달 할 수 있음
  • ConsumerDaemon Set Pod 에 접근하지 않고 다른 서비스를 통해서 확인
  • 예시로 Fluentd 의 로그를 ElasticSearch 로 보내는 것이 있음

Daemon Set Update

Daemon Set 에는 두 가지 업데이트 전략 유형이 있습니다.
전략을 적용하기 위해 .spec.updateStrategy.typeOnDelete 또는 RollingUpdate 를 설정합니다.

다음은 두 가지 업데이트 전략에 대한 설명입니다.

1) OnDelete

OnDelete 전략은 Daemon Set Template 를 업데이트 한 후
이전 Daemon Set Pod 를 수동으로 삭제할 때만 새로운 Daemon Set Pod 가 생성되는 전략입니다.

2) RollingUpdate

RollingUpdate 전략은 기본 업데이트 전략으로 Daemon Set Template 를 업데이트 한 후
이전 Dameon Set Pod 는 삭제되며 새로운 Daemon Set Pod 가 자동생성되는 전략입니다.
또한 전체 업데이트 프로세스 동안 Daemon Set 의 최대 하나의 Pod 가 각 노드에서 실행되도록 합니다.

🍏 정리

이번 글을 통해서 쿠버네티스가 Daemon 을 관리하는 법에 대해서 알아보았습니다.

쿠버네티스 패턴 시리즈에서는 쿠버네티스 플랫폼 관리자보다 개발자를 위한 패턴을 주로 설명합니다.
Daemon Set 은 플랫폼 관리자와 개발자의 중간쯤에 있으며, 오히려 관리자의 툴박스 쪽에 더 가깝습니다.

하지만 Daemon Set 에 대해 설명한 이유는 어플리케이션 레벨에서 개발자에게도 적용이 가능하기 때문입니다.
따라서 Daemon Set 에 대한 내용을 반드시 알아야 하며 잘 사용할 수 있어야 합니다.

👉 Reference

profile
ohhong

0개의 댓글