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 | 워크로드 | 용도 |
|---|---|---|
Agent | DaemonSet | 노드별 로그 수집 |
Aggregator | StatefulSet | 중앙 집계(PVC 사용) |
Stateless-Aggregator | Deployment | 상태 없는 집계 |
⚠️ 기본 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-libcvariant). 차트 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+ sinkacknowledgments로 다운스트림 장애 시에도 at-least-once 전달을 보장합니다. 자체 메트릭은internal_metricssource +prometheus_exportersink로 노출하고,podMonitor로 Prometheus Operator와 연동합니다(핵심:vector_component_sent_events_total,vector_component_errors_total,vector_buffer_byte_size).
📐 대규모 vs 소규모, 무엇이 다른가 #
규모에 따라 달라지는 점만 한곳에 모으면 다음과 같습니다. 이 글의 기본 전제는 대규모(Agent + Aggregator) 입니다.
| 구분 | 대규모(기본) | 소규모/개인 |
|---|---|---|
| 구성 | Agent + Aggregator | Agent만 |
| Agent sink | type: vector → Aggregator | elasticsearch → VictoriaLogs 직결 |
| Aggregator | StatefulSet, PVC | 없음 |
| VRL 가공 위치 | Aggregator | Agent |
💡 소규모라면 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 트랙
- 1편 — OpenTelemetry 개념과 Agent/Gateway 구조
- 2편 — VictoriaLogs 클러스터 구축
- 3편 — 폐쇄망 OTel Collector Helm 설치
- 4편 — 멀티클러스터 중앙집중
Vector 트랙 (대안 수집기)
- 1편 — Vector 개념과 파이프라인 구조
- 2편 (현재) — Vector 설치: Agent/Aggregator Helm values
- 3편 — VRL로 로그 가공
비교
- OTel vs Vector — 어떤 걸 선택할까
대시보드 트랙
- 1편 — 조회 개요: Grafana·vmui·Perses
- 2편 — Grafana 연결: 플러그인·Explore·대시보드
- 3편 — vmui로 LogsQL 탐색
- 4편 — Perses 연결 (예정)
이 편의 한 줄 요약: "role이 워크로드를 정하고, customConfig는 전체를 명시한다." Agent는 kubernetes_logs로 수집해 type: vector(6000)로 Aggregator에 보내고, Aggregator는 elasticsearch sink로 VictoriaLogs(vmauth 8427)에 적재합니다. Helm/Vector 템플릿 충돌 이스케이프와 _stream_fields 카디널리티 관리가 핵심 주의점입니다.