二時間分を復旧して入れたのに画面には何も出なかった
한국어 원문으로 표시합니다.
목표
과거 타임스탬프로 넣은 줄이 접수는 되는데 보이지 않는 현상을 파드의 진짜 Loki 에서 재현하고, 그 경계를 정하는 설정을 서버에서 직접 확인한 뒤 플러시로 되살립니다.
왜 중요한가
Loki 의 쓰기와 읽기는 서로 다른 길을 간다. 들어온 줄은 인제스터의 열린 청크에 쌓이고, 청크가 닫혀야 저장소로 올라간다. 질의는 저장소에 묻되 최근 구간이면 인제스터에도 묻는데, 그 '최근' 의 범위가 query_ingesters_within(기본 3시간)이다. 그래서 복구 작업으로 뒤늦게 밀어 넣은 과거 자료는 두 길 사이의 틈에 빠진다 — 저장소에는 아직 없고 인제스터에는 있지만 아무도 묻지 않는다. 이 구조를 모르면 'push 가 거짓말을 한다' 로 결론 내리고 엉뚱한 곳을 고치게 된다.
단계
/root/lk-chunks에서 Loki 를 띄우고date +%s를/root/lk-chunks/anchor.txt에 적은 뒤python3 /opt/lab/d5/gen.py chunks "$(cat anchor.txt)"로 자료를 넣으세요. 이 자료는 기준 시각에서 30분 안쪽에 있습니다.{app="fresh"}를 한 시간 구간으로 질의해 줄 수를 세고, 저장소 디렉터리/tmp/lokidata/chunks아래의 파일 수도 세어/root/lk-chunks/01-boot.txt에lines=<정수>와chunk_files=<정수>두 줄로 적으세요.python3 /opt/lab/d5/gen.py chunks-old "$(cat anchor.txt)"로 기준 시각에서 다섯 시간 전 자료를 넣으세요. 그리고 그 시각 앞뒤 한 시간 구간으로{app="aged"}를 질의해 줄 수를 세고,/root/lk-chunks/02-aged.txt에 두 줄로 적으세요 —push_code=<HTTP 상태 코드>와lines=<정수>.- 새 스트림 네 개에 한 줄씩 넣어 보이는지 확인하세요 — 기준 시각에서 1·2·4·5시간 전이고 라벨은
{"app":"b1h"}·b2h·b4h·b5h입니다. 결과를/root/lk-chunks/boundary.tsv에 머리글 없이 네 줄, 탭으로 나눈 두 칸<시간><탭><yes|no>로 적습니다(시간은1·2·4·5). 그리고 이 경계를 정하는 설정을 서버의/config에서 찾아/root/lk-chunks/03-param.txt에param=<설정 이름>과value=<기본값 그대로>두 줄로 적으세요. - 플러시 전후를 한 파일에 기록하세요. 먼저
{app="aged"}줄 수와/tmp/lokidata/chunks의 파일 수를 재고,curl -XPOST http://localhost:3100/flush를 부른 뒤 같은 두 숫자를 다시 잽니다./root/lk-chunks/04-flush.txt에 네 줄로 적으세요 —aged_before=,chunks_before=,aged_after=,chunks_after=. - 서버의
/config에서 열린 청크가 닫히는 조건을 정하는 세 설정을 찾아/root/lk-chunks/chunkparams.tsv에 머리글 없이 세 줄, 탭으로 나눈 두 칸<설정이름><탭><값>으로 적으세요. 순서는chunk_idle_period,chunk_target_size,max_chunk_age이고 값은 서버가 찍어 준 그대로입니다. - 플러시가 끝난 지금 색인에 어떤 스트림이 있는지 series API 로 확인해
/root/lk-chunks/06-series.txt에 두 줄로 적으세요 —streams=<정수>와apps=<app 라벨 값들을 쉼표로, 사전순>. 조회 구간은 기준 시각에서 과거 일곱 시간으로 주세요. 8단계에서 만들revive스트림은 세지 않습니다(이 단계에서는 아직 없습니다). /root/lk-chunks/runbook.txt에 네 줄을 적으세요. 각 줄은1.부터4.로 시작하고, 각 줄에는 실제로 칠 수 있는 확인 명령이나 확인할 값이 하나씩 들어가야 합니다. 주제는 "과거 구간의 로그가 비어 보인다" 는 신고를 받았을 때의 점검 순서입니다. 네 줄을 합쳐 공백을 뺀 글자가 120자 이상이어야 합니다.- 본문에
revive-check라는 낱말이 든 줄 하나를 라벨{"app":"revive"}로 기준 시각에서 여섯 시간 전에 넣고, 질의로 보이게 만든 뒤 그 줄의 본문을/root/lk-chunks/08-revive.txt에 한 줄로 적으세요. 본문의 나머지 내용은 자유입니다.
참고
- 작업 디렉터리는
/root/lk-chunks입니다. Loki 는 1단계에서 직접 띄웁니다. - 자료 생성기는
/opt/lab/d5/gen.py이고chunks와chunks-old두 자료를 씁니다. 채점기는 이 파일을 읽지 않습니다. - 이 실습 설정은
reject_old_samples: false라 오래된 타임스탬프도 접수됩니다. 운영 기본값은 켜져 있어서, 너무 오래된 자료는 접수 단계에서 거부됩니다. - 저장소는 로컬 파일 시스템(
/tmp/lokidata)입니다. 운영의 객체 저장소와 경로만 다르고 원리는 같습니다. - 흔한 실수: 플러시 직후에 바로 세는 것. 비동기라 몇 초 걸립니다 — 파일 수가 늘어날 때까지 상한을 둔 반복문으로 기다리세요.
- 흔한 실수: series API 에
start·end를 주지 않는 것. 기본 구간이 짧아 과거 스트림이 빠집니다. - Loki 구조 · 설정 문서 · HTTP API · 요청 검증과 속도 제한
최근 자료는 넣자마자 보인다
/root/lk-chunks 에서 Loki 를 띄우고 date +%s 를 /root/lk-chunks/anchor.txt 에 적은 뒤 python3 /opt/lab/d5/gen.py chunks "$(cat anchor.txt)" 로 자료를 넣으세요. 이 자료는 기준 시각에서 30분 안쪽에 있습니다. {app="fresh"} 를 한 시간 구간으로 질의해 줄 수를 세고, 저장소 디렉터리 /tmp/lokidata/chunks 아래의 파일 수도 세어 /root/lk-chunks/01-boot.txt 에 lines=<정수> 와 chunk_files=<정수> 두 줄로 적으세요.
설정 파일의 path_prefix 와 storage_config.filesystem.directory 가 저장소 자리를 정합니다. 파일 수는 find /tmp/lokidata/chunks -type f | wc -l 로 셉니다. 방금 넣었는데 그 디렉터리가 비어 있는 것이 이상하다면, 그것이 이 실습의 출발점입니다.
다섯 시간 전 자료는 204 를 받고도 안 보인다
python3 /opt/lab/d5/gen.py chunks-old "$(cat anchor.txt)" 로 기준 시각에서 다섯 시간 전 자료를 넣으세요. 그리고 그 시각 앞뒤 한 시간 구간으로 {app="aged"} 를 질의해 줄 수를 세고, /root/lk-chunks/02-aged.txt 에 두 줄로 적으세요 — push_code=<HTTP 상태 코드> 와 lines=<정수>.
생성기는 실패하면 0 이 아닌 값으로 끝납니다. 상태 코드를 직접 보고 싶으면 curl -o /dev/null -w '%{http_code}' 로 한 줄을 손으로 넣어 보세요. 질의 구간은 다섯 시간 전을 가운데 두어야 합니다 — 최근 한 시간으로 물으면 당연히 0 입니다.
경계가 어디인지 실측하고 설정에서 확인한다
새 스트림 네 개에 한 줄씩 넣어 보이는지 확인하세요 — 기준 시각에서 1·2·4·5시간 전이고 라벨은 {"app":"b1h"}·b2h·b4h·b5h 입니다. 결과를 /root/lk-chunks/boundary.tsv 에 머리글 없이 네 줄, 탭으로 나눈 두 칸 <시간><탭><yes|no> 로 적습니다(시간은 1·2·4·5). 그리고 이 경계를 정하는 설정을 서버의 /config 에서 찾아 /root/lk-chunks/03-param.txt 에 param=<설정 이름> 과 value=<기본값 그대로> 두 줄로 적으세요.
curl -s localhost:3100/config 가 지금 도는 설정을 통째로 내놓습니다. querier: 블록을 보세요. 값은 서버가 찍어 준 문자열 그대로 적습니다(예: 1h0m0s 같은 모양). 각 줄을 질의할 때는 그 시각 앞뒤로 넉넉한 구간을 주세요.
강제로 플러시하면 같은 질의가 답한다
플러시 전후를 한 파일에 기록하세요. 먼저 {app="aged"} 줄 수와 /tmp/lokidata/chunks 의 파일 수를 재고, curl -XPOST http://localhost:3100/flush 를 부른 뒤 같은 두 숫자를 다시 잽니다. /root/lk-chunks/04-flush.txt 에 네 줄로 적으세요 — aged_before=, chunks_before=, aged_after=, chunks_after=.
플러시는 비동기입니다. 파일이 실제로 생길 때까지 몇 초 걸리니, 고정 sleep 대신 파일 수가 늘어날 때까지 짧게 도는 반복문을 쓰세요(상한을 두는 것을 잊지 마세요). 질의 구간은 2단계와 같아야 두 숫자를 견줄 수 있습니다.
청크는 언제 닫히나 — 세 손잡이를 찾는다
서버의 /config 에서 열린 청크가 닫히는 조건을 정하는 세 설정을 찾아 /root/lk-chunks/chunkparams.tsv 에 머리글 없이 세 줄, 탭으로 나눈 두 칸 <설정이름><탭><값> 으로 적으세요. 순서는 chunk_idle_period, chunk_target_size, max_chunk_age 이고 값은 서버가 찍어 준 그대로입니다.
ingester: 블록에 있습니다. /config 출력이 길면 grep -n 으로 줄 번호를 먼저 찾고 sed -n 으로 그 근처만 보세요. 같은 이름이 다른 블록에도 나올 수 있으니 어느 블록의 값인지 확인해야 합니다.
색인에는 무엇이 남았나
플러시가 끝난 지금 색인에 어떤 스트림이 있는지 series API 로 확인해 /root/lk-chunks/06-series.txt 에 두 줄로 적으세요 — streams=<정수> 와 apps=<app 라벨 값들을 쉼표로, 사전순>. 조회 구간은 기준 시각에서 과거 일곱 시간으로 주세요. 8단계에서 만들 revive 스트림은 세지 않습니다(이 단계에서는 아직 없습니다).
/loki/api/v1/series 에 match[]={app=~".+"} 와 start·end 를 줍니다. 구간을 안 주면 기본값이 최근 몇 시간이라 과거 스트림이 빠집니다 — 그것 자체가 이 실습이 말하는 함정과 같은 종류입니다.
응용 ① — 같은 신고를 받았을 때의 점검 순서
/root/lk-chunks/runbook.txt 에 네 줄을 적으세요. 각 줄은 1. 부터 4. 로 시작하고, 각 줄에는 실제로 칠 수 있는 확인 명령이나 확인할 값이 하나씩 들어가야 합니다. 주제는 "과거 구간의 로그가 비어 보인다" 는 신고를 받았을 때의 점검 순서입니다. 네 줄을 합쳐 공백을 뺀 글자가 120자 이상이어야 합니다.
이 실습에서 실제로 쓴 것들을 순서대로 떠올리면 됩니다 — 접수됐는지, 어느 경로가 답하는지, 저장소에 내려갔는지, 설정이 어떻게 되어 있는지. 남이 새벽에 읽고 따라 할 수 있게 명령을 그대로 적으세요.
응용 ② — 여섯 시간 전 줄 하나를 보이게 만든다
본문에 revive-check 라는 낱말이 든 줄 하나를 라벨 {"app":"revive"} 로 기준 시각에서 여섯 시간 전에 넣고, 질의로 보이게 만든 뒤 그 줄의 본문을 /root/lk-chunks/08-revive.txt 에 한 줄로 적으세요. 본문의 나머지 내용은 자유입니다.
앞 단계에서 한 일을 순서대로 다시 하면 됩니다 — 넣고, 저장소로 내리고, 그 시각을 가운데 두는 구간으로 묻기. 질의가 빈 결과를 내면 아직 한 단계가 남은 것입니다.