From 818d25ea91b42746075d7d1f62df3a5b9b811788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Sat, 8 Aug 2026 05:21:24 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20Alloy=20storage(positions)=EB=A5=BC?= =?UTF-8?q?=20=ED=98=B8=EC=8A=A4=ED=8A=B8=20=EB=B3=BC=EB=A5=A8=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=98=81=EC=86=8D=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 매 배포의 rm -f 재기동이 컨테이너 내부 positions 를 유실해, 새 수집기가 떠 있는 앱 컨테이너 로그를 처음부터 재전송했다. 도착 시점 40분을 넘긴 라인은 Grafana Cloud 가 __time_shard__ 스트림으로 받아 원본과 별개로 저장돼 로그가 약 1.4배 중복됐다(2026-08 core 실측) - 고정 경로 /var/lib/piki-alloy/data 를 /var/lib/alloy/data 로 마운트하고 --storage.path 를 명시. 미지정 기본값이 CWD 상대(data-alloy/)라 이미지 내부 구조에 묶이기 때문 - 컨테이너가 root 로 돌아(실측 uid=0) chown 은 두지 않았다 --- blocks/alloy/provision-alloy.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/blocks/alloy/provision-alloy.sh b/blocks/alloy/provision-alloy.sh index e212c11..0dac09e 100755 --- a/blocks/alloy/provision-alloy.sh +++ b/blocks/alloy/provision-alloy.sh @@ -112,6 +112,16 @@ INSTALLED="$INSTALL_DIR/config.alloy" $SUDO mkdir -p "$INSTALL_DIR" $SUDO cp "$CONFIG" "$INSTALLED" +# ── 데이터 경로 (positions 영속화) ── +# 읽기 위치(loki.source.docker 의 positions.yml)는 storage.path 밑에 쌓인다. 컨테이너 안에만 두면 +# 아래 rm -f 재기동마다 위치가 유실돼, 새 수집기가 떠 있는 앱 컨테이너의 로그를 처음부터 재전송한다 +# — 도착 시점에 40분(time_sharding_ignore_recent) 넘게 지난 라인은 Grafana Cloud 가 __time_shard__ +# 스트림으로 받아 원본과 별개로 저장돼 중복이 된다(2026-08 core 로그 실측 약 1.4배). config 와 같은 +# 이유로 재부팅에도 남는 고정 경로에 둔다. --storage.path 를 명시하는 이유: 미지정 시 기본값이 CWD +# 상대(data-alloy/)라 이미지 내부 구조(작업 디렉터리)에 묶여 마운트 대상이 흔들린다. +DATA_DIR="/var/lib/piki-alloy/data" +$SUDO mkdir -p "$DATA_DIR" + # ── (재)기동 ── # --network host: 앱 포트가 127.0.0.1 바인딩이라 호스트 루프백으로 scrape 하고, host-gateway 로 들어오는 # 앱 OTLP push 를 받는다. 마운트: docker.sock(컨테이너 SD)·/proc·/sys·/(호스트 메트릭). :ro 로 읽기 전용. @@ -119,6 +129,7 @@ echo "run: $IMAGE (name=$NAME, network=host, listen=$LISTEN_ADDR)" docker rm -f "$NAME" >/dev/null 2>&1 || true docker run -d --name "$NAME" --restart unless-stopped --network host \ -v "$INSTALLED":/etc/alloy/config.alloy:ro \ + -v "$DATA_DIR":/var/lib/alloy/data \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /proc:/host/proc:ro,rslave \ -v /sys:/host/sys:ro,rslave \ @@ -133,7 +144,7 @@ docker run -d --name "$NAME" --restart unless-stopped --network host \ -e GRAFANA_TRACES_USER="$TRACES_USER" \ -e GRAFANA_CLOUD_TOKEN="$CLOUD_TOKEN" \ "$IMAGE" \ - run --server.http.listen-addr="$LISTEN_ADDR" /etc/alloy/config.alloy >/dev/null + run --server.http.listen-addr="$LISTEN_ADDR" --storage.path=/var/lib/alloy/data /etc/alloy/config.alloy >/dev/null # ── 기동 확인 ── # 즉시 죽는 config/런타임 오류를 잡는다. validate 를 통과해도 런타임에서 죽을 수 있으니 실제 상태를 본다. From 902dce30a4a75d3e36c3b6ae73828df908d61aea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A1=B0=EC=9E=AC=EC=A4=91?= <126754298+m-a-king@users.noreply.github.com> Date: Sun, 9 Aug 2026 11:06:45 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20Alloy=20=EA=B5=90=EC=B2=B4=20?= =?UTF-8?q?=EC=A0=84=20docker=20stop=20=EC=9C=BC=EB=A1=9C=20=EC=A0=95?= =?UTF-8?q?=EC=83=81=20=EC=A2=85=EB=A3=8C=EB=A5=BC=20=EC=8B=9C=EB=8F=84?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rm -f 단독은 SIGKILL 이라 positions 마지막 sync(10s 주기) 이후 오프셋과 loki.write 미전송 배치가 유실된다. stop(timeout 15s)이 종료 flush 를 보장하고 rm -f 는 fallback 으로 남긴다 - CodeRabbit 리뷰 수용 --- blocks/alloy/provision-alloy.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/blocks/alloy/provision-alloy.sh b/blocks/alloy/provision-alloy.sh index 0dac09e..f806268 100755 --- a/blocks/alloy/provision-alloy.sh +++ b/blocks/alloy/provision-alloy.sh @@ -126,6 +126,10 @@ $SUDO mkdir -p "$DATA_DIR" # --network host: 앱 포트가 127.0.0.1 바인딩이라 호스트 루프백으로 scrape 하고, host-gateway 로 들어오는 # 앱 OTLP push 를 받는다. 마운트: docker.sock(컨테이너 SD)·/proc·/sys·/(호스트 메트릭). :ro 로 읽기 전용. echo "run: $IMAGE (name=$NAME, network=host, listen=$LISTEN_ADDR)" +# 교체 전 정상 종료 우선 — rm -f 단독은 SIGKILL 이라 positions 의 마지막 sync(10s 주기) 이후 +# 오프셋과 loki.write 미전송 배치가 유실된다. stop 이 종료 flush(positions 저장·배치 전송)를 +# 보장하고, rm -f 는 stop 실패·잔재 정리의 fallback 으로 남긴다. +docker stop --timeout 15 "$NAME" >/dev/null 2>&1 || true docker rm -f "$NAME" >/dev/null 2>&1 || true docker run -d --name "$NAME" --restart unless-stopped --network host \ -v "$INSTALLED":/etc/alloy/config.alloy:ro \