본문 바로가기
1. K8s Core & Architecture/1.3. 파드(Pod)와 워크로드 아키텍처

DaemonSet 동작 원리: 모든 노드에 파드를 보장하는 스케줄링 메커니즘

by K8s Architect 2026. 4. 9.

DaemonSet 동작 원리: 모든 노드에 파드를 보장하는 스케줄링 메커니즘

쿠버네티스 환경에서 서비스를 배포할 때 가장 널리 사용되는 컨트롤러는 단연 Deployment입니다. Deployment는 사용자가 지정한 '파드의 개수(Replicas)'를 클러스터 내에서 어떻게든 유지하는 데 목적을 둡니다. 노드 A에 3개가 뜨든, 노드 B에 몰아서 뜨든 파드의 총량만 맞으면 그만입니다.

하지만 클러스터 인프라를 운영하다 보면 파드의 '개수'가 아니라 파드의 '위치(노드당 1개)'가 절대적으로 중요한 워크로드들이 존재합니다. 노드의 리소스 상태를 수집하는 모니터링 에이전트, 모든 노드의 로그를 중앙으로 쏴주는 로그 포워더, 노드 간의 통신을 책임지는 네트워크(CNI) 플러그인이 대표적입니다.

이처럼 클러스터의 모든 워커 노드(또는 특정 조건을 만족하는 노드)마다 정확히 하나의 파드가 실행되도록 끈질기게 보장하는 핵심 인프라 컨트롤러가 바로 DaemonSet(데몬셋)입니다. 본 가이드에서는 DaemonSet이 파드를 노드에 안착시키는 내부 스케줄링 메커니즘과 그 아키텍처적 특징을 심층적으로 해부합니다.


1. 개수(Replicas)가 아닌 노드(Node) 중심의 철학

DaemonSet 명세서(YAML)를 작성할 때 가장 눈에 띄는 특징은 replicas 필드가 아예 존재하지 않는다는 점입니다. DaemonSet 컨트롤러는 클러스터의 노드 목록을 지속적으로 감시(Watch)하며 파드의 배포를 결정합니다.

  1. 탐색: 현재 클러스터에 등록된, 그리고 DaemonSet의 타겟 조건에 맞는 노드의 목록을 확보합니다.
  2. 비교: 해당 노드 위에서 자신의 라벨(Label)을 가진 파드가 이미 실행 중인지 확인합니다.
  3. 실행: 파드가 없는 노드에는 새로운 파드를 생성하고, 파드가 두 개 이상 띄워진 비정상 노드가 있다면 한 개만 남기고 삭제하여 노드당 1:1 매칭 상태를 강제로 유지합니다.

2. DaemonSet 스케줄링 아키텍처의 진화 (kube-scheduler의 개입)

초창기 쿠버네티스(v1.11 이전)에서 DaemonSet은 표준 스케줄러인 kube-scheduler를 완전히 무시하고 동작했습니다. DaemonSet 컨트롤러가 직접 파드의 spec.nodeName 필드에 목적지 노드 이름을 박아 넣어 강제로 할당하는 방식을 사용했습니다.

하지만 이 방식은 표준 스케줄링 파이프라인을 우회했기 때문에, 파드 우선순위(Priority)나 선점(Preemption) 기능과 충돌하는 심각한 아키텍처 결함을 낳았습니다. 이를 해결하기 위해 현재의 쿠버네티스는 완전히 다른 방식을 사용합니다.

현재의 스케줄링 흐름:

  • DaemonSet 컨트롤러는 더 이상 파드를 직접 노드에 꽂아 넣지 않습니다. 대신, 파드를 생성할 때 NodeAffinity(노드 친화성) 규칙을 동적으로 생성하여 파드 명세에 몰래 주입합니다.
  • 이 파드는 일반 파드들과 똑같이 kube-scheduler의 평가 대기열에 들어갑니다.
  • kube-scheduler는 주입된 NodeAffinity 규칙을 보고, "아, 이 파드는 무조건 A 노드에만 가야 하는구나"라고 판단하여 정상적인 표준 스케줄링 파이프라인을 통해 노드에 할당합니다.

이러한 우아한 위임(Delegation) 구조 덕분에 DaemonSet 파드 역시 쿠버네티스의 일관된 자원 할당 정책과 우선순위 규칙을 완벽하게 따를 수 있게 되었습니다.

3. 보이지 않는 마법: 자동 주입되는 Toleration(용인)

일반적인 애플리케이션 파드는 마스터 노드(Control Plane)나 리소스가 고갈되어 NotReady 상태에 빠진 노드에는 스케줄링될 수 없습니다. 이런 노드들에는 파드의 접근을 막는 Taint(얼룩)가 강력하게 쳐져 있기 때문입니다.

하지만 네트워크 플러그인(CNI)이나 인프라 로깅 파드는 노드 상태가 불안정하더라도 디버깅과 복구를 위해 반드시 그 노드에 띄워져야만 합니다. 이를 위해 DaemonSet 컨트롤러는 사용자가 명세서에 명시하지 않아도 다음과 같은 강력한 Toleration(용인) 속성들을 파드에 자동으로 추가합니다.

  • node.kubernetes.io/not-ready: 노드가 준비되지 않은 상태라도 무시하고 실행합니다.
  • node.kubernetes.io/unreachable: 노드와 컨트롤 플레인의 통신이 끊겼어도 파드를 유지합니다.
  • node.kubernetes.io/disk-pressure: 노드의 디스크가 꽉 찼다는 경고가 떠도 무시하고 배포합니다.
  • node.kubernetes.io/unschedulable: 노드에 Cordon 처리가 되어 스케줄링이 정지된 상태라도 강제로 뚫고 들어갑니다.

이러한 자동 주입 메커니즘 덕분에 DaemonSet은 노드의 상태를 가리지 않고 인프라의 가장 깊숙한 곳까지 파고들어 생존할 수 있는 강력한 권한을 부여받습니다.

4. 동적 노드 확장(Auto-scaling)에 대한 즉각적인 반응

클라우드 환경에서 Cluster Autoscaler에 의해 트래픽 피크 타임에 워커 노드가 10대에서 20대로 동적 확장(Scale-out)되는 상황을 가정해 보겠습니다.

새로운 노드 인스턴스가 부팅되고 Kubelet이 API 서버에 자신을 등록하여 노드 객체가 생성되는 그 즉시, DaemonSet 컨트롤러의 감시망에 새로운 대상이 포착됩니다. 컨트롤러는 새로 추가된 10대의 노드에도 즉각적으로 CNI, Kube-proxy, 로깅 에이전트 파드들을 스케줄링하여 노드가 클러스터의 일원으로 정상 작동할 수 있는 기초 인프라 환경을 순식간에 세팅합니다.

반대로 노드가 축소(Scale-in)되어 삭제될 때도, DaemonSet 컨트롤러는 해당 노드에 있던 파드들을 미련 없이 삭제 테이블에 올려 가비지 컬렉션을 수행합니다.

5. 모든 노드가 아니다: 특정 노드 타겟팅 전략

'모든 노드에 배포'가 기본 원칙이지만, 특정 노드에만 데몬셋을 띄워야 하는 고급 아키텍처 환경도 많습니다. 예를 들어, 머신러닝 연산을 위해 GPU가 탑재된 노드에만 NVIDIA Device Plugin 데몬셋을 띄우거나, 외부 트래픽을 처리하는 Ingress 전용 엣지(Edge) 노드에만 프록시 데몬셋을 띄우는 경우입니다.

이때는 DaemonSet 명세서의 nodeSelector 또는 affinity.nodeAffinity 필드를 활용합니다.

  • 노드에 hardware-type=gpu라는 라벨을 붙여두고, DaemonSet에서 이 라벨을 가진 노드만 선택하도록 지정합니다.
  • DaemonSet 컨트롤러는 클러스터의 전체 노드 중 이 라벨 조건을 만족하는 노드의 부분 집합(Subset)을 계산한 뒤, 오직 그 노드 그룹 내에서만 1:1 파드 매칭 규칙을 강제합니다.

6. 무중단 인프라 업데이트: DaemonSet의 롤링 업데이트

DaemonSet으로 배포된 인프라 파드(예: Calico 네트워크 에이전트)의 이미지를 버전 업그레이드해야 할 때, 모든 노드의 파드를 동시에 죽이고 새로 띄우면 클러스터 전체의 네트워크가 마비되는 대참사가 발생합니다.

이를 방지하기 위해 DaemonSet 역시 RollingUpdate(롤링 업데이트) 전략을 기본적으로 지원합니다.

  • maxUnavailable: 한 번에 몇 개의 노드에서 업데이트를 진행할지 제어하는 핵심 파라미터입니다.
  • 이 값을 1로 설정하면, 전체 노드 중 단 1대의 노드에서만 기존 파드를 삭제하고 새로운 버전의 파드를 띄웁니다. 새 파드가 Ready 상태가 된 것을 완벽히 확인한 후에야 다음 노드의 파드를 업데이트합니다.
  • 이를 통해 클러스터 관리자는 수백 대의 워커 노드 환경에서도 인프라 로깅이나 네트워크 통신의 공백(Downtime) 없이 매우 안전하고 점진적으로 글로벌 시스템 패치를 수행할 수 있습니다.

결론적으로 DaemonSet은 애플리케이션 서비스를 구동하기 위해 존재하는 것이 아니라, 쿠버네티스 클러스터라는 거대한 '운영체제' 자체가 숨 쉬고 동작할 수 있도록 각 노드라는 장기에 혈관(네트워크)과 신경망(모니터링)을 깔아주는 핵심 시스템 컨트롤러입니다. DaemonSet의 스케줄링 원리와 Toleration 메커니즘을 명확히 통제할 때, 비로소 빈틈없고 견고한 클라우드 네이티브 인프라를 완성할 수 있습니다.