Files
obsidian/history/2026-06-01-longhorn-snapshot-retention-fix.md
kaffa fbb3506643 history: Longhorn sftpgo corruption loop 해소 + snapshot 자동 retention 영구 수정
- sftpgo replica kr1 13분 주기 corruption loop → kr2 anti-affinity reschedule로 해소
- root cause: snapshot .checksum 누락 + chain meta 손상 (디스크 정상)
- 시스템 차원 발견: 906/906 snapshot이 recurring-job 라벨 누락
- snapshot 일괄 정리 906 → 194 (volume당 7~8개)
- RecurringJob 4개 spec.labels patch — 자동 retention 영구 수정
- 후속: ArgoCD/IaC 매니페스트 반영 필요
2026-06-01 11:38:19 +09:00

6.3 KiB

date, topic, areas, tags
date topic areas tags
2026-06-01 Longhorn sftpgo replica corruption loop 해소 + 시스템 차원 snapshot 자동 retention 영구 수정 (RecurringJob 라벨 누락)
infra/k3s
infra/storage/longhorn
history
longhorn
k3s
sftpgo
snapshot
recurring-job
retention

2026-06-01 / Longhorn snapshot retention 시스템 차원 수정

시작 — sftpgo replica corruption loop

Longhorn UI에 "Warning". 진단 결과 sftpgo/sftpgo PVC(1Gi, 실사용 50MB)의 kr1 replica가 13분 주기로 Detected corrupted replica tcp://10.42.1.189:... 마킹 → rebuild → 또 마킹 무한 반복.

항목
영향 PVC sftpgo/sftpgo
Replica 분포 kr1() / hp1() / hp2() — 3-way
Corruption 마킹 출처 longhorn-manager engine controller
발생 간격 ~13분 (rebuild 끝나자마자 또 fault)
영향 워크로드 sftpgo (실서비스 영향 0, 자동 rebuild로 데이터 0 손실)

진단 — kr1 디스크는 정상

점검 결과
kr1 dmesg (err/warn) I/O 에러 0, NVMe 에러 0, ext4 에러 0. systemd-sysv 잡소리만
kr1 디스크 용량 nvme0n1 28% (247G/937G), /var/lib/longhorn 114G — 여유 충분
kr1 uptime 30일, 최근 재기동 없음
kr1 위 다른 replica 18개 전부 running — 디스크 자체 정상
iSCSI 5/27 SCSI reset 1회 무관

하드웨어 이슈 아님. Longhorn chain 레벨의 메타데이터 손상 의심.

Root cause 추적

instance-manager-kr2 (rebuild 시) 로그에서 핵심 단서:

level=error msg="Failed to get recorded metadata for file volume-snap-snapshot-...img"
error="failed to open checksum file: ...img.checksum: no such file or directory"

= snapshot의 .checksum 파일이 source 측에 누락. snapshot-data-integrity(fast-check)가 checksum 기반으로 비교하는데 일부 snapshot에 checksum 부재 → integrity check fail → "corrupted" 마킹 → rebuild → 같은 chain을 source에서 받음 → 또 fail → 루프.

sftpgo만의 특별한 원인은 없음 (다른 25개 volume도 더 많은 snapshot 보유, 같은 환경). 우연한 chain 메타 손상이 first cause, integrity check가 루프 증폭.

해소 절차

  1. Volume의 orphan recurring-job-group.longhorn.io/default=enabled 라벨 제거 (정의 안 된 group)
  2. kr1 replica r-750f60ae 명시적 삭제
  3. → Longhorn anti-affinity가 kr1을 회피해 kr2에 새 replica r-4cee3e8e 생성
  4. fresh chain을 hp1에서 sync → 39 snapshot 모두 새로 받음
  5. Volume robustness: degraded → healthy, RW 3-replica 안정화
  6. 2분 post-healthy 관찰 — 재발 0

시스템 차원 이슈 발견 — snapshot 자동 retention 깨짐

별건 점검에서 전체 906개 snapshot 모두 recurring-job.longhorn.io/<job-name> 라벨이 없음. 1시간 전 만든 신규 snapshot도 동일.

항목 데이터
전체 snapshot 906개
recurring-job.longhorn.io/* 라벨 보유 0개 (100% 누락)
Longhorn 버전 v1.11.2
RecurringJob spec.labels {} (4개 모두 비어있음) ← 원인

Longhorn RecurringJob retention 메커니즘:

  • RecurringJob이 만든 snapshot에 자기 라벨(recurring-job.longhorn.io/<job-name>=enabled) 부착
  • retention 시 그 라벨로 자기 소속 snapshot 식별 → retain 개수 외 삭제

spec.labels가 비어 있으면 snapshot에 라벨 안 붙음 → retention 동작 불가 → 모든 RecurringJob snapshot이 무한 누적. 알려진 동작 (명시 안 하면 자동 안 붙임).

정리 — snapshot 906 → 194

각 volume에서 volume-head + 최신 7개 chain만 유지하고 나머지 일괄 delete (kubectl delete snapshot.longhorn.io). Longhorn finalizer가 chain coalesce 자동 처리.

지표 Before After
전체 snapshot 906 194
volume당 평균 ~35 7~8
Volume robustness 26 healthy 26 healthy (변동 0)
데이터 영향 0 (backup은 S3에 별도 보관)

영구 수정 — RecurringJob 라벨 정책 patch

4개 RecurringJob에 자기 라벨을 spec.labels로 명시:

for j in critical-snapshot critical-backup standard-snapshot standard-backup; do
  kubectl -n longhorn-system patch recurringjob.longhorn.io $j --type=merge \
    -p "{\"spec\":{\"labels\":{\"recurring-job.longhorn.io/$j\":\"enabled\"}}}"
done

다음 cron 실행부터 새 snapshot에 라벨 붙음 → retention 자동 동작 시작.

Job spec.labels (After)
critical-snapshot recurring-job.longhorn.io/critical-snapshot: enabled
critical-backup recurring-job.longhorn.io/critical-backup: enabled
standard-snapshot recurring-job.longhorn.io/standard-snapshot: enabled
standard-backup recurring-job.longhorn.io/standard-backup: enabled

검증 (예정)

다음 critical-snapshot 실행 (매시간 정각) 후:

kubectl -n longhorn-system get snapshots.longhorn.io --sort-by=.metadata.creationTimestamp -o json \
  | jq -r '.items[-3:] | .[] | "\(.metadata.creationTimestamp) \(.metadata.name) \(.metadata.labels)"'

→ 새 snapshot에 recurring-job.longhorn.io/critical-snapshot=enabled 있으면 OK.

잔여 사항 / 후속

  • RecurringJob 4개 spec.labels 수동 patch만 적용. ArgoCD/IaC 매니페스트에도 같은 변경 반영 필요 (다음 sync에서 빈 spec.labels로 되돌아갈 위험)
  • snapshot .checksum 파일 누락 패턴은 Longhorn 알려진 이슈일 가능성 — GitHub issue 검색 후 v1.11.3+ 업그레이드 시 해소되는지 확인 필요
  • 같은 corruption loop가 다른 volume에서 재발 시 동일 절차 (anti-affinity 활용한 노드 회피 rebuild) 적용 가능

운영 메모

  • 로컬 Mac Tailscale 데몬이 작업 중 멈춤(Tailscale is stopped., 버전 mismatch 1.98.1 vs 1.96.5 의심). LAN 192.168.9.214 직접 접근으로 우회.
  • 작업 중 임시 kubectl wrapper /tmp/kk: kubectl --server=https://192.168.9.214:6443 --insecure-skip-tls-verify=true (Tailscale 복구 후 폐기)
  • 헤임달(10.100.3.108)은 작업 초반 진단만 위임, snapshot 정리는 kappa 직접 수행 (헤임달은 ops-agents 키가 kr1 sshd에 미등록이라 SMART 등 직접 진단 불가)

수행: kappa (직접) + ../ops-agents/heimdall/_index (초기 카테고리 진단)