Files
obsidian/infra/platform/longhorn.md

8.5 KiB

title, updated, tags
title updated tags
Longhorn 분산 블록 스토리지 2026-05-07
infra
platform
longhorn
storage
k3s

개요

Longhorn은 K3s 클러스터의 분산 블록 스토리지. 각 노드 로컬 NVMe에 replica 분산 저장, CSI 드라이버로 PV/PVC 공급. 기본 StorageClass longhorn (default), 정적 복구용 longhorn-static.

항목
Helm release longhorn (ns longhorn-system)
Chart / App longhorn-1.11.2 / v1.11.2
노드 incus-kr1, incus-kr2, incus-hp1, incus-hp2 (4)
Data engine v1 (v2 미사용)
Default data path /var/lib/longhorn/
Default replica count 2 ({"v1":"2","v2":"2"})
Default SC longhorn — WaitForFirstConsumer 아님, Immediate / ReclaimPolicy Delete / ExpansionAllowed true
정적 복구 SC longhorn-static (Volume CR 경유 복구 시)
Backup target s3://longhorn-backup@auto/ (Cloudflare R2) — [[../data/k3s-backup

컴포넌트 (helm rev 6 기준)

컴포넌트 종류 이미지
longhorn-manager DaemonSet longhorn-manager:v1.11.2 + longhorn-share-manager:v1.11.2
longhorn-csi-plugin DaemonSet csi-node-driver-registrar:v2.16.0, livenessprobe:v2.18.0, longhorn-manager:v1.11.2
longhorn-driver-deployer Deployment (1) longhorn-manager:v1.11.2
longhorn-ui Deployment (2) longhorn-ui:v1.11.2
csi-attacher / provisioner / resizer / snapshotter Deployment (3 replicas each) csi-attacher:v4.x, csi-provisioner:v5.x, csi-resizer:v1.x, csi-snapshotter:v8.x
engine-image DaemonSet (per-version) longhorn-engine:v1.11.2 (ei-c9fa6d45). 신규 EI 적용 후 모든 25 볼륨 live engine upgrade 완료, 구 EI ei-75a03ec3 (v1.11.1) 는 refcount 0 으로 자동 정리 대기
instance-manager per-node per-version longhorn-instance-manager:v1.11.2

Helm values (커스텀)

defaultSettings:
  nodeDownPodDeletionPolicy: delete-both-statefulset-and-deployment-pod
  nodeDrainPolicy: always-allow
  replicaAutoBalance: best-effort
  • nodeDownPodDeletionPolicy: 노드 다운 시 StatefulSet / Deployment 파드 양쪽 모두 강제 삭제하여 PV 재attach 허용
  • nodeDrainPolicy: always-allow: kubectl drain 시 볼륨 attach 여부 무관하게 허용
  • replicaAutoBalance: best-effort: 노드 간 replica 분포 자동 밸런싱 시도

UI

볼륨 운영

  • 기본 PVC 생성: StorageClass longhorn (default)
  • 백업/복구·라벨 기반 recurring job: ../data/k3s-backup
  • 복구 시 주의: longhorn.io/fromBackup annotation은 Longhorn v1.8+ CSI에서 무시됨 → Volume CR 직접 생성 후 longhorn-static SC PV 만드는 절차. 상세 ../data/k3s-backup
  • 주기 백업 라벨 키는 대시 포함: recurring-job-group.longhorn.io/<group>=enabled (과거 오타 이슈 ../../history/2026-04-15-longhorn-backup-label-typo)

Stuck snapshot 임시 cron (v1.11.1 워크어라운드 — 회수 대상)

상태 (2026-05-07): v1.11.2 업그레이드로 fix 적용됨 — 업그레이드 직후 stuck CR 12개 자연 cleanup, 23:00 UTC RecurringJob 사이클부터 신규 Warning 0건. 임시 cron 은 회수 대상. ArgoCD longhorn-snapshot-purge Application 만 삭제, chart 디렉토리는 repo 보존 (재현 시 재활용 가능).

v1.11.1 instance-manager 재시작 후 일부 snapshot CR 이 status.markRemoved=true && status.readyToUse=false && status.ownerID="" 상태로 멈췄다. ownerId 가 비어 longhorn-manager 가 reconcile 못 했고, 수동 kubectl delete / finalizer patch 시 admission webhook 이 finalizer 를 즉시 재추가해 정리 불가했다.

근본 fix 는 v1.11.2 백포트 #12856. 그 전까지 임시로 snapshotPurge API 를 cron 으로 자동 호출해 engine 단 chain cleanup 을 주기 트리거했다.

구성

항목
Helm chart gitea.inouter.com/kaffa/helm-charts · charts/longhorn-snapshot-purge
ArgoCD App argocd/longhorn-snapshot-purge (auto-sync, prune, selfHeal)
CronJob longhorn-system/longhorn-snapshot-purge
Schedule */30 * * * *
ServiceAccount longhorn-snapshot-purge (ns Role: snapshots.longhorn.io get/list)
Image alpine/k8s:1.32.1 (kubectl + curl + jq 포함)

동작

  1. namespace 내 snapshots.longhorn.io 전수 list
  2. status.markRemoved=true 이면서 status.readyToUse=false 인 CR 추출 → spec.volume 중복 제거
  3. 각 volume 에 POST http://longhorn-frontend.longhorn-system.svc/v1/volumes/{name}?action=snapshotPurge 호출
  4. HTTP 200 / 비-200 별 카운트, 비-200 있으면 job exit 1

한계 / 운영 주의

  • snapshotPurge 는 chain 의 redundant snapshot 만 정리. stuck snapshot 이 그 볼륨의 유일 snapshot 이고 volume-head 의 직속 parent 라면 .img 파일이 정리되지 않는다 (engine snapshotList 에서 removed=true 만 마킹 유지).
  • 따라서 cron 은 디스크 재확보의 best-effort. CR 자체 cleanup 은 보장 안 됨 — 그건 v1.11.2 / v1.12 업그레이드로 해결.
  • 임시 cron 이라 업그레이드 직후 ArgoCD App 삭제로 회수할 것 (chart 디렉토리는 repo 에 보존하되 Application 만 prune).

운영 명령

# 수동 트리거 (다음 30분 boundary 기다리지 않을 때)
kubectl -n longhorn-system create job --from=cronjob/longhorn-snapshot-purge longhorn-snapshot-purge-manual-$(date +%s)

# 마지막 실행 로그
kubectl -n longhorn-system logs -l job-name --tail=50 --selector='batch.kubernetes.io/job-name'

# stuck snapshot 현재 카운트
kubectl get snapshots.longhorn.io -A -o json | jq '[.items[] | select(.status.markRemoved == true and .status.readyToUse == false)] | length'

상세 도입 기록: ../../history/2026-05-02-longhorn-snapshot-purge-cron / ../../history/2026-05-07-longhorn-1-11-2-upgrade

업그레이드 절차 (표준)

minor skip 금지 — 한 단계씩 순차. 각 단계 공통:

  1. Pre-check: 볼륨 healthy/attached, backup target available, ongoing snapshot 없음, 4노드 Ready
  2. helm upgrade longhorn longhorn/longhorn -n longhorn-system --version <x.y.z> --reset-then-reuse-values
  3. longhorn-manager DS 롤링 대기
  4. 신규 engine-image DS 4/4 state=deployed 확인
  5. 모든 볼륨 spec.image 를 신규 engine image 로 일괄 패치 (live engine upgrade, v1 data engine)
  6. status.currentImage 전수 확인
  7. 구 engine-image CR refcount=0 확인 — Longhorn 자동 정리 대상

구 engine-image CR 과 구 instance-manager pod 는 refcount 0 확인 후 manager가 자동 정리 (기본 timeout ~10분). 수동 삭제 불필요.

최근 버전 변경

2026-05-07: 1.11.1 → 1.11.2 (patch, snapshot warning 회귀 fix)

단계 Helm rev Chart 결과
1.11.1 → 1.11.2 6 longhorn-1.11.2 25/25 볼륨 healthy
  • 백포트 #12856 적용 — snapshot becomes not ready to use Warning 사이클 해소
  • 업그레이드 직후 stuck CR 12개 자연 cleanup (manager ownership reset 흐름 회복)
  • 35분 관측 동안 신규 Warning 0건, 23:00 UTC critical-snapshot RecurringJob 사이클 통과
  • 신규 EI ei-c9fa6d45 (v1.11.2), 25 볼륨 모두 live engine upgrade 완료
  • 상세: ../../history/2026-05-07-longhorn-1-11-2-upgrade

2026-04-23: 1.8.2 → 1.11.1 (3단계 minor 순차)

단계 Helm rev Chart 결과
1.8.2 → 1.9.2 3 longhorn-1.9.2 27/27 볼륨 healthy
1.9.2 → 1.10.2 4 longhorn-1.10.2 27/27 볼륨 healthy
1.10.2 → 1.11.1 5 longhorn-1.11.1 27/27 볼륨 healthy
  • 전 단계 live engine upgrade (v1 data engine만 사용 중이라 가능)
  • 전 단계 무중단 — attached 25 + detached 2(safeline) 볼륨 전수 신규 엔진 이미지로 이행
  • 각 단계 breaking change 없음 (공식 릴리스 노트 기준)
  • 상세 로그·검증 스냅샷: Outline heimdall/2026-04-23 Longhorn 업그레이드 (id 750faea0-6720-4e27-b219-0942247d53aa)

관련 문서