모든 노드에 에이전트를 심어야 하는 순간

클러스터 규모가 커지면서 갑자기 데이터 파이프라인의 로그가 비어있는 현상을 겪어본 적이 있나요? 새로 추가된 노드에는 로그 수집 에이전트가 설치되지 않아서, 특정 구간의 데이터가 유실되는 상황은 데이터 엔지니어에게 정말 아찔한 경험이에요. 노드가 10개일 때는 수동으로 확인이라도 할 수 있지만, 노드가 100개, 1000개로 늘어나는 환경에서는 불가능에 가까워요.
대부분의 엔지니어는 처음에는 디플로이먼트(Deployment)로 해결하려고 시도해요. 하지만 디플로이먼트는 단순히 지정된 개수의 파드를 띄우는 데 집중할 뿐, 모든 노드에 하나씩 파드를 배치해야 하는 요구사항은 충족하지 못해요. 노드가 새로 추가될 때마다 매번 명령어를 입력하거나 자동화 스크립트를 복잡하게 짤 필요 없이, 쿠버네티스가 알아서 모든 노드에 에이전트를 심어주길 바라는 마음이 드는 건 당연해요.
이런 고민을 해결해 주는 것이 바로 데몬셋 실전 예제를 통해 익힐 수 있는 데몬셋(DaemonSet) 기능이에요. 데몬셋을 사용하면 클러스터 내의 모든, 혹은 특정 조건에 맞는 노드마다 파드를 자동으로 배포하고 관리할 수 있어요. 노드가 늘어나면 파드도 같이 늘어나고, 노드가 삭제되면 파드도 자동으로 정리되죠.
이번 글에서는 데이터 엔지니어가 가장 흔하게 마주하는 로그 수집 시나리오를 바탕으로 실무적인 흐름을 따라가 보려고 해요. 단순히 코드를 복사하는 것을 넘어, 왜 이렇게 설정해야 하는지 그 이유를 함께 짚어볼게요.
- 로그 수집을 위한 데몬셋 매니페스트 작성법
- 클러스터 배포 및 노드별 자동 할당 확인
- 실무에서 빈번한 트러블슈팅과 해결 방법
- 리소스 제한을 통한 클러스터 안정성 확보
실습 전 반드시 확인해야 할 기본 사항
데몬셋을 본격적으로 다루기 전에 현재 내가 가진 환경이 실습에 적합한지 먼저 점검해야 해요. 준비 없이 명령어를 입력했다가는 클러스터 전체 리소스가 고갈되거나, 예상치 못한 노드 설정 때문에 파드가 실행되지 않아 당황할 수 있어요.
가장 먼저 확인해야 할 것은 쿠버네티스 클러스터 접근 권한이에요. `kubectl` 명령어를 통해 클러스터의 노드 리스트를 조회할 수 있어야 하고, 파드를 생성할 수 있는 권한이 필요해요. 또한, 실습에 사용할 컨테이너 이미지가 사전에 준비되어 있거나 공용 레지스트리(Docker Hub 등)에서 바로 가져올 수 있는 상태여야 해요.
특히 데이터 엔지니어라면 데몬셋과 다른 컨트롤러의 차이를 명확히 알고 있어야 해요. 어떤 상황에서 데몬셋을 선택해야 할지 판단하는 기준을 아래 표로 정리해 두었으니, 실습 전에 한 번 더 눈에 익혀두세요.
| 컨트롤러 유형 | 주요 목적 | 노드 배치 방식 | 실무 활용 사례 |
|---|---|---|---|
| 디플로이먼트 | 애플리케이션 실행 | 설정된 개수만큼 분산 배치 | 웹 서버, API 서버 |
| 데몬셋 | 인프라/에이전트 배포 | 모든(또는 특정) 노드당 1개 | 로그 수집, 모니터링, 네트워크 |
| 스테이트풀셋 | 상태 유지 애플리케이션 | 고유 ID와 순차적 생성 | 데이터베이스, 메시지 큐 |
데몬셋은 노드의 인프라 수준에서 동작하는 경우가 많기 때문에, 노드의 테인트(Taint) 설정도 반드시 고려해야 해요. 만약 특정 노드가 마스터 노드라서 일반 파드가 뜨지 못하도록 설정되어 있다면, 데몬셋 파드도 그 규칙을 따라야 하거든요. 이 규칙을 무시하면 데몬셋이 노드에 배치되지 않는 문제가 발생해요.
데몬셋을 사용할 때는 클러스터의 전체 리소스(CPU/Memory) 사용량이 갑자기 늘어날 수 있어요. 모든 노드에 파드가 하나씩 뜨기 때문에, 노드 개수가 많을수록 전체 클러스터에 가해지는 부담이 커진다는 점을 기억해 주세요.
데몬셋 배포 및 검증 실습 단계
이제 본격적으로 로그 수집 에이전트를 모든 노드에 배포하는 과정을 진행해 볼게요. 이번 실습에서는 가상의 로그 수집기 이미지를 사용한다고 가정하고, 실제 운영 환경에서 사용하는 것과 유사한 매니페스트를 작성해 볼 거예요.
STEP 1. 데몬셋 매니페스트(YAML) 작성하기
먼저 `daemonset-log-collector.yaml` 파일을 생성해야 해요. 단순히 이미지 이름만 넣는 게 아니라, 실제 데이터 엔지니어가 관리해야 할 리소스 제한과 노드 선택 조건을 포함하는 것이 핵심이에요.
아래 코드를 참고해서 파일을 작성해 보세요. 각 설정값이 어떤 의미를 갖는지 주석과 함께 상세히 설명해 드릴게요.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-collector
namespace: kube-system
spec:
selector:
matchLabels:
app: log-agent
template:
metadata:
labels:
app: log-agent
spec:
# 모든 노드에 띄우고 싶지만, 특정 테인트를 가진 노드는 피하고 싶을 때 사용해요
tolerations:
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: agent
image: fluentbit/fluent-bit:latest
resources:
limits:
cpu: "200m"
memory: "256Mi"
requests:
cpu: "100m"
memory: "128Mi"
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
hostPath:
path: /var/log
여기서 가장 눈여겨봐야 할 부분은 tolerations 부분이에요. 보통 마스터 노드(Control Plane)에는 일반 파드가 배치되지 않도록 설정되어 있는데, 로그 수집기는 마스터 노드의 로그도 수집해야 할 때가 많죠. 이때 이 설정을 넣어줘야 마스터 노드에도 파드가 성공적으로 안착할 수 있어요.
또한, resources 항목은 절대 빼놓아서는 안 돼요. 데몬셋은 모든 노드에서 실행되므로, 만약 리소스 제한이 없다면 모든 노드의 CPU와 메모리를 순식간에 점유해 버려 본래 운영 중인 애플리케이션을 죽게 만들 수 있어요.
STEP 2. 클러스터 배포 및 상태 확인
매니페스트 작성을 마쳤다면 이제 클러스터에 명령을 내릴 차례예요. 터미널에서 아래 명령어를 입력하여 데몬셋을 생성해 주세요.
kubectl apply -f daemonset-log-collector.yaml
배포 명령을 내린 직후에는 바로 성공했다고 믿지 마세요. 데몬셋이 각 노드에 파드를 하나씩 할당하고 컨테이너를 띄우는 데 시간이 걸리기 때문이에요. 아래 명령어를 통해 파드들이 Running 상태로 변하는지 지켜봐야 해요.
kubectl get pods -n kube-system -l app=log-agent -o wide
이 명령어를 입력했을 때 나오는 출력 결과의 NODE 컬럼을 유심히 보세요. 클러스터에 있는 각 노드의 이름이 하나씩 다 등장하고 있다면, 데몬셋이 제 역할을 수행하며 노드별로 파드를 잘 배치한 거예요. 만약 특정 노드 이름이 보이지 않는다면, 그 노드는 데몬셋의 배치 조건에서 제외되었거나 다른 오류가 발생한 상태예요.
STEP 3. 노드별 동작 검증과 로그 확인
파드가 떠 있다고 해서 안심하기엔 일러요. 로그 수집기가 실제로 노드의 로그 파일을 읽고 있는지, 데이터를 전송하는 데 오류는 없는지 확인해야 하죠. 각 파드에 직접 들어가서 로그를 확인하는 과정이 필요해요.
먼저 특정 노드에서 실행 중인 파드의 이름을 알아낸 뒤, 아래 명령어로 로그를 확인해 보세요.
kubectl logs [파드이름] -n kube-system
로그에서 Successfully sent data 또는 Connected to endpoint와 같은 메시지가 보인다면 성공이에요. 만약 Permission denied라는 메시지가 보인다면, 이는 아까 매니페스트에서 설정한 hostPath 권한 문제일 가능성이 커요. 쿠버네티스 노드의 실제 디렉토리를 파드가 읽을 수 있도록 권한 설정이 되어 있는지 다시 한번 체크해 봐야 해요.
STEP 4. 리소스 사용량 모니터링
마지막으로, 데몬셋이 노드의 자원을 얼마나 갉아먹고 있는지 검증해야 해요. 데이터 엔지니어링 파이프라인은 안정성이 생명이니까요. `kubectl top` 명령어를 사용해 보세요.
kubectl top pod -n kube-system -l app=log-agent
여기서 출력되는 CPU와 Memory 사용량이 우리가 매니페스트에 설정한 limits 값을 넘지 않는지 확인하세요. 만약 지속적으로 limit 근처까지 올라간다면, 에이전트의 설정이 너무 과하거나 로그 데이터 양이 너무 많다는 뜻이에요. 이 경우 리소스를 증설하거나 로그 필터링 규칙을 더 촘촘하게 만들어야 해요.
실제 운영 환경에서는 `hostPath`를 사용할 때 보안 취약점이 생길 수 있어요. 노드의 루트 파일 시스템에 직접 접근하는 것이므로, 반드시 필요한 디렉토리만 최소한의 권한으로 마운트해야 해요.
자주 하는 실수와 해결법
데몬셋을 운영하다 보면 예상치 못한 벽에 부딪히기 마련이에요. 실무에서 가장 자주 발생하는 문제 5가지를 정리해 두었으니, 비슷한 상황이 생기면 바로 적용해 보세요.
❌ 특정 노드에 파드가 생성되지 않아요
왜 발생하는가: 해당 노드에 설정된 Taint(테인트) 때문일 확률이 매우 높아요. 노드가 특정 용도로 제한되어 있으면 데몬셋도 그 제한을 허용(Toleration)받아야 해요.
✅ 해결법: 데몬셋 매니페스트의 `tolerations` 섹션에 해당 노드의 Taint 키를 추가해 주세요.
❌ 모든 노드에 파드가 뜨는데 리소스를 너무 많이 써요
왜 발생하는가: `resources.limits`를 설정하지 않았거나 너무 높게 잡았기 때문이에요.
✅ 해결법: 각 노드의 가용 자원을 계산하여 `limits` 값을 엄격하게 제한하고, 로그 수집 주기를 조절하세요.
❌ 파드가 계속 `CrashLoopBackOff` 상태예요
왜 발생하는가: 컨테이너가 실행되자마자 종료되는 현상으로, 주로 설정 파일 오류나 권한 문제예요.
✅ 해결법: `kubectl logs`로 에러 메시지를 확인하고, 특히 마운트하려는 호스트 경로의 권한을 체크하세요.
❌ 노드가 새로 추가되었는데 파드가 안 떠요
왜 발생하는가: 클라우드 환경이나 특정 오토스케일링 환경에서 노드 프로비저닝 속도가 파드 스케줄링보다 늦을 때 발생할 수 있어요.
✅ 해결법: 시간이 지나도 안 뜬다면 `kubectl describe daemonset` 명령어로 스케줄링 이벤트를 확인해 보세요.
❌ 이미지를 가져오지 못해요 (ImagePullBackOff)
왜 발생하는가: 이미지 이름이 틀렸거나, 프라이빗 레지스트리에 접근할 수 있는 인증 정보가 없기 때문이에요.
✅ 해결법: `imagePullSecrets` 설정을 확인하거나 이미지 태그가 정확한지 검토하세요.
자주 묻는 질문
Q. 데몬셋을 사용하면 노드가 늘어날 때마다 자동으로 파드가 생기나요?
네, 맞아요. 데몬셋의 핵심 기능이에요. 클러스터에 새로운 노드가 추가되어 ‘Ready’ 상태가 되면, 쿠버네티스 컨트롤러가 이를 감지하고 즉시 해당 노드에 정의된 데몬셋 파드를 하나 생성해요.
Q. 디플로이먼트와 데몬셋을 같이 쓸 수 있나요?
물론이에요. 보통 애플리케이션은 디플로이먼트로 띄우고, 그 애플리케이션들이 내뱉는 로그를 수집하기 위해 데몬셋을 사용하는 방식으로 함께 운영하는 것이 정석이에요.
Q. 특정 노드만 제외하고 데몬셋을 돌릴 수 있나요?
네, 가능해요. `nodeSelector`를 사용해서 특정 라벨이 있는 노드에만 배치하거나, 반대로 특정 노드에 있는 테인트를 무시하지 않도록 설정함으로써 특정 노드를 제외할 수 있어요.
Q. 데몬셋 파드를 삭제하면 어떻게 되나요?
데몬셋 컨트롤러가 관리하는 상태와 일치하지 않는다고 판단하여, 삭제된 즉시 다시 새로운 파드를 해당 노드에 생성하려고 시도할 거예요. 파드를 없애고 싶다면 파드를 지우는 게 아니라 데몬셋 자체를 삭제해야 해요.
Q. 데몬셋 파드도 스케줄링 우선순위를 조절할 수 있나요?
네, `PriorityClass`를 사용하여 설정할 수 있어요. 인프라 에이전트 같은 핵심 데몬셋은 높은 우선순위를 부여하여, 리소스가 부족할 때 다른 애플리케이션 파드가 먼저 퇴출되도록 만들 수 있어요.
실습 마무리 및 다음 단계
오늘 우리는 데몬셋을 활용해 모든 노드에 로그 수집기를 배포하는 실전 과정을 살펴보았어요. 단순히 명령어를 입력하는 것보다, 왜 이 설정이 필요한지를 이해하는 것이 실무에서는 훨씬 더 중요해요.
- 데몬셋은 모든 노드에 동일한 파드를 배포할 때 사용해요
- 마스터 노드 배포를 위해선 `tolerations` 설정이 필수예요
- 리소스 고갈 방지를 위해 `resources.limits`를 반드시 설정하세요
- `hostPath` 사용 시 노드 파일 시스템에 대한 보안과 권한을 주의하세요
- 배포 후에는 반드시 `kubectl top`으로 자원 사용량을 검증하세요
이제 여러분의 클러스터에 직접 적용해 볼 차례예요. 처음에는 테스트용 클러스터에서 아주 작은 리소스 제한을 두고 시작해 보는 걸 추천해요. 설정이 익숙해졌다면 실제 운영 환경의 로그 수집기나 모니터링 에이전트(Prometheus Node Exporter 등)로 확장해 보세요.
오늘 바로 실행해 보세요:
- 지금 바로 사용 중인 클러스터의 노드 테인트(Taint) 설정을 확인해 보세요.
- 로그 수집기 매니페스트에 리소스 제한(Limits)이 제대로 들어가 있는지 점검하세요.
- 실습 환경에서 직접 `kubectl apply`를 해보고 노드별로 파드가 뜨는지 확인해 보세요.
만약 실습 과정에서 설정이 꼬이거나 예상치 못한 에러 메시지가 나온다면, 주저하지 말고 댓글로 질문을 남겨 주세요. 함께 고민하고 해결 방법을 찾아볼게요!
관련해서 더 깊이 있는 내용이 궁금하다면 아래 글들도 함께 읽어보시면 큰 도움이 될 거예요.