본문으로 건너뛰기

스토리지 토폴로지

GenD는 블록 스토리지(PVC)객체 스토리지(S3 API) 를 이원화하여 운영합니다. dev(Kind)와 prod(AKS)는 백엔드만 다르고 동일한 S3 API 추상화 레이어(datax-s3-config ConfigMap + Secret) 를 공유하므로 애플리케이션 코드 변경 없이 환경 전환이 가능합니다.

토폴로지

환경별 매핑

용도dev (Kind)prod (AKS)
블록 PVClocal-path-provisionermanaged-csi-tagged (Ceph RBD + LUKS + Vault Transit)
객체 (S3)SeaweedFS 3.80Ceph RGW + SSE-KMS
DB (PostgreSQL)StatefulSet PVCStatefulSet PVC (Managed DB 미사용 — 자체 운영 확정)
인증서 키self-signedcert-manager + Let's Encrypt

PVC 카탈로그

워크로드크기모드비고
vault1GiRWORaft state
kafka-N × 310GiRWOper-broker
opensearch(동적)RWO감사 로그
prometheus(동적)RWO메트릭 TSDB
seaweedfs-data100Gi (prod)RWO논리 상한은 아래 §SeaweedFS 용량 참조

SeaweedFS 용량 — 디스크가 아니라 볼륨 슬롯이 상한이다

:::danger 실제 저장 가능량 = volume.max × master.volumeSizeLimitMB PVC 크기가 아니라 이 곱이 상한이다. 초과하면 마스터가 No writable volumes and no free volumes leftPUT 을 거부한다 — 디스크에 여유가 아무리 많아도 그렇다. :::

2026-07-31 장애 (#2784): volume.max=20 × 1024 MB = 20 GiB 하드 상한에 도달해 Iceberg 쓰기가 약 30시간 100% 실패했다. 그때 디스크 사용률은 20% 였다 (98 GiB 중 20 GiB). #630 이 PVC 를 20Gi→100Gi 로 늘렸지만 volume.max 를 20 그대로 두어, 늘린 용량의 80% 를 구조적으로 쓸 수 없는 상태였다.

공식 이미지의 entrypoint 가 server 모드에 아래를 강제 주입한다 — 매니페스트에 없다고 기본값이 아니다:

weed -logtostderr=true server -dir=/data \
-master.volumePreallocate -master.volumeSizeLimitMB=1024 ...

확인: kubectl exec deploy/seaweedfs -c seaweedfs -- cat /proc/1/cmdline | tr '\0' ' '

매니페스트 args 는 그 뒤에 붙으므로, 같은 플래그를 다시 지정하면 Go flag 의 "나중 값 우선" 규칙으로 덮어쓸 수 있다. 현재 prod 설정은 volume.max=40 × volumeSizeLimitMB=2048 = 80 GiB (98 GiB 파일시스템의 81%).

점검 방법

# Free=0 이면 슬롯 고갈. 컬렉션별 writables 가 [] 이면 그 컬렉션은 쓰기 불가.
kubectl exec deploy/seaweedfs -c seaweedfs -- \
wget -qO- "http://$(kubectl get pod -l app=seaweedfs -o jsonpath='{.items[0].status.podIP}'):9333/dir/status"

Topology.Free == 0임박, 어떤 컬렉션의 writables == []이미 장애다.

:::warning preallocate 가 켜져 있다 볼륨 1개 생성 = 즉시 volumeSizeLimitMB 만큼 디스크 점유(fallocate). 두 값을 올릴 때는 반드시 곱이 파일시스템 크기 이하인지 재계산할 것 — 넘으면 ENOSPC 다. :::

운영 주의

  • SeaweedFS 용량 알람 (#2793): PVC 사용률 알람으로는 이 장애를 원리적으로 잡을 수 없다 (장애 당시 20%). Topology.Free 와 컬렉션별 writables 를 봐야 한다 (#2784). infra/monitoring/prometheus-rules/seaweedfs.yaml 이 위 exporter 메트릭을 근거로 4종을 감시한다.

    • SeaweedFSCollectionNotWritableseaweedfs_collection_writable_volumes == 0 (critical, 5m). 해당 컬렉션은 이미 PUT 전량 거부 중이다.
    • SeaweedFSVolumeSlotsExhaustedseaweedfs_volume_slots_free == 0 (critical, 5m). 신규 볼륨 생성 불가 — 남은 볼륨이 차는 순간 전체 컬렉션이 쓰기 불가로 전이된다.
    • SeaweedFSVolumeSlotsLow — 슬롯 사용률 80% 초과 (warning, 30m). 컬렉션 첫 grow 가 슬롯 7개를 한 번에 잡으므로 여유 7개 미만은 실질적으로 고갈이다.
    • SeaweedFSExporterDownabsent_over_time(seaweedfs_volume_slots_free[10m]) (critical, 10m). dead-man's switch: 위 3종은 전부 exporter 가 스크레이프되고 있을 때만 발화하므로, exporter 가 죽으면 셋 다 조용히 사라진다. 이 알람이 떠 있는 동안 SeaweedFS 용량 감시는 전면 실명 상태로 취급할 것. up == 0 대신 absent_over_time 을 쓰는 이유는 파드가 Endpoints 에서 빠지면 up 시계열 자체가 사라져 up == 0 이 원리적으로 발화하지 못하기 때문이다.

    대응 절차: 위 "점검 방법" 명령으로 Topology.Free 와 컬렉션별 writables 를 확인한다. 두 critical 알람은 심각도는 같아도 뜻이 다르다 — SeaweedFSCollectionNotWritable 은 해당 컬렉션이 이미 쓰기 불가이므로 즉시 대응한다. SeaweedFSVolumeSlotsExhausted 는 신규 볼륨을 못 만든다는 뜻일 뿐, writable 볼륨이 남은 다른 컬렉션은 아직 정상 이다 — 다만 그 볼륨이 마저 차는 순간 끊기므로 임박으로 보고 신속히 처리한다. SeaweedFSVolumeSlotsLow 는 그보다 앞선 선행 경고다. 조치는 세 경우 공통이다: volume.max 또는 master.volumeSizeLimitMB 를 상향하되(곱이 PVC 용량 이하인지 재계산 — 위 preallocate 경고 참고) kubectl rollout restart deploy/seaweedfs 로 반영한다. exporter 파드가 다운되면 세 알람 모두 못 뜨는 사각지대이므로 파드가 Running 인지도 함께 확인한다.

  • Ceph RGW: SSE-KMS는 datax-ceph-kms Vault Transit 키와 연동 — 키 회전 시 객체 재암호화 정책 확인

  • 백업: Managed DB 미사용 결정에 따라 PostgreSQL은 CronJob 기반 자체 백업 (backup-restore.md 참고)

관련 문서