- 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 매니페스트 반영 필요
6.3 KiB
date, topic, areas, tags
| date | topic | areas | tags | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-06-01 | Longhorn sftpgo replica corruption loop 해소 + 시스템 차원 snapshot 자동 retention 영구 수정 (RecurringJob 라벨 누락) |
|
|
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가 루프 증폭.
해소 절차
- Volume의 orphan
recurring-job-group.longhorn.io/default=enabled라벨 제거 (정의 안 된 group) - kr1 replica
r-750f60ae명시적 삭제 - → Longhorn anti-affinity가 kr1을 회피해 kr2에 새 replica
r-4cee3e8e생성 - fresh chain을 hp1에서 sync → 39 snapshot 모두 새로 받음
- Volume robustness: degraded → healthy, RW 3-replica 안정화
- 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 (초기 카테고리 진단)