[IT-정보] 데몬셋 운영 사례 분석: 실무 적용기와 개선 포인트 – 클러스터 운영 효율을 높이는 실제 경험담

클러스터가 커질수록 반복되는 로그와 모니터링의 늪

새로운 워커 노드를 클러스터에 추가한 직후, 모니터링 대시보드에 데이터가 나타나지 않아 당황했던 적이 있으신가요? 분명히 에이전트를 배포했는데, 정작 새로 들어온 노드에서는 아무런 소식이 없는 상황 말이에요. 이런 문제는 클러스터의 규모가 커질수록 개발자와 운영자 모두를 괴롭히는 흔한 골칫거리예요.

처음에는 단순히 Deployment를 사용해서 에이전트를 띄우면 해결될 줄 알았어요. 하지만 노드 숫자가 늘어날 때마다 스케줄링을 신경 써야 하고, 특정 노드에는 에이전트가 너무 많이 몰리거나 아예 배치되지 않는 불안정한 모습을 보였죠. 시스템 전체의 가시성을 확보하기 위해 모든 노드에 반드시 존재해야 하는 로깅 엔진이나 네트워크 플러그인을 관리하는 일은 생각보다 훨씬 까다로웠어요.

이 글에서는 실제 운영 환경에서 데몬셋(DaemonSet)을 어떻게 도입했는지, 그리고 그 과정에서 어떤 시행착오를 겪으며 시스템을 안정화했는지에 대한 생생한 이야기를 나누려고 해요. 단순히 이론적인 정의를 나열하는 것이 아니라, 실무에서 마주하는 구체적인 설정값과 트러블슈팅 경험을 중심으로 구성했어요.

이 글을 끝까지 읽고 나면 다음과 같은 내용을 확실히 얻어갈 수 있어요.

  • 실무에서 데몬셋을 도입해야 하는 결정적인 순간들
  • Deployment나 StatefulSet과 비교했을 때 데몬셋만의 확실한 강점
  • 로깅 및 모니터링 에이전트 배포 시 반드시 설정해야 하는 핵심 옵션
  • 운영 중 발생할 수 있는 리소스 경합과 스케줄링 오류 해결법

준비가 되셨다면, 이제 클러스터의 모든 노드를 빈틈없이 관리하는 비결을 함께 살펴볼까요?

데몬셋 도입 전 반드시 체크해야 할 기초 지식

데몬셋을 무턱대고 적용하기 전에, 현재 운영 중인 워크로드의 성격과 클러스터의 구조를 먼저 이해해야 해요. 모든 파드를 모든 노드에 띄우는 것이 능사는 아니거든요. 리소스 낭비를 막으려면 각 컨트롤러의 특성을 정확히 파악하는 것이 우선이에요.

워크로드 유형에 따른 컨트롤러 선택 기준

쿠버네티스에는 여러 가지 컨트롤러가 존재하지만, 데몬셋은 그 목적이 매우 명확해요. 노드 단위의 작업이 필요할 때 사용하죠. 아래 표를 통해 현재 상황에 어떤 컨트롤러가 가장 적합한지 판단해 보세요.

컨트롤러 유형핵심 동작 방식적합한 서비스 사례
데몬셋(DaemonSet)모든(또는 선택된) 노드에 파드 1개씩 배치로깅 에이전트, 모니터링, 네트워크 플러그인
디플로이먼트(Deployment)설정한 복제본 수만큼 노드에 분산 배치웹 서버, API 서버 등 일반적인 애플리케이션
스테이트풀셋(StatefulSet)고유한 식별자와 순차적인 배포 보장데이터베이스, 메시지 큐 등 상태 유지가 필요한 앱

도입 전 검토해야 할 3가지 핵심 질문

설계 단계에서 스스로에게 다음 질문을 던져보세요. 이 질문들에 명확히 답할 수 없다면 데몬셋 도입을 재고해야 할 수도 있어요.

첫째, “이 파드가 모든 노드에 반드시 있어야 하는가?”를 고민해야 해요. 특정 역할(예: GPU 연산)을 수행하는 노드에만 필요하다면, 데몬셋 전체를 돌리기보다 NodeSelectorAffinity를 사용하여 범위를 좁혀야 해요.

둘째, “노드 리소스 점유율을 감당할 수 있는가?”예요. 데몬셋은 노드가 늘어날수록 파드 수도 정비례해서 늘어나요. 만약 에이전트 하나가 사용하는 메모리가 크다면, 클러스터 전체의 비용 부담이 급격히 커질 수 있어요. 리소스 요청(Requests)과 제한(Limits) 설정을 매우 보수적으로 잡아야 하는 이유예요.

셋째, “Taint와 Toleration 관계를 파악했는가?”예요. 마스터 노드나 특정 용도로 격리된 노드에는 Taint가 걸려 있어 일반적인 파드가 스케줄링되지 않아요. 데몬셋이 해당 노드에서도 실행되어야 한다면, 적절한 Toleration 설정을 미리 준비해야 해요.

💡 알아두기
데몬셋은 노드 추가/제거 이벤트에 매우 민감하게 반응해요. 노드가 생기자마자 파드를 띄우려고 시도하므로, 초기 부팅 시 리소스 경합이 발생하지 않도록 주의해야 해요.

데몬셋 실무 적용: 로깅부터 모니터링까지

이제 실제 운영 환경에서 데몬셋을 어떻게 구성하고 적용했는지 단계별 시나리오를 통해 살펴볼게요. 우리는 가장 흔하게 쓰이는 두 가지 사례인 로그 수집(Logging)시스템 모니터링(Monitoring)을 중심으로 설명할게요.

STEP 1. 로깅 에이전트(Fluent Bit) 배포하기

가장 먼저 해결해야 했던 문제는 분산된 노드에서 발생하는 로그를 중앙 저장소로 모으는 일이었어요. 우리는 가벼운 Fluent Bit를 데몬셋으로 구성했어요.

이 단계에서 가장 중요한 것은 노드의 로그 파일에 접근할 수 있는 권한을 주는 것이에요. 쿠버네티스 파드는 기본적으로 격리된 환경에서 실행되므로, 호스트 시스템의 `/var/log` 디렉토리에 접근하려면 hostPath 볼륨 마운트가 필수적이에요.

  • 설정 포인트: `volumeMounts`를 통해 `/var/log`를 파드의 특정 경로로 연결하세요.
  • 주의 사항: `hostPath`를 사용하면 파드가 노드에 강하게 결합되므로, 노드 장애 시 로그 데이터 유실 가능성을 염두에 두어야 해요.
  • 보안 고려: 로그를 읽기 위해 `privileged: true` 설정을 사용하는 경우가 많은데, 이는 보안 취약점이 될 수 있으므로 가능한 RBAC(역할 기반 액세스 제어)를 통해 최소 권한만 부여하세요.

실제로 적용했을 때, 노드가 50대인 환경에서 Fluent Bit 데몬셋을 배포하자 약 2분 이내에 모든 노드에서 로그 수집이 시작되는 것을 확인했어요. Deployment를 썼을 때처럼 스케줄링을 기다릴 필요가 없어 매우 효율적이었죠.

STEP 2. 노드 메트릭 수집을 위한 Node Exporter 구성

두 번째 단계는 각 노드의 CPU, 메모리, 디스크 사용량을 수집하는 Node Exporter를 배치하는 작업이었어요. 시스템 메트릭은 네트워크 인터페이스나 커널 통계까지 포함해야 하므로 설정이 조금 더 복잡해요.

이때는 hostNetwork: true 설정이 핵심이에요. 파드가 노드의 네트워크 네임스페이스를 직접 공유해야만, 노드 자체의 네트워크 트래픽과 인터페이스 정보를 정확하게 읽어올 수 있기 때문이에요. 만약 이 설정을 빠뜨리면, 파드 내부의 가상 IP 기준으로 메트릭이 잡혀 실제 노드의 상태를 반영하지 못하는 오류가 발생해요.

[실제 구성 시나리오: 메트릭 수집 흐름]

  1. 데몬셋이 새로운 노드 감지
  2. Node Exporter 파드가 해당 노드에 즉시 생성
  3. `hostNetwork`를 통해 노드의 네트워크 인터페이스 접근
  4. 수집된 메트릭을 Prometheus 서버로 전송

이 과정을 통해 우리는 클러스터 전체의 리소스 사용량을 초 단위로 관찰할 수 있게 되었어요. 특히 특정 노드에서 메모리 누수가 발생할 때, 데몬셋이 즉각적으로 해당 노드의 상태를 보고해주어 빠르게 대응할 수 있었답니다.

STEP 3. 특정 노드 그룹을 위한 타겟팅 설정

모든 노드에 에이전트를 띄우는 것이 항상 정답은 아니에요. 예를 들어, GPU 전용 노드에는 GPU 모니터링 에이전트만 띄우고, 일반 노드에는 띄우지 않아야 하죠. 이때 사용하는 것이 NodeSelectorAffinity예요.

우리는 노드에 `workload=gpu`라는 레이블을 붙여 관리했어요. 데몬셋 설정 파일의 `nodeSelector` 섹션에 이 값을 넣으면, 쿠버네티스 스케줄러는 해당 레이블이 있는 노드에만 에이전트를 배치해요. 불필요한 리소스 소모를 줄이는 아주 효과적인 방법이에요.

⚠️ 주의
NodeSelector를 잘못 설정하면, 새로운 노드가 추가되어도 에이전트가 배포되지 않아 관측 불가능한 ‘블라인드 스팟(Blind Spot)’이 생길 수 있어요. 레이블 관리를 엄격하게 해야 해요.

STEP 4. 리소스 경합 방지를 위한 최적화

데몬셋은 시스템 운영을 위한 ‘기반 서비스’이기 때문에, 애플리케이션 파드와 자원 싸움을 해서는 안 돼요. 만약 애플리케이션이 폭주하여 CPU를 다 써버렸는데, 데몬셋인 모니터링 에이전트까지 자원이 없어 죽어버린다면? 운영자는 클러스터 상황을 파악할 방법이 사라지는 최악의 상황에 직면하게 돼요.

이를 방지하기 위해 우리는 다음과 같은 규칙을 세웠어요.

  • Requests는 낮게, Limits는 확실하게: 에이전트가 평소에는 적은 자원을 쓰도록 유도하되, 갑작스러운 로그 폭증 시에도 최소한의 동작은 보장할 수 있도록 제한 범위를 설정해요.
  • PriorityClass 활용: 데몬셋 파드에 System-node-critical과 같은 높은 우선순위를 부여하여, 리소스가 부족할 때 애플리케이션 파드가 먼저 퇴거(Eviction)되도록 설계했어요.

이렇게 설정한 후에는 노드 부하가 극심한 상황에서도 모니터링 데이터가 끊기지 않고 안정적으로 들어오는 것을 확인할 수 있었어요.

자주 하는 실수와 해결법 및 FAQ

데몬셋을 운영하다 보면 이론과는 다른 예상치 못한 문제들이 발생하곤 해요. 실무에서 가장 자주 마주쳤던 사례들을 정리해 보았습니다.

자주 하는 실수와 해결법

실수: 특정 노드(예: 마스터 노드)에 데몬셋이 뜨지 않아요.
왜 발생하는가: 해당 노드가 Taint(용인되지 않는 설정)를 가지고 있어 일반 파드의 스케줄링을 거부하기 때문이에요.
해결법: 데몬셋 설정에 해당 Taint를 허용하는 tolerations 항목을 추가하세요.

실수: 에이전트가 노드마다 중복으로 실행되거나 하나도 안 떠요.
왜 발생하는가: NodeSelector 설정이 모호하거나, 노드의 레이블이 예상과 다르게 관리되고 있기 때문이에요.
해결법: `kubectl get nodes –show-labels` 명령어로 노드 레이블을 먼저 전수 조사하고, 데몬셋의 Selector와 일치하는지 확인하세요.

실수: 에이전트 때문에 노드 전체가 느려졌어요.
왜 발생하는가: 데몬셋의 리소스 Limit이 설정되지 않아, 로그가 폭증할 때 CPU/메모리를 무한정 점유했기 때문이에요.
해결법: 반드시 Resource Limits를 설정하여 에이전트가 가질 수 있는 최대 자원량을 제한하세요.

실수: 로그 파일이 너무 커져서 디스크 풀(Full)이 발생했어요.
왜 발생하는가: 데몬셋이 로그를 수집만 하고, 호스트의 로그 로테이션(Rotation) 정책을 고려하지 않았기 때문이에요.
해결법: 호스트 OS 수준에서 `logrotate` 설정을 점검하고, 데몬셋이 읽는 경로의 디스크 사용량을 주기적으로 모니터링하세요.

실수: 네트워크 플러그인이 업데이트된 후 통신이 안 돼요.
왜 발생하는가: CNI 데몬셋이 업데이트되면서 기존 파드들의 네트워크 인터페이스와 충돌이 발생했을 수 있어요.
해결법: 데몬셋 업데이트 시에는 반드시 스테이징 환경에서 먼저 테스트하고, 롤링 업데이트 전략을 신중하게 선택하세요.

자주 묻는 질문

Q. 데몬셋을 사용할 때 반드시 모든 노드에 다 깔아야 하나요?

아니요, 그렇지 않아요. 특정 역할을 수행하는 노드 그룹(예: GPU 노드, 스토리지 노드)에만 실행되도록 NodeSelector나 Affinity를 사용하여 대상을 제한할 수 있어요. 이는 리소스 효율성을 높이는 데 매우 중요해요.

Q. 데몬셋 파드가 삭제되면 어떻게 되나요?

데몬셋 컨트롤러는 상태를 지속적으로 감시하고 있어요. 만약 사용자가 실수로 파드를 삭제하더라도, 컨트롤러는 즉시 새로운 파드를 해당 노드에 다시 생성하여 항상 노드당 하나 이상의 파드가 유지되도록 보장해요.

Q. 노드 수가 급격히 늘어날 때 데몬셋 배포 속도는 어떤가요?
데몬셋은 노드의 생명주기와 밀접하게 연결되어 있어요. 새로운 노드가 `Ready` 상태가 되면 스케줄러는 즉시 데몬셋 파드를 할당하려고 시도하므로, Deployment보다 훨씬 빠르게 인프라 구성에 합류할 수 있어요.

Q. 데몬셋에도 롤링 업데이트가 가능한가요?

네, 가능해요. `updateStrategy`를 설정할 수 있는데, 보통 `RollingUpdate`를 사용해요. 한 번에 모든 노드의 에이전트를 교체하면 서비스 중단 위험이 있으므로, 한 번에 몇 개의 노드씩 교체할지 `maxUnavailable` 값을 조절하는 것이 안전해요.

댓글 남기기