Vector로 K8s 로그 수집 설치하기: Agent/Aggregator Helm values와 VictoriaLogs 연동

Vector는 Helm 차트의 role 값(Agent=DaemonSet, Aggregator=StatefulSet)으로 워크로드가 결정되며, customConfig에 sources/transforms/sinks를 직접 정의합니다. Agent가 kubernetes_logs로 파드 로그를 수집해 type: vector sink로 Aggregator(6000)에 보내고, Aggregator가 elasticsearch sink로 VictoriaLogs에 적재합니다. 소규모는 Aggregator 없이 Agent가 VictoriaLogs로 직결할 수 있습니다. 이 글은 “OTel + VictoriaLogs 로그 스택” 시리즈의 Vector 트랙 2편(설치편) 으로, 1편(Vector 개념)에서 다룬 파이프라인 구조를 실제 Helm values로 구현합니다.

🧭 설치 전 정리: role이 워크로드를 결정한다 #

Vector Helm 차트는 하나지만, role 값에 따라 생성되는 워크로드가 달라집니다. OTel이 차트는 같고 mode로 갈리는 것과 같은 발상입니다.

role워크로드용도
AgentDaemonSet노드별 로그 수집
AggregatorStatefulSet중앙 집계(PVC 사용)
Stateless-AggregatorDeployment상태 없는 집계

⚠️ 기본 role은 Aggregator 입니다. Agent로 쓰려면 반드시 role: Agent를 명시해야 합니다.

대규모는 Agent + Aggregator 2단, 소규모는 Agent 직결입니다.

flowchart LR
    subgraph cluster["클러스터"]
        A["Vector Agent<br/>DaemonSet<br/>kubernetes_logs"] -->|"vector :6000"| AGG["Vector Aggregator<br/>StatefulSet<br/>VRL + sink"]
    end
    AGG -->|"elasticsearch sink<br/>/insert/elasticsearch/"| VL["VictoriaLogs<br/>(vmauth :8427)"]

📦 폐쇄망 이미지 준비 #

Vector 이미지는 timberio/vector 하나입니다. Docker Hub에서 받아 사내 레지스트리로 미러합니다.

1docker pull docker.io/timberio/vector:0.5x.0-debian
2docker tag docker.io/timberio/vector:0.5x.0-debian <사내레지스트리>/vector:0.5x.0-debian
3docker push <사내레지스트리>/vector:0.5x.0-debian

⚠️ nightly 태그는 금지하고 안정 버전 태그를 고정하세요(-debian 또는 -distroless-libc variant). 차트 tgz도 helm pull로 사내망에 반입합니다. Helm repo는 helm repo add vector https://helm.vector.dev 입니다.


⚙️ Agent values.yaml (DaemonSet) #

Agent는 kubernetes_logs source로 노드의 파드 로그를 수집해, type: vector sink로 Aggregator(6000)에 전달합니다.

 1# === vector-agent-values.yaml ===
 2role: Agent
 3
 4image:
 5  repository: <사내레지스트리>/vector
 6  tag: "0.5x.0-debian"
 7
 8resources:
 9  requests: { cpu: 100m, memory: 128Mi }
10  limits:   { cpu: 500m, memory: 512Mi }
11
12# customConfig 사용 시 모든 설정을 여기서 명시 (부분 오버라이드 아님)
13customConfig:
14  data_dir: /vector-data-dir
15  api:
16    enabled: true
17    address: 127.0.0.1:8686
18  sources:
19    k8s_logs:
20      type: kubernetes_logs
21      # 시스템 네임스페이스 제외 (노이즈 감소)
22      exclude_paths_glob_patterns:
23        - "/var/log/pods/kube-system_*/**"
24  transforms:
25    add_env:
26      type: remap
27      inputs: [k8s_logs]
28      source: |
29        .env = "prod"   # 클러스터마다 dev/stg/prod
30  sinks:
31    to_aggregator:
32      type: vector
33      inputs: [add_env]
34      address: "vector-aggregator:6000"   # 같은 클러스터 aggregator svc
35      # 디스크 버퍼 + ack로 유실 방지
36      buffer:
37        type: disk
38        max_size: 268435488   # 약 256Mi
39      healthcheck:
40        enabled: false

💡 차트가 kubernetes_logs에 필요한 RBAC(ClusterRole/Binding/ServiceAccount) 를 기본 제공합니다. Vector가 /api/v1/pods에 접근해 메타데이터를 붙이려면 이 권한이 필요합니다. 읽기 위치는 data_dir의 체크포인트에 저장돼 재시작 시 중복 없이 이어 읽습니다.


⚙️ Aggregator values.yaml (StatefulSet) #

Aggregator는 Agent들이 보낸 로그를 type: vector source(6000)로 받아, VRL로 가공한 뒤 elasticsearch sink로 VictoriaLogs에 적재합니다.

 1# === vector-aggregator-values.yaml ===
 2role: Aggregator
 3replicas: 2
 4
 5image:
 6  repository: <사내레지스트리>/vector
 7  tag: "0.5x.0-debian"
 8
 9resources:
10  requests: { cpu: 200m, memory: 256Mi }
11  limits:   { cpu: "1", memory: 1Gi }
12
13# Aggregator는 PVC 사용(StatefulSet)
14persistence:
15  enabled: true
16  storageClassName: <사내-storageclass>
17  size: 10Gi
18
19# VictoriaLogs 인증 토큰 등 자격증명 (Secret으로 주입, git 커밋 금지)
20secrets:
21  generic:
22    vl_token: "<적재용-토큰>"
23
24customConfig:
25  data_dir: /vector-data-dir
26  api:
27    enabled: true
28    address: 0.0.0.0:8686
29  sources:
30    from_agents:
31      type: vector
32      address: 0.0.0.0:6000
33      version: "2"
34  transforms:
35    cleanup:
36      type: remap
37      inputs: [from_agents]
38      source: |
39        # 불필요 필드 정리 (카디널리티 관리)
40        del(.kubernetes.pod_ip)
41        del(.file)
42  sinks:
43    vlogs:
44      type: elasticsearch
45      inputs: [cleanup]
46      endpoints:
47        - http://vlc-victoria-logs-cluster-vmauth.logging.svc:8427/insert/elasticsearch/
48      mode: bulk
49      api_version: v8
50      compression: gzip
51      healthcheck:
52        enabled: false
53      query:
54        _msg_field: message
55        _time_field: timestamp
56        _stream_fields: kubernetes.pod_namespace,kubernetes.container_name,env
57      # 적재 시 무시할 필드
58      ignore_fields: log.offset,event.original
59      # 인증이 필요하면 헤더로 토큰(또는 vmauth basic auth)
60      request:
61        headers:
62          Authorization: "Bearer ${VL_TOKEN}"   # secrets.generic 주입값

핵심은 적재 sink입니다. VictoriaLogs 전용 sink가 없으므로 elasticsearch sink로 /insert/elasticsearch/ 에 보내고, 클러스터 모드는 vmauth(8427) 를 경유합니다.


⚠️ 흔한 함정: Helm vs Vector 템플릿 충돌 #

Vector의 템플릿 문법 {{ ... }}이 Helm 템플릿과 겹쳐, customConfig 안에서 그대로 쓰면 Helm이 먼저 해석해 깨집니다. 이게 Vector 차트에서 가장 자주 막히는 지점입니다.

Vector 템플릿(동적 필드 참조)을 쓰려면 이스케이프해야 합니다.

1path: /var/log/k8s/{{ "{{" }} .folder {{ "}}" }}/{{ "{{" }} .filename {{ "}}" }}.log

💡 env = "prod"처럼 정적 값은 문제없지만, 경로·필드명에 Vector 동적 참조({{ .field }})를 넣을 때는 반드시 위처럼 이스케이프하세요.


🚀 설치 (Aggregator 먼저) #

Agent가 보낼 대상(6000)이 살아 있어야 하므로 Aggregator를 먼저 설치합니다. OTel에서 Gateway를 먼저 띄우는 것과 같은 원리입니다.

 1kubectl create namespace logging
 2
 3# 1) Aggregator 먼저 (agent가 보낼 6000이 살아있어야 함)
 4helm install vector-aggregator ./vector-<차트버전>.tgz \
 5  -f vector-aggregator-values.yaml -n logging
 6kubectl -n logging rollout status statefulset/vector-aggregator
 7
 8# 2) Agent 나중
 9helm install vector-agent ./vector-<차트버전>.tgz \
10  -f vector-agent-values.yaml -n logging
11kubectl -n logging get pods -o wide

🔎 vmui로 적재 확인 #

1kubectl -n logging port-forward svc/vlc-victoria-logs-cluster-vmauth 8427
2# 브라우저: http://localhost:8427/select/vmui/  →  LogsQL: env:prod

로그가 보이면 Agent → Aggregator → VictoriaLogs 파이프라인이 정상입니다.

env:prod

🧪 검증 / 트러블슈팅 #

Vector 자체 도구로 설정·처리량을 점검합니다.

1# 설정 검증 (Vector 자체 도구)
2kubectl -n logging exec -it <vector-pod> -- vector validate /etc/vector/vector.yaml
3
4# 실시간 처리량
5kubectl -n logging exec -it <vector-pod> -- vector top
6
7# 렌더링 이미지 확인
8helm template x ./vector-<차트버전>.tgz -f vector-agent-values.yaml | grep 'image:'
증상원인해결
설정 일부 무시됨customConfig를 부분만 작성전체 명시(부분 오버라이드 아님)
경로의 {{ }}가 깨짐Helm/Vector 템플릿 충돌이스케이프({{ "{{" }})
적재 안 됨elasticsearch sink 경로 오타/insert/elasticsearch/ 확인
조회 급격히 느려짐_stream_fields 미지정스트림 필드 제한
메타데이터 누락·권한 오류RBAC 부족/api/v1/pods 접근 권한 확인

💡 신뢰성: buffer.type: disk + sink acknowledgments로 다운스트림 장애 시에도 at-least-once 전달을 보장합니다. 자체 메트릭은 internal_metrics source + prometheus_exporter sink로 노출하고, podMonitor로 Prometheus Operator와 연동합니다(핵심: vector_component_sent_events_total, vector_component_errors_total, vector_buffer_byte_size).


📐 대규모 vs 소규모, 무엇이 다른가 #

규모에 따라 달라지는 점만 한곳에 모으면 다음과 같습니다. 이 글의 기본 전제는 대규모(Agent + Aggregator) 입니다.

구분대규모(기본)소규모/개인
구성Agent + AggregatorAgent만
Agent sinktype: vector → Aggregatorelasticsearch → VictoriaLogs 직결
AggregatorStatefulSet, PVC없음
VRL 가공 위치AggregatorAgent

💡 소규모라면 Aggregator를 만들지 말고, Agent의 sink를 바로 elasticsearch(VictoriaLogs)로 두면 됩니다. transform(VRL)도 Agent에서 처리합니다.

 1# 소규모 agent 직결 예 (sinks만 교체)
 2sinks:
 3  vlogs:
 4    type: elasticsearch
 5    inputs: [add_env]
 6    endpoints:
 7      - http://<victorialogs>:9428/insert/elasticsearch/
 8    api_version: v8
 9    healthcheck: { enabled: false }
10    query:
11      _stream_fields: kubernetes.pod_namespace,kubernetes.container_name,env

❓ 자주 묻는 질문 #

Q. role을 안 정하면 어떻게 되나요? 기본값은 Aggregator입니다. Agent로 쓰려면 role: Agent를 명시해야 합니다.

Q. customConfig를 일부만 써도 되나요? 안 됩니다. customConfig를 사용하면 sources/transforms/sinks 등 전체를 명시해야 합니다(부분 오버라이드가 아닙니다).

Q. VictoriaLogs sink 타입이 뭔가요? 전용 sink가 없습니다. elasticsearch(/insert/elasticsearch/) 또는 http(jsonline) sink를 씁니다.

Q. 경로에 {{ }}를 넣으니 깨집니다. Helm 템플릿과 충돌해서입니다. {{ "{{" }} .field {{ "}}" }} 형태로 이스케이프하세요.

Q. Agent와 Aggregator는 어떤 포트로 연결되나요? type: vector 전용 프로토콜, 기본 6000번 포트입니다.

Q. 로그 유실을 막으려면? buffer.type: disk + sink healthcheck/acknowledgments로 at-least-once 전달을 구성하세요.


🧭 시리즈: OTel + VictoriaLogs 로그 스택 #

이 시리즈는 같은 백엔드(VictoriaLogs)에 로그를 보내는 두 수집기 트랙으로 구성됩니다.

OTel 트랙

Vector 트랙 (대안 수집기)

비교

대시보드 트랙

이 편의 한 줄 요약: "role이 워크로드를 정하고, customConfig는 전체를 명시한다." Agent는 kubernetes_logs로 수집해 type: vector(6000)로 Aggregator에 보내고, Aggregator는 elasticsearch sink로 VictoriaLogs(vmauth 8427)에 적재합니다. Helm/Vector 템플릿 충돌 이스케이프와 _stream_fields 카디널리티 관리가 핵심 주의점입니다.


📚 참고 #