[Loki] #6.Docker기반 Loki 설치 및 설정 가이드
📌 들어가며
로그를 한곳에 모아 조회·알람하려면 로그 집계 시스템이 필요합니다. Loki는 Grafana에서 제공하는 오픈소스 로그 집계 시스템으로, Prometheus·Grafana 스택과 잘 맞고 메타정보만 인덱싱해 Elasticsearch보다 가볍게 쓸 수 있습니다. 이 글은 Docker 기반으로 Loki를 설치하고 설정하는 방법을 안내합니다.
💡 이런 분들께 추천합니다
- Grafana/Prometheus 스택에 로그 수집(Loki)을 붙이려는 분
- Docker 환경에서 Loki를 빠르게 띄워 보고 싶은 분
- 로그 집계·모니터링 구성을 처음 해 보는 분
🧩 개념 설명 / 배경 지식
이미 Loki와 Grafana 스택을 알고 있다면 다음 섹션으로 넘어가도 됩니다.
Grafana Promtail Loki Architecture
아래 그림에서 Loki에 해당하는 부분입니다. Prometheus Loki는 Grafana에서 제공하는 오픈소스 기반의 로그 집계 시스템이며, 수평 확장·고가용성·Multi-tenancy를 지원합니다.

Loki 인덱스 구성
메타정보만 인덱스하도록 강제되어 있어, 전체를 인덱싱하는 Elasticsearch에 비해 빠르고 간결하며 저장소를 적게 씁니다.

🔍 본론: Docker 기반 Loki 설치 및 설정
테스트 환경: 인터넷 가능 환경, Rocky Linux 8.6, Docker 구성 완료 상태
1. Loki docker-compose 구동을 위한 스크립트 준비
전체파일 구성
tree
├── create.sh
├── delete.sh
├── docker-compose.yml
├── log.sh
├── start.sh
└── stop.sh
1) Loki의 docker-compose.yml 샘플
주요설정 설명
- -config.file: loki에서 사용하는 config파일 위치 정의. 아래와 같이 설정시 loki 컨테이너 이미지에서 제공하는 기본설정값 그대로 사용
vi docker-compose.yml
version: '3.7'
# monitor-net이름으로 이미 구성한 경우에는 networks부분은 주석처리
networks:
monitor-net:
driver: bridge
services:
loki:
# image: grafana/loki:2.7.4
image: grafana/loki:latest
container_name: loki
ports:
- 3100:3100
command: -config.file=/etc/loki/local-config.yaml
networks:
- monitor-net
labels:
logging: "promtail"
logging_jobname: "containerlogs"
참고: /etc/loki/local-config.yaml 설정 내용 조회방법
docker exec -it loki cat /etc/loki/local-config.yaml
auth_enabled: false
server:
http_listen_port: 3100
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
ruler:
alertmanager_url: http://localhost:9093
# By default, Loki will send anonymous, but uniquely-identifiable usage and configuration
# analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/
#
# Statistics help us better understand how Loki is used, and they show us performance
# levels for most users. This helps us prioritize features and documentation.
# For more information on what's sent, look at
# https://github.com/grafana/loki/blob/main/pkg/usagestats/stats.go
# Refer to the buildReport method to see what goes into a report.
#
# If you would like to disable reporting, uncomment the following lines:
#analytics:
# reporting_enabled: false
2) docker 컨테이너 생성,삭제,구동,중지,로그조회 등 스크립트 작성
cat > create.sh <<EOF
#!/usr/bin/bash
docker-compose -f docker-compose.yml up -d
docker-compose -f docker-compose.yml logs -f
EOF
cat > delete.sh <<EOF
#!/usr/bin/bash
docker-compose -f docker-compose.yml down -v
EOF
cat > start.sh <<EOF
#!/usr/bin/bash
docker-compose -f docker-compose.yml start
EOF
cat > stop.sh <<EOF
#!/usr/bin/bash
docker-compose -f docker-compose.yml stop
EOF
cat > log.sh <<EOF
#!/usr/bin/bash
docker-compose -f docker-compose.yml logs -f
EOF
chmod +x *.sh
2. Loki 정상구동여부 확인
### 구동하기
./create.sh
### 도커컨테이너 정상구동여부 확인
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c16cdc7ba488 grafana/loki:latest "/usr/bin/loki -conf…" 6 days ago Up 35 minutes 0.0.0.0:3100->3100/tcp, :::3100->3100/tcp loki
docker logs loki
[root@rocky8 promtail]# docker logs loki
level=warn ts=2023-04-12T00:20:46.856282084Z caller=loki.go:286 msg="per-tenant timeout not configured, using default engine timeout (\"5m0s\"). This behavior will change in the next major to always use the default per-tenant timeout (\"5m\")."
level=info ts=2023-04-12T00:20:46.870600208Z caller=main.go:108 msg="Starting Loki" version="(version=2.8.0, branch=HEAD, revision=90888a0cc)"
level=info ts=2023-04-12T00:20:46.871668305Z caller=server.go:323 http=[::]:3100 grpc=[::]:9095 msg="server listening on addresses"
level=warn ts=2023-04-12T00:20:46.895185176Z caller=cache.go:114 msg="fifocache config is deprecated. use embedded-cache instead"
level=warn ts=2023-04-12T00:20:46.895219711Z caller=experimental.go:20 msg="experimental feature in use" feature="In-memory (FIFO) cache - chunksembedded-cache"
level=info ts=2023-04-12T00:20:46.895570888Z caller=table_manager.go:262 msg="query readiness setup completed" duration=1.322µs distinct_users_len=0
level=info ts=2023-04-12T00:20:46.895605572Z caller=shipper.go:131 msg="starting index shipper in RW mode"
level=info ts=2023-04-12T00:20:46.895770641Z caller=shipper_index_client.go:78 msg="starting boltdb shipper in RW mode"
level=info ts=2023-04-12T00:20:46.89613884Z caller=worker.go:112 msg="Starting querier worker using query-scheduler and scheduler ring for addresses"
level=info ts=2023-04-12T00:20:46.8972083Z caller=mapper.go:47 msg="cleaning up mapped rules directory" path=/loki/rules-temp
이후 로그 생략..
3. Loki 메트릭 데이터 조회
curl http://아이피:3100/metrics
# HELP cortex_consul_request_duration_seconds Time spent on consul requests.
# TYPE cortex_consul_request_duration_seconds histogram
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="0.005"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="0.01"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="0.025"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="0.05"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="0.1"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="0.25"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="0.5"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="1"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="2.5"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="5"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="10"} 725
cortex_consul_request_duration_seconds_bucket{kv_name="ingester-ring",operation="CAS loop",status_code="200",le="+Inf"} 725
cortex_consul_request_duration_seconds_sum{kv_name="ingester-ring",operation="CAS loop",status_code="200"} 0.052866492999999945
cortex_consul_request_duration_seconds_count{kv_name="ingester-ring",operation="CAS loop",status_code="200"} 725
# HELP cortex_distributor_ingester_clients The current number of ingester clients.
# TYPE cortex_distributor_ingester_clients gauge
cortex_distributor_ingester_clients 2
# HELP cortex_dns_failures_total The number of DNS lookup failures
# TYPE cortex_dns_failures_total counter
cortex_dns_failures_total{name="memberlist"} 0
# HELP cortex_dns_lookups_total The number of DNS lookups resolutions attempts
# TYPE cortex_dns_lookups_total counter
cortex_dns_lookups_total{name="memberlist"} 0
# HELP cortex_frontend_query_range_duration_seconds Total time spent in seconds doing query range requests.
# TYPE cortex_frontend_query_range_duration_seconds histogram
4. 구동화면 예시
container 로그 파일을 Promtail로 수집한 뒤 Grafana 대시보드에 추가해 조회하는 방법은 별도 글로 설명 예정입니다.
⚠️ 주의사항
monitor-net등 기존 Docker 네트워크가 있으면docker-compose.yml의networks부분을 주석 처리하세요. Loki 기본 설정은 단일 인스턴스용이므로, 프로덕션 고가용성은 공식 문서의 분산 설정을 참고하세요.
✅ 실습 / 적용 예시
Step 1. docker-compose.yml과 create.sh·delete.sh·start.sh·stop.sh·log.sh 스크립트를 준비합니다. Step 2. ./create.sh로 Loki 컨테이너를 띄운 뒤 docker ps, docker logs loki로 구동을 확인합니다. Step 3. curl http://아이피:3100/metrics로 메트릭을 조회하고, Promtail·Grafana와 연동해 로그를 수집·조회합니다.
🚧 트러블슈팅 / 자주 묻는 질문
Q. Loki 컨테이너는 떠 있는데 Grafana에서 로그가 안 보여요.
A. Promtail이 Loki로 로그를 전송하도록 설정했는지, Grafana 데이터 소스에 Loki URL(예: http://loki:3100)이 올바르게 등록됐는지 확인하세요. Q. 기본 설정 파일 내용을 바꾸고 싶어요.
A. local-config.yaml을 바꾸려면 볼륨 마운트로 설정 파일을 넘기고 command에서 해당 경로를 지정하세요.
📝 마무리
- Loki는 Grafana 계열의 로그 집계 시스템으로, Docker 한 컨테이너로 빠르게 구동할 수 있습니다.
- docker-compose와 스크립트로 생성·시작·중지·로그 조회를 정리해 두면 운영이 편합니다.
- 다음 단계로 Promtail 로그 수집 설정과 Grafana 대시보드 구성을 이어가면 됩니다.
댓글남기기