Loki — 로그를 색인하지 않는 로그 저장소 · 보존과 삭제 · 실습
요청하자마자 화면에서 사라졌는데 저장 용량은 한 달째 그대로였다
목표
보존을 켜고 스트림마다 다른 기간을 거는 설정을 직접 써서 검증하고, 그 설정으로 두 번째 Loki 를 띄운 뒤 삭제 요청을 넣어 접수와 실제 삭제 사이의 시간 간격을 숫자로 확인합니다.
왜 중요한가
Loki 는 보존을 꺼 둔 채로 출발한다. 아무도 켜지 않으면 넣은 로그는 영원히 남고, 청구서가 네 배가 된 뒤에야 그 사실을 알게 된다. 삭제 요청도 마찬가지로 두 겹이다 — 기본 방식에서는 요청이 접수되는 즉시 질의가 그 줄을 걸러 주지만, 저장된 객체에서 실제로 지워지는 것은 취소 대기 기간이 지난 뒤 컴팩터의 몫이다. '안 보인다' 를 '지워졌다' 로 읽으면 규제 대응 보고서가 틀리게 되고 용량 계획도 어긋난다. 보존 기간을 정하는 일은 추정이 아니라 실측에서 출발해야 한다 — 질의 응답에 실려 오는 바이트 수가 그 출발점이다.
단계
1. /root/lk-retention 에서 Loki 를 띄우고 date +%s 를 /root/lk-retention/anchor.txt 에 적은 뒤 python3 /opt/lab/d5/gen.py retention "$(cat anchor.txt)" 로 자료를 넣으세요. 그리고 audit 과 debug 두 스트림을 한 시간 구간으로 각각 질의해 응답 통계의 읽은 바이트를 /root/lk-retention/01-bytes.txt 에 audit_bytes=<정수> 와 debug_bytes=<정수> 두 줄로 적으세요.
2. 1단계의 한 시간치 바이트에서 스트림별 저장량을 계산해 /root/lk-retention/budget.tsv 를 만드세요. 머리글 없이 두 줄이고 각 줄은 탭으로 나눈 네 칸 <스트림><탭><한시간바이트><탭><보존일수><탭><보존기간총바이트> 입니다. 스트림은 순서대로 audit, debug 이고 보존 일수는 각각 365 와 1 로 잡습니다. 총바이트는 한시간바이트 × 24 × 보존일수 입니다.
3. /root/lk-retention/loki-ret.yaml 을 쓰세요. 지금 쓰는 loki.yaml 을 바탕으로 하되 다음을 더합니다 — server.http_listen_port 는 3200, server.grpc_listen_port 는 9096, 저장 경로는 /tmp/lokiret 아래, compactor.retention_enabled 는 true, compactor.delete_request_store 는 filesystem, compactor.working_directory 지정, limits_config.retention_period 는 720h. 그리고 loki -config.file=/root/lk-retention/loki-ret.yaml -verify-config 가 아무 오류 없이 끝나야 합니다.
4. /root/lk-retention/loki-ret.yaml 의 limits_config 에 retention_stream 목록을 더해 {app="debug"} 는 24h, {app="audit"} 는 8760h 로 보존되게 하세요. 우선순위는 각각 1 과 2 로 명시합니다. 그리고 /root/lk-retention/04-rules.txt 에 두 줄을 적으세요 — rules=<규칙 개수> 와 verify=ok(-verify-config 가 통과했을 때).
5. /root/lk-retention/loki-ret.yaml 로 두 번째 Loki 를 띄우고 http://localhost:3200/ready 가 ready 를 돌려줄 때까지 기다리세요. 그리고 그 서버의 /config 에서 세 값을 읽어 /root/lk-retention/05-run.txt 에 적습니다 — retention_enabled=<값>, retention_period=<값>, compaction_interval=<값>.
6. 3200 포트의 Loki 에 줄을 몇 개 넣고, 그중 한 스트림의 한 구간을 지워 달라고 요청하세요. 요청은 POST /loki/api/v1/delete 에 query·start·end 를 줍니다. 그리고 /root/lk-retention/06-delete.txt 에 세 줄을 적으세요 — post_code=<HTTP 상태 코드>, requests=<목록에 있는 요청 수>, status=<그 요청의 status 값>.
7. 삭제를 요청한 그 구간을 다시 질의해 지금 몇 줄이 나오는지 세고, 실제 삭제가 언제 일어나는지를 서버 설정에서 찾아 확인하세요. /root/lk-retention/07-async.txt 에 네 줄을 적습니다 — still_visible=<정수>, mode=<deletion_mode 값>, param=<실제 삭제까지 기다리는 시간을 정하는 설정 이름>, value=<서버가 찍은 값 그대로>.
8. /root/lk-retention/policy.txt 에 다섯 줄을 적으세요 — audit_period=, debug_period=(둘 다 설정에 쓴 값 그대로), audit_bytes_total=, debug_bytes_total=(2단계 표의 마지막 칸), note=(공백 뺀 60자 이상, 왜 두 기간을 다르게 잡았는지와 삭제 요청이 즉시 반영되지 않는다는 사실을 함께 적습니다).
참고
- 작업 디렉터리는
/root/lk-retention입니다. 첫 번째 Loki 는 1단계에서, 두 번째는 5단계에서 띄웁니다. - 자료 생성기는
/opt/lab/d5/gen.py이고retention자료를 씁니다. 채점기는 이 파일을 읽지 않습니다. - 이 실습에서는 보존 삭제가 실제로 일어나는 것까지는 볼 수 없습니다. 컴팩터는 기본 10분 주기로 돌고 삭제 요청은 기본 24시간을 기다립니다. 이 실습이 확인하는 것은 설정이 유효한가, 서버가 그 값으로 떴는가, 요청이 접수되는가, 그리고 그 일이 비동기라는 사실까지입니다.
- 두 번째 Loki 는
http_listen_port만 바꾸면 죽습니다 —grpc_listen_port도 함께 바꿔야 합니다. 저장 경로(path_prefix와storage_config)도 첫 번째와 겹치면 안 됩니다. - 삭제 요청의
start·end는 초 단위 정수입니다. 질의 API 의 나노초와 다릅니다. - [보존(Compactor)](https://grafana.com/docs/loki/latest/operations/storage/retention/) · [로그 삭제 요청](https://grafana.com/docs/loki/latest/operations/storage/logs-deletion/) · [설정 문서](https://grafana.com/docs/loki/latest/configure/) · [HTTP API](https://grafana.com/docs/loki/latest/reference/loki-http-api/)
단계 8개
- 두 종류의 로그를 넣고 실제 바이트를 잰다
- 실측에서 보존 예산을 계산한다
- 보존을 켜는 설정을 쓰고 검증한다
- 스트림마다 다른 보존 기간
- 두 번째 Loki 를 띄운다 — 포트는 두 개다
- 삭제 요청을 넣고 목록을 본다
- 응용 ① — 안 보이는 것과 지워진 것은 다르다
- 응용 ② — 보존 정책을 문서로 못박는다