loki-stack을 통해서 loki, promtail, grafana, Prometheus 등을 한번에 패키지로 설치할 수 있다. Helm으로 빠르고 간편하게 설치 가능하며, 로그 시스템만 추가적으로 구축하는 경우에는 Loki와 promtail 단독 helm chart를 사용하는것이 더 좋다.

Loki-stack 패키지 다운시 아래 리스트가 다운되며, loki와 Promtail은 필수적으로 설치해야한다.
filebeat: ELK 스택(Elasticsearch)에서 사용 (promtail 대체)
fluent-bit: promtail을 대신하는 가볍고 빠른 수집기
grafana
logstash: ELK 스택(Elasticsearch)에서 사용 (promtail 대체)
loki: Log Engine (저장/분석)
prometheus
promtail: Log Forwarder (수집기)로 각 노드에서 로그를 읽어서 loki로 push해주는 agent이고 데몬셋으로 띄워진다.
Loki와 promtail은 필수적으로 설치해야 로그 수집 시스템을 구성할 수 있다. grafana와 prometheus는 이미 설치되어있어서 설치하지 않았지만 시각화를 위해서 필요하다.
로그 전달 과정 (Promtail → Loki → Grafana)
1. Promtail (수집기): 로그 파일을 읽으면서 설정된 규칙(relabel_configs)에 따라 라벨(Key:Value)을 붙인다. 이때 JSON 형식이 아니라 Loki 전용 프로토콜로 라벨과 로그 라인을 묶어서 보낸다. relabel_configs에 라벨을 추가할 수 있지만 너무 많은 라벨 추가 시 Loki 인덱싱이 너무 많아질 수 있기에 조심해야한다.
2. Loki (저장소): 받은 라벨을 인덱싱하여 저장한다. 예를 들어서 namespace=airflow 이런식으로 인덱싱하여 로그를 저장한다.
3. Grafana (시각화): Loki에게 LogQL을 통해서 Log Selectors로 필터링해서 로그를 가져온다.
설치 시 필수 확인사항
모두 loki chart의 values.yaml 파일내에서 수정해야한다.
1. loki의 pod가 재시작되어도 데이터를 보전할 수 있게 PVC 구성
loki는 엔진으로써 데이터를 저장하고 분석하기에 Pod가 재시작되어도 데이터가 날라가지 않게 PVC 구성을 해줘야한다.
persistence:
enabled: true # false를 true로 덮어쓰기
size: 100Gi # 10Gi를 100Gi로 덮어쓰기
storageClassName: "nfs-client" # 빈 값을 "nfs-client"로 덮어쓰기
2. 데이터 보관기간 설정
reject_old_samples_max_age와 retention_period은 동일한 값을 설정해주는것이 좋다. 보관은 90일 하는데, 유입은 7일 전 것만 받으면 과거 데이터를 백업해서 넣고 싶을 때 넣을수가없다. 기본값은 7일이였다.
limits_config:
reject_old_samples: true
reject_old_samples_max_age: 2160h # 90일 이전 로그 유입 차단
retention_period: 2160h # 90일 지나면 삭제
3. 이전 데이터 삭제 활성화
Loki가 실제로 1번에서 할당한 PVC로 설정해서 Loki Pod에 마운트해준 디스크에서 오래된 데이터를 찾아 지우는 작업을 수행한다. Compactor가 실제로 삭제 명령을 내리고 삭제 작업을 하기에, true로 주지 않는다면 2번에서 설정한 90일 지나면 삭제가 먹지 않는다. 운영 환경에서 NAS 디스크 용량 고갈을 방지하기 위해서는 필수적이다.
config:
compactor:
retention_enabled: true
Grafana와 loki 설치가 완료됐다면 아래 링크에서 대시보드 템플릿을 json 파일로 다운받거나 url로 grafana에 import 가능하다.
시간도 절약되고 다양한 대시보드가 존재해서 추천한다.
대시보드 모음 페이지: https://grafana.com/grafana/dashboards/
Grafana dashboards | Grafana Labs
No results found. Please clear one or more filters.
grafana.com
나는 저 중에서 아래 링크로 만들어진 대시보드를 선택했다. 여기서 grafana Variables 설정만 수정하여 node > namespace > pod 계층으로 조회할 수 있도록 시각화했다.
https://grafana.com/grafana/dashboards/24574-logging-dashboard-via-loki-v3/
Logging Dashboard via Loki v3 | Grafana Labs
Big update of https://grafana.com/grafana/dashboards/18042-logging-dashboard-via-loki-v2/ By default queries of variables and panels supposed that you have this loki labels (if not, you should change them in variables dashboard settings section or in json
grafana.com

트러블슈팅
1. Grafana에서 loki connection error
Save & Test 시 오류가 발생했다. Grafana pod에 들어가서 오류 메세지( Unexpected < )가 아래와 같이 나오는걸 확인했다.
Loki: v2.6.1 (구형) 이였고 Grafana는 v11.2.2 (최신) 버전이여서 발생한 문제였다. grafana와 loki의 각 pod 들어가서 curl을 다양한 종류로 날려봤는데 서로 통신이 너무 잘된다... Loki 엔진을 업그레이드하면 문제는 해결되지만, 결론적으로 Explore에서 로그가 나온다면 그냥 쓰면 된다!!
2. Grafana Dashboard Tag 값 불일치
Loki version이 3인 대시보드를 import 했더니, 나는 Loki version이 2라서 라벨 호환이 되지 않아서 json 파일을 수정하고 import했더니 문제가 없었다. 라벨 호환이 되지 않은 이유는 3버전부터 Promtail의 OTel(OpenTelemetry)의 Semantic Conventions(시맨틱 컨벤션) 규칙을 따르기 때문이다. 2버전에서는 차트 제작자 마음대로 라벨링을 했지만, 3버전부터는 전세계 엔지니어들이 정한 OTel 규칙을 따라서 만들어졌다. 그래서 key가 달랐고 key명으로 패널 쿼리와 Variables 설정값의 name과 label을 수정했다.
3. Variables의 Chained Variables(종속 변수) 미작동
node > namespace > pod로 종속 변수를 설정했는데 자꾸 전체 레이블이 보이면서 필터링이 무시됐다. 아래와 같이 수정했는데도 되지 않아서 트러블슈팅에 오랜 시간이 걸렸다. 알고보니 loki 2.6.1 버전에서는 Grafana 드롭다운 종속변수가 잘 적용되지 않았다. 그래서 Loki 엔진을 2.9.3으로 업그레이드 + 최신 인덱스 포맷(TSDB)로 변경했더니 그라파나와의 통신 병목이 해결됐다. Loki 버전을 업그레이드 한 이유는 2.8 버전부터 TSDB가 적용가능하기 때문이다.
#수정해도 적용이 안됨
#수정 전
label_values({node_name=~\"$node_name\"}, namespace)"
# 수정 후
label_values({node_name=~\"${node_name:regex}\"}, namespace)"
loki chart의 values.yaml의 아래 부분을 수정했다.
schema_config:
configs:
# 1. 기존 boltdb-shipper 설정
- from: "2024-01-01"
store: boltdb-shipper
object_store: s3
schema: v11
index:
prefix: index_
period: 24h
# 2. 신규 TSDB 설정
- from: "2026-05-13"
store: tsdb # 수정
object_store: s3
schema: v13 # 수정 (tsdb 사용 시 v13 권장)
index:
prefix: index_
period: 24h
storage_config:
tsdb_shipper: # 수정
active_index_directory: /loki/index
cache_location: /loki/index_cache
shared_store: s3
인덱스 스토리지 엔진(Index Storage Engine) 파헤쳐보기
1. boltdb-shipper (기존 방식)
- 알고리즘: B+ Tree (Key-Value store) 기반
- 구조: 인덱스를 BoltDB라는 파일(KV 저장소)에 담아서 관리함, "이 레이블 조합은 이 로그 위치에 있다"라는 정보를 키-값 쌍으로 저장하는 방식
- 특징: 구현이 단순하고 안정적이지만, 레이블이 많아지면(High Cardinality) 인덱스 파일이 너무 커지고, 여러 레이블을 조합해서 필터링할 때 속도가 급격히 떨어진다. ('필터링 무시' 현상을 일으킨 원인)
2. tsdb (신규 방식)
- 알고리즘: Inverted Index (역색인) 기반
- 구조: 프로메테우스(Prometheus)의 TSDB 구조를 그대로 가져옴. 특정 레이블 값(예: node="worker-1")이 포함된 모든 데이터 블록의 ID를 리스트(Postings list)로 관리한다.
- 특징: 검색 조건이 node="worker-1" AND namespace="prod"라면, 각각의 리스트를 가져와서 교집합만 슥 뽑아내면 돼서 알고리즘적으로 훨씬 효율적이다.
'Monitoring' 카테고리의 다른 글
| 📊 kube-prometheus-stack로 prometheus와 Grafana 설치하기 (0) | 2026.06.28 |
|---|---|
| 📊 인프라/어플리케이션 메트릭 모니터링 (Prometheus, Telegraf, PostgreSQL) (0) | 2026.05.02 |