Files
obsidian/history/2026-05-02-longhorn-snapshot-purge-cron.md

5.1 KiB
Raw Permalink Blame History

date, topic, areas
date topic areas
2026-05-02 Longhorn stuck snapshot cleanup workaround
infra/platform/longhorn

2026-05-02 / Longhorn snapshot-purge cron 도입

배경

Longhorn v1.11.1 에서 instance-manager 재시작(2026-05-02 09:00 UTC 즈음) 후 12개 snapshot CR 이 다음 패턴으로 stuck:

  • status.markRemoved = true
  • status.readyToUse = false
  • status.ownerID = ""
  • metadata.finalizers = ["longhorn.io"]

ownerID 가 비어 longhorn-manager controller 가 이 CR 들을 reconcile 하지 않음. 수동 kubectl delete / finalizer patch 는 admission webhook(admission.go:115) 이 즉시 finalizer 를 다시 추가해 무력화.

근본 원인은 v1.11.1 의 ownerId-loss 회귀로 추정. 1.11.2 / 1.12 에서 fix 예상. 임시로 snapshotPurge API 를 cron 으로 주기 호출.

stuck 12개 식별

pvc-0440758f-f056-46d0-9733-dbb77f2e9101  (snapshot 1e632239-...)
pvc-15af4f6d-6129-4858-ae51-a3aa3546c4c2  (snapshot d95f165a-...)
pvc-384dd143-05b6-4cd6-a0dd-3edf5dca3acc  (snapshot a8f0cbfd-...)
pvc-3c39ef90-d8ea-402d-8363-772ddbaf56a2  (snapshot 8f80ed9d-...)
pvc-411b3be5-ce8f-4039-a73e-d9b1e61a07de  (snapshot 545f2ca5-...)
pvc-4d4cb56b-7be8-43ac-80be-5367cacd625a  (snapshot 26dbf46f-...)
pvc-573db32c-f3fa-494e-8e1f-9f899938ec40  (snapshot 300158d8-...)
pvc-8534d9f3-91b9-49c3-9acd-804581c51893  (snapshot ef714f28-...)
pvc-8f9bfed6-236d-49d3-94d9-41880c351059  (snapshot b700b4d7-...)
pvc-bc38d860-0bc5-4b49-ab19-2586e0f78515  (snapshot 2581dac8-...)
pvc-c702c67d-7c5d-47d5-8814-b13fff45cbe7  (snapshot d43c685b-...)
pvc-f4b8b3b4-1a51-45a7-a460-422f9fca023f  (snapshot cd9c36a3-...)

12 snapshot ↔ 12 volume (1:1).

도입 단계

Chart 작성 + push

gitea.inouter.com/kaffa/helm-charts · charts/longhorn-snapshot-purge/ 생성.

  • Chart.yaml: name longhorn-snapshot-purge, version 0.1.0
  • values.yaml: schedule */30 * * * *, image alpine/k8s:1.32.1, longhornFrontendUrl http://longhorn-frontend.longhorn-system.svc.cluster.local
  • templates/serviceaccount.yaml: SA longhorn-snapshot-purge
  • templates/role.yaml: Role + RoleBinding (snapshots.longhorn.io get/list, ns-scoped)
  • templates/cronjob.yaml: CronJob with kubectl + curl shell script

commit: 0edf886 Add longhorn-snapshot-purge chart for stuck snapshot cleanup fix commit: d75c9a6 longhorn-snapshot-purge: query in-namespace to match Role scope (-A-n longhorn-system — RBAC scope mismatch 수정)

ArgoCD Application 생성

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: longhorn-snapshot-purge
  namespace: argocd
spec:
  destination: { namespace: longhorn-system, server: https://kubernetes.default.svc }
  project: default
  source:
    path: charts/longhorn-snapshot-purge
    repoURL: https://gitea.inouter.com/kaffa/helm-charts.git
    targetRevision: HEAD
  syncPolicy:
    automated: { prune: true, selfHeal: true }

Synced/Healthy 도달.

수동 트리거 검증

kubectl -n longhorn-system create job --from=cronjob/longhorn-snapshot-purge \
  longhorn-snapshot-purge-manual-2

[2026-05-02T06:14:55Z] longhorn-snapshot-purge starting
stuck snapshot owner volumes (deduped): 12
ok  pvc-0440758f-... (HTTP 200)
ok  pvc-15af4f6d-... (HTTP 200)
ok  pvc-384dd143-... (HTTP 200)
ok  pvc-3c39ef90-... (HTTP 200)
ok  pvc-411b3be5-... (HTTP 200)
ok  pvc-4d4cb56b-... (HTTP 200)
ok  pvc-573db32c-... (HTTP 200)
ok  pvc-8534d9f3-... (HTTP 200)
ok  pvc-8f9bfed6-... (HTTP 200)
ok  pvc-bc38d860-... (HTTP 200)
ok  pvc-c702c67d-... (HTTP 200)
ok  pvc-f4b8b3b4-... (HTTP 200)
[2026-05-02T06:15:03Z] longhorn-snapshot-purge done (rc=0)

snapshotPurge 12/12 HTTP 200. job 8 초 내 완료 (rc=0).

snapshotPurge 한계 확인

POST snapshotList 로 첫 stuck volume 의 engine snapshot 상태 검사:

{"data":[
  {"id":"volume-head", "parent":"1e632239-...", "removed":false},
  {"id":"1e632239-...", "parent":"", "removed":true, "size":"51265536"}
]}
  • 1e632239-... 가 chain 의 유일 snapshot, volume-head 의 직속 parent
  • removed=true 마킹은 됐으나 .img 파일은 미정리 (chain merge 대상 없음)
  • snapshotPurge 는 chain 중간의 redundant snapshot 만 합치므로 leaf snapshot 은 정리 불가
  • 따라서 stuck snapshot CR 12 → 12 그대로 (5분 대기 후 재확인)

결론

  • cron 은 사용자 요건 (3) "snapshotPurge API 매 30분 자동 호출" 을 정확히 수행
  • engine 의 chain redundancy 가 발생하면 정리 — 향후 같은 볼륨에 추가 snapshot 이 쌓일 때 효과
  • 단일 leaf stuck snapshot 들은 v1.11.2 / v1.12 업그레이드로 manager 가 reconcile 회복할 때까지 그대로 잔존
  • 디스크 사용량은 12 × ~50MiB ≈ 600MiB 수준 — 운영 임팩트 무시 가능
  • 향후 새 stuck 이 생기더라도 cron 이 자동 처리

후속

  • v1.11.2 또는 v1.12 출시 → 표준 minor 순차 업그레이드 절차로 진행
  • 업그레이드 완료 후 kubectl -n argocd delete application longhorn-snapshot-purge 로 cron 회수 (chart 디렉토리는 repo 에 보존)
  • 만약 disk 회수가 시급한 stuck 이 발생하면 ownerID 강제 부여 patch + delete 흐름 도입 검토 — admission webhook 우회 필요해 별도 작업