Skip to main content

BrickML 스토리지 표준

문서 성격: 제품 표준. BrickML의 영상·이미지 과제(Object Detection / Segmentation)를 지원하는 모든 배포 환경에 적용된다. 상태: 초안 (v0.2) 관련 문서

  • BrickDatasetCache-CRD-설계.md — 데이터셋 캐시 리소스 설계
  • 사이트별 적용 문서 — 사내 한정, 별도 관리

용어가 낯선 경우 부록 A를 먼저 참고할 것.


0. 이 문서의 위치와 용어​

본 문서는 자사가 표준으로 채택하고 지원하는 구성을 정의한다. 스토리지 벤더의 일반 권장 사항과 반드시 일치하지 않으며, 차이가 있는 경우 §5에 이탈 근거를 명시한다.

구분의미
표준 구성자사가 기본으로 채택하며 신규 배포에 적용하는 구성. 지원 범위의 기준선
허용고객사 환경상 표준을 충족할 수 없을 때 채택 가능. 감수사항을 문서화하고 진행
비권장채택하지 않는다. 불가피한 경우 감수사항을 고객사와 명시적으로 합의

전제: 폐쇄망 고객사 배포에서는 스토리지 하드웨어를 고객사가 제공한다. 따라서 표준은 "우리가 요구할 수 있는 최소 조건 + 미달 시 감수사항"의 형태를 취한다.

결정 요약​

항목결정상세
MinIO 백엔드블록 스토리지 우선. 파일 프로토콜은 조건부 허용§4-①
MinIO 내구성RAID 또는 MinIO EC 중 하나만. 둘 다 적용하지 않음§4-②
MinIO 가용성단일 인스턴스 + 겹침 방지. 워크로드 종류는 볼륨 프로비저닝 방식에 따라§4-③
분산 MinIO표준 아님. 장애 도메인 분리 조건 충족 시에만 허용§5
Ceph 등 분산 스토리지도입하지 않음§5
업로드 위치처음부터 최종 위치. 임시 영역 경유 후 복사하지 않음§4-⑦
학습 데이터 전달노드 로컬 볼륨에 미리 내려받음. 학습 중 MinIO 직접 읽기 안 함§2
스테이징 실행GPU 미할당 별도 Job§2
스테이징 볼륨local PV. hostPath 사용 금지§4-④
데이터셋 캐시채택. BrickDatasetCache CRD로 관리§4-⑥
노드별 캐시 상태 UI 노출후순위§6

1. 배경​

영상·이미지 과제 도입으로 스토리지 요구사항이 성격이 다른 두 계층으로 분리되었다.

계층성격핵심 지표
MinIO 백엔드원본 데이터셋의 영구 보관내구성, 용량, 정확성
스테이징 볼륨학습 직전 데이터셋 실체화처리량, 지연시간

기존 표준은 스토리지를 단일 계층으로 다루었다. 두 계층을 분리하지 않으면 현장에서 "파일 스토리지면 사용 불가인가" 같은 불필요한 논의가 발생하고, 반대로 성능 요구사항이 실제로 필요한 지점(스테이징)이 누락된다.

범위: 데이터셋 저장·전달 경로. 모델 아티팩트, MLflow 백엔드, 로그 아카이브는 별도 문서에서 다룬다.


2. 아키텍처 전제​

브라우저 ──(presigned PUT)──▶ MinIO: datasets/{datasetId}/
│ 상태: uploading
▼
분석 Job (검증 · 구조 정리)
│
▼
상태: ready ← 이후 변경되지 않음
│
┌──────────┘
▼
스테이징 Job (GPU 미할당)
│
▼
데이터셋 캐시 볼륨 (노드 로컬 PVC)
│
▼
학습 Job (GPU 할당) — 읽기 전용 마운트

업로드 위치는 처음부터 최종 위치(datasets/{datasetId}/)로 한다. 별도 임시 영역에 올린 뒤 옮기는 방식은 채택하지 않는다. 근거는 §4-⑦.

설계 원칙​

  1. 학습 중에는 MinIO를 반복해서 읽지 않는다. 매 에폭 MinIO에서 데이터를 가져오면 GPU가 데이터를 기다리며 놀게 된다. MinIO 접근은 데이터셋당 처음 한 번, 순차 읽기로 제한한다.
  2. 다운로드와 GPU 점유를 분리한다. 파드는 스케줄된 순간부터 GPU를 점유하므로, init container에서 대용량 다운로드를 수행하면 그 시간만큼 GPU가 낭비된다.
  3. 데이터셋은 불변으로 취급한다. 승격된 데이터셋은 변경되지 않으므로 datasetId가 그대로 캐시 키가 된다. 캐시 무효화 로직이 필요 없다.
  4. 캐시 손실은 사고가 아니다. 원본이 MinIO에 있으므로 스테이징 볼륨은 언제든 재생성 가능하다. 정리 정책을 공격적으로 운영해도 안전하다.
  5. 보호 계층은 한 번만 둔다. 백엔드에 RAID가 있으면 MinIO erasure coding은 중복이며, 그 반대도 같다. 이중 보호는 용량을 두 번 깎는다.
  6. 성능 투자는 스테이징 계층에 집중한다. 원칙 1에 따라 MinIO는 병목이 아니다. MinIO 백엔드 개선보다 스테이징 볼륨 확보가 투자 대비 효과가 크다.

왜 업로드 후 별도 검증 단계를 두는가​

업로드가 끝나도 데이터셋이 바로 사용 가능해지지 않는다. 분석 Job이 한 번 실행되어 다음을 수행해야 한다.

  • 파일 수·용량이 기대값과 일치하는지 확인
  • 이미지와 라벨 파일의 짝이 맞는지, 누락이 없는지 검사
  • 이미지 헤더를 읽어 실제 가로·세로 크기 확보 (YOLO 라벨은 비율 좌표만 담고 있어 절대 좌표 복원에 필요)
  • 학습 프레임워크가 기대하는 디렉터리 구조로 정리

이 검증을 통과한 뒤에야 상태가 ready로 바뀌고, 이후 데이터셋은 변경되지 않는다.

학습 실행 모델​

BrickML은 학습 실행 시 사용자가 노드를 직접 선택하며 멀티 노드 GPU 분산 학습을 지원하지 않는다. 따라서 데이터셋 캐시의 노드 고정은 추가 제약이 아니라 제품의 기본 동작과 정합한다.


3. 표준 구성 요약​

축표준 구성허용비권장
① MinIO 백엔드 프로토콜블록 스토리지 (로컬 SSD/NVMe 또는 SAN via CSI), XFS파일 프로토콜 (NFS/SMB) — §4-① 조건 충족 시보호 없는 파일 스토리지
② 백엔드 내구성고객사 스토리지의 RAID에 위임 (MinIO는 단일 드라이브)MinIO EC (4드라이브 이상, 장애 도메인 분리 시)RAID + EC 이중 적용 / 어느 보호도 없음
③ MinIO 토폴로지·가용성단일 인스턴스 + Recreate분산 구성 (§5 조건 충족 시)단일 인스턴스 + RollingUpdate
④ 스테이징 볼륨GPU 노드 전용 디스크 + local PV (RWO)SAN 블록 RWO via CSI파일 프로토콜 RWX / hostPath / OS 디스크 공유
⑤ GPU 노드 RAM데이터셋 크기 이상데이터셋 크기의 절반—
⑥ 데이터셋 캐시 관리BrickDatasetCache CRD + Controller—캐시 없이 실행 단위 재다운로드 (대역폭 충분 시 허용)

4. 축별 상세​

① MinIO 백엔드 프로토콜​

MinIO는 로컬 파일시스템의 POSIX 의미론을 전제로 설계되어 있다. 파일 프로토콜에서의 문제는 디스크 성능이 아니라 파일 락 의미론과 메타데이터 연산이므로, 게이트웨이 뒤에 고성능 어레이가 있어도 개선되지 않는다.

파일 프로토콜 허용 조건 (모두 충족 시)

  • 백엔드에 RAID 등 디스크 보호가 존재
  • hard 마운트 — 네트워크 순단 시 I/O 오류가 MinIO로 전달되면 상태가 어긋날 수 있다
  • 단일 MinIO 인스턴스 (§4-③) — 복수 인스턴스가 같은 경로를 사용하면 데이터가 손상된다
  • 스테이징 계층 구현 완료 — 학습 중 MinIO 반복 읽기 없음
  • 오브젝트 수 모니터링 체계 — 수만 개 초과 시 재검토 (§11)

감수사항

  • MinIO 벤더 권장 구성에서 벗어나며, 장애 시 벤더 지원을 기대할 수 없다. 대응 부담을 자사가 흡수한다
  • 오브젝트 수 증가 시 메타데이터 연산이 병목이 된다. 업로드 검증(ListObjects)도 함께 느려진다

성능 기대치: 동일 네트워크 대역폭이라면 블록과 파일의 대용량 순차 처리량은 유사하다. 블록의 이점은 메타데이터 연산, IOPS, 지연시간, 정확성에 있다. 프로토콜 전환만으로 스테이징 다운로드 시간이 크게 줄어들 것으로 기대하지 않는다.

② 백엔드 내구성​

디스크 장애로부터 데이터를 보호하는 계층이 정확히 하나 있어야 한다.

  • 백엔드에 RAID가 있으면 → MinIO는 단일 드라이브 구성으로 내구성 요구를 충족한다. 표준 구성
  • 백엔드에 보호가 없으면 → MinIO를 4드라이브 이상 분산 구성으로 배포해 EC로 보호한다
  • 둘 다 적용하지 않는다. RAID 위에 MinIO EC를 얹으면 실사용 용량이 raw의 1/4 이하로 떨어진다

장애 도메인 원칙​

동일 스토리지 어레이에서 프로비저닝된 LUN들은 단일 장애 도메인으로 간주하며, 이들 간 erasure coding은 내구성 향상으로 계산하지 않는다.

같은 어레이에서 잘라낸 LUN 4개를 4노드에 붙여 분산 MinIO를 구성해도, 어레이 또는 게이트웨이 장애 시 4드라이브가 동시에 소실되어 EC로 복구할 수 없다. "단일 물리 디스크를 파티션으로 분할하지 않는다"와 동일한 원리이며 단위만 LUN으로 확대된 것이다.

이 경우 분산 구성이 제공하는 것은 내구성이 아니라 가용성뿐이다.

③ MinIO 토폴로지·가용성​

표준은 단일 인스턴스 + Recreate다. 근거는 §5에 정리한다.

RollingUpdate 금지​

MinIO는 백엔드에 대한 배타적 접근을 전제로 동작한다. 두 프로세스가 같은 저장 경로를 동시에 사용하면 데이터가 손상된다. Deployment의 기본 전략은 새 파드를 먼저 띄운 뒤 기존 파드를 종료하므로 업데이트마다 겹치는 구간이 발생한다. 백엔드가 RWX(파일 프로토콜)면 두 파드가 다른 노드에 떠도 모두 마운트가 성공하여 쿠버네티스의 안전장치도 작동하지 않는다.

spec:
replicas: 1
strategy:
type: Recreate # 기존 파드 완전 종료 후 새 파드 생성

추가로 PVC 접근 모드를 ReadWriteOnce로 선언한다. 백엔드가 파일 프로토콜이라도 쿠버네티스가 두 노드 동시 마운트를 스케줄링 단계에서 거부한다.

접근 모드로 중복 기동을 차단한다​

접근 모드는 스토리지가 강제하는 값이 아니라 선언이다. 파일 프로토콜 볼륨을 RWO로 선언하면 쿠버네티스가 두 노드 동시 마운트를 스케줄링 단계에서 거부한다. NFS PV를 의도적으로 RWO로 선언하는 것은 이 목적의 정당한 사용이다.

접근 모드강제 범위MinIO 적합성
ReadWriteMany제한 없음부적합 — 두 파드가 어디서든 같은 경로를 물 수 있다
ReadWriteOnce노드 하나최소 요건. 같은 노드에 두 파드가 뜨는 것은 막지 못한다
ReadWriteOncePod파드 하나가장 적합. 중복 기동을 구조적으로 차단

ReadWriteOncePod을 우선 검토한다. CSI 드라이버 지원이 필요하므로 볼륨 프로비저닝 방식(in-tree, 외부 프로비저너, 벤더 CSI)에 따라 가능 여부가 갈린다. 지원되지 않으면 RWO로 선언한다.

워크로드 종류: Deployment로 충분하다​

필수 요건은 "두 인스턴스가 겹치지 않는 것" 하나이며, Deployment + strategy: Recreate가 이를 충족한다.

StatefulSet은 롤링 업데이트 시 기존 파드를 먼저 종료하므로 겹침 방지가 기본 동작으로 보장된다는 이점이 있다. 그러나:

  • volumeClaimTemplates의 이점은 동적 프로비저닝 환경에서만 성립한다. 기존 정적 PV(파일 프로토콜 볼륨 등)를 사용하려면 storageClassName: ""로 동적 생성을 끄고, 생성될 PVC 이름({templateName}-{statefulSetName}-0)에 맞춰 PV를 미리 준비해야 한다. PV가 하나뿐이면 "파드마다 별도 볼륨"이라는 이점 자체가 없다
  • 향후 분산 구성 전환에 도움이 되지 않는다. 토폴로지는 배포 시점에 고정되며 변경할 수 없다 (§5)
  • 중복 기동 방지는 위의 접근 모드로 처리하는 것이 더 직접적이다

적용 방침

상황방침
기존 배포 (정적 PV)Deployment + Recreate 유지. 전환하지 않는다
신규 배포 (정적 PV)Deployment + Recreate. StatefulSet 선택 가능하나 실익이 작다
신규 배포 (동적 프로비저닝 블록 스토리지)StatefulSet + volumeClaimTemplates 권장
분산 구성StatefulSet 필수 (안정적 파드 이름·DNS가 엔드포인트 목록에 필요)

④ 스테이징 볼륨​

RWX를 요구사항에 포함하지 않는다. 블록 장치 위의 XFS/ext4는 배타적 접근을 전제하므로 iSCSI/RBD 계열은 RWX를 안전하게 지원할 수 없다. 일부 CSI 드라이버가 RWX 요청을 통과시키더라도 파일시스템이 손상된다.

대신 다음 성질을 활용한다.

ReadWriteOnce는 "파드 하나"가 아니라 "노드 하나" 를 의미한다. 같은 노드에 스케줄된 여러 파드는 RWO PVC를 동시에 마운트할 수 있다.

RWO PVC + node affinity로 동시 학습 실행이 성립한다. 사용자가 노드를 선택하는 제품 모델과 정합하므로 추가 제약이 아니다.

hostPath 금지​

전용 디스크를 마운트해 로컬 볼륨으로 사용하는 방향은 맞으나, hostPath는 사용하지 않는다.

  • 노드 바인딩을 강제하지 못한다. node affinity를 누락하면 파드가 다른 노드에서 정상 시작되며, 그 노드에 이전 데이터셋의 잔여물과 마커가 남아 있으면 잘못된 데이터로 학습이 조용히 진행된다. 실패가 관측되지 않는 것이 가장 위험하다
  • Pod Security Standards의 baseline / restricted 모두 hostPath를 허용하지 않는다 → PSA를 강제하는 고객사에서 admission 거부
  • 용량이 스케줄러·ResourceQuota에 회계되지 않아 디스크 고갈을 막는 장치가 없다
  • PVC 생명주기가 없어 정리 주체가 부재하다
  • DirectoryOrCreate로 생성된 디렉터리는 root 소유이므로 non-root 컨테이너가 쓸 수 없다

local PV는 PV 스펙에 nodeAffinity가 내장되어 스케줄러가 해당 노드로만 배치하도록 강제한다. volumeBindingMode: WaitForFirstConsumer와 함께 사용하며, 용량이 선언되어 ResourceQuota에 반영되고 restricted PSA 아래에서도 동작한다.

폐쇄망 배포: local-path-provisioner는 YAML 단일 파일로 설치되고(Helm 불필요) 동적 프로비저닝을 지원한다. 이미지 하나만 내부 레지스트리에 등록하면 된다.

디스크 준비 요구사항​

  • 전용 디스크에 XFS 생성 후 /mnt/brick-staging 등 전용 경로로 마운트 (/etc/fstab 등록)
  • OS 디스크와 분리 필수. emptyDir 및 노드 ephemeral-storage는 컨테이너 이미지와 로그가 위치한 디스크를 사용한다. CUDA 기반 ML 이미지(10~15GB)와 대용량 데이터가 겹치면 disk pressure로 파드가 축출되며, 장시간 학습 중 축출은 치명적이다
  • storage class 명명: brick-staging-local, reclaimPolicy: Delete
  • emptyDir 또는 generic ephemeral volume을 사용하는 경우 resources.requests/limits에 ephemeral-storage를 반드시 명시한다 (누락 시 스케줄러가 용량을 고려하지 않는다)

⑤ GPU 노드 RAM​

데이터셋 전체가 페이지 캐시에 상주하면 첫 에폭 이후 디스크 접근이 거의 사라진다. 스테이징 볼륨이 상대적으로 느린 경우 이 효과가 상당한 완화책이 된다.

⑥ 데이터셋 캐시 관리​

BrickDatasetCache CRD와 Controller로 관리한다. 상세 설계는 BrickDatasetCache-CRD-설계.md 참조.

캐시를 채택하는 이유: 고객사별 네트워크 대역폭 편차가 크다. 10GbE 환경에서는 60GB 스테이징이 수 분이지만 1GbE 환경에서는 10분 이상이며, 하이퍼파라미터 튜닝으로 동일 데이터셋을 반복 사용하는 패턴에서 누적 차이가 크다.

캐시 없이 운영하는 경우 (허용): 클러스터 내부 대역폭이 충분하여 스테이징이 1~2분 이내로 완료되는 환경이라면, 실행 단위 generic ephemeral volume으로 매번 재다운로드해도 무리가 없다. 이 경로는 캐시 사용 불가 시의 폴백으로 항상 구현해 둔다.

volumes:
- name: dataset
ephemeral:
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: brick-staging-local
resources:
requests:
storage: 100Gi

⑦ 업로드 위치 정책​

표준: 브라우저가 처음부터 최종 위치(datasets/{datasetId}/)에 업로드한다.

임시 영역(staging/)에 올린 뒤 검증 후 최종 위치로 복사하는 2단계 방식은 채택하지 않는다.

2단계 방식이 제공하는 것​

브라우저의 쓰기 권한이 임시 영역만 향하므로, 검증이 끝난 데이터셋은 어떤 경우에도 변경될 수 없다. 업로드 크리덴셜이 아직 유효하더라도 최종 위치에는 손을 댈 수 없다.

채택하지 않는 이유: 복사 비용​

서버사이드 복사는 MinIO가 읽기 60GB + 쓰기 60GB를 수행하는 작업이다. 백엔드가 단일 게이트웨이·어레이라면 120GB가 그 지점을 통과한다.

조건소요
120MB/s약 17분
저장 용량복사 구간 동안 2배 필요

업로드 완료 후 학습 시작까지 이 시간이 추가되며, 용량 산정에도 반영해야 한다.

같은 보장을 더 낮은 비용으로 얻는 방법​

  1. 업로드 쓰기 권한을 해당 데이터셋 하나의 prefix로만 스코프한다
  2. 데이터셋 레코드에 상태를 둔다: uploading → validating → ready. ready 이전에는 어떤 학습도 이 데이터셋을 읽지 않는다
  3. 완료 콜백을 받으면 크리덴셜·서명 URL 갱신을 중단한다. 남은 유효 시간(최대 TTL 길이)이 경과하면 쓰기가 불가능해진다

이 경우 쓰기가 가능한 창은 "완료 시점의 잔여 TTL"로 한정되며, 그 대상도 아직 사용 불가 상태인 데이터셋 하나다.

2단계 방식을 검토해야 하는 경우​

규제·감사 요건으로 "검증 후 물리적 변경 불가"를 증명해야 하는 경우. 단 이때도 복사보다 MinIO 오브젝트 락(WORM) 을 먼저 검토한다. 복사 없이 동일하거나 더 강한 보장을 제공한다 (버킷 버저닝 활성화가 전제).

미완료 업로드 정리​

ready에 도달하지 못한 데이터셋은 상태와 생성 시각으로 식별 가능하다. 업로드 재개 허용 기간(예: 7일)을 초과한 것은 expired로 전이시키고 prefix를 삭제한다. 정리 주기는 재개 허용 기간보다 길게 설정한다 — 정리가 먼저 일어나면 재개하려는 파일이 이미 삭제되어 있다.


5. MinIO 토폴로지 — 표준과 벤더 권장의 차이​

참고: 이상적 구성​

⚠️ 아래는 자사 표준이 아니다. 참고 정보이며, 고객사에 이 구성을 제시하거나 약속하지 않는다. 채택 조건은 이 절 마지막의 "분산 구성 허용 조건"을 따른다.

스토리지 계층만 놓고 보았을 때 이론적으로 가장 좋은 구성은 다음과 같다.

계층이상적 구성이유
MinIO 백엔드노드별 전용 로컬 NVMe, JBOD (RAID 없이)하드웨어 RAID 계층을 제거해 MinIO가 로컬 파일시스템을 직접 사용
MinIO 토폴로지4노드 이상 분산, MinIO EC로 보호노드 장애 내성. EC는 오브젝트 단위로 치유하므로 RAID 리빌드보다 복구가 빠르고 안전
스테이징 볼륨GPU 노드별 전용 NVMe학습 중 데이터 읽기가 로컬 디스크 속도로 수행됨
네트워크10GbE 이상스테이징 소요 시간 단축

이것이 MinIO의 공식 프로덕션 권장 구성이기도 하다.

이 구성을 실제로 채택할 수 있는 경우: 고객사가 GPU 노드에 전용 NVMe를 제공하고, MinIO용으로 별도 노드·디스크를 4세트 이상 할당할 수 있으며, 그 디스크들이 서로 다른 물리 장애 도메인에 속하는 환경. 이 조건이 충족되면 §3 표준보다 이 구성을 우선한다.

대부분의 배포에서 성립하지 않는 이유는 아래 "자사 표준" 항에 정리한다.

자사 표준: 단일 인스턴스​

의도적 이탈이며 근거는 다음과 같다.

  1. 스토리지 토폴로지를 자사가 지정할 수 없다. 폐쇄망 고객사가 하드웨어를 제공하며, 4노드에 전용 로컬 NVMe를 요구하는 것은 대부분의 현장에서 성립하지 않는다
  2. 고객사 스토리지에 이미 RAID 보호가 있는 경우가 일반적이다. 이 경우 MinIO EC는 중복 보호이며 용량을 두 번 깎는다 (§4-②)
  3. 동일 어레이 LUN으로 구성한 분산은 내구성을 향상시키지 않는다 (§4-② 장애 도메인 원칙). 실무에서 확보 가능한 "4드라이브"는 대개 이 형태다
  4. 대상 워크로드가 짧은 중단을 허용한다. log-archive는 CronJob 재시도로 흡수되고, 서빙 모델은 로컬 파일을 읽으며, 데이터셋 업로드·스테이징은 사용자 개시 작업으로 재시도가 가능하다
  5. 현장 운영 인력이 제한적이다. 단일 인스턴스는 파드나 노드 장애 시 새 파드를 띄워 같은 볼륨을 마운트하면 복귀한다. 분산 구성의 degraded 상태 대응은 폐쇄망 현장에서 부담이 크다

감수사항​

  • MinIO 업데이트 및 노드 장애 시 스토리지가 중단된다 (Recreate로 인한 수십 초 ~ 수 분)
  • 벤더 권장 구성이 아니다

분산 구성 허용 조건​

고객사가 고가용성을 요구하거나 조건이 충족되는 경우 분산 구성을 채택할 수 있다. 다음을 모두 만족해야 한다.

  • 드라이브 4개 이상
  • 드라이브 간 장애 도메인이 실제로 분리 (서로 다른 어레이 또는 노드 로컬 물리 디스크)
  • 노드 장애 내성이 필요하면 4노드 × 1드라이브 이상
  • 백엔드에 별도 RAID 보호를 적용하지 않음 (JBOD)
  • 실행 시 모든 엔드포인트를 명시 (아래 참조)

토폴로지 티어​

티어구성견디는 장애위치
SNSD단일 노드 · 단일 드라이브없음 (EC 미적용)표준 — 백엔드 RAID가 보호 담당
SNMD단일 노드 · 4드라이브 이상드라이브 장애허용 — 백엔드 보호가 없는 경우
분산4드라이브 이상, 다중 노드드라이브 + 노드 장애허용 — 위 조건 충족 시

토폴로지 불변성​

토폴로지는 배포 시점에 고정되며 in-place 변경이 불가능하다. 드라이브 추가나 백엔드 교체는 신규 배포 + mc mirror + 컷오버가 필요하다. 용량 확장은 새 server pool 추가 방식이며 기존 데이터는 재분배되지 않고 신규 쓰기만 새 풀로 향한다.

→ 초기 배포 시 티어 결정이 사실상 되돌릴 수 없는 결정이다. 데이터가 작을 때와 클 때의 전환 비용 차이가 크므로, 신규 사이트에서는 배포 전에 확정한다.

금지 사항​

  • 단일 물리 디스크를 파티션으로 분할해 드라이브 수를 채우지 않는다. 디스크 하나가 죽으면 여러 "드라이브"가 동시에 사라져 EC가 무의미해진다
  • 동일 스토리지 어레이의 LUN들로 드라이브 수를 채우지 않는다. 위와 동일한 이유 (§4-②)
  • StatefulSet 전환만으로 분산 구성이 되지 않는다. replicas: 4에 각 파드가 독립적으로 minio server /data를 실행하면 서로 무관한 MinIO 4개가 생긴다. 분산 구성은 실행 시 모든 엔드포인트를 명시해야 성립한다
minio server http://minio-{0...3}.minio-svc.brick-storage.svc.cluster.local/data

⚠️ 패리티 기본값과 정족수 계산은 MinIO 버전에 따라 다르다. 배포 전 해당 버전 문서로 확인할 것.

용어 구분​

MinIO의 bucket / site replication은 별도 클러스터로의 비동기 복제(DR 용도)이며 erasure coding과 다른 계층이다. 문서 검토 시 혼동하지 않도록 한다.


6. 스테이징 계층 규약​

완결성 마커​

스테이징 Job은 완료 시 볼륨 루트에 .complete 마커를 기록한다. 학습 Job은 이 마커를 검증하지 않고 시작하지 않는다.

{
"datasetId": "ds-8f2a",
"manifestHash": "sha256:3f8a...",
"fileCount": 3000,
"totalBytes": 62914560000,
"layoutVersion": "yolo-v1",
"stagedAt": "2026-07-30T04:15:00Z"
}
  • 파일별 체크섬은 요구하지 않는다. 파일 수 + 총 바이트 + 매니페스트 해시로 실질적 오류가 검출되며 검증이 즉시 완료된다
  • layoutVersion은 디렉터리 규약 변경 시 구버전 캐시를 자동 무효화하기 위한 필드다
  • 재스테이징 시 기존 잔여물을 삭제한 후 시작한다

검증 책임​

UI 표시나 CR status는 추정치이며, 권위 있는 검증은 볼륨이 마운트된 파드 내부에서만 가능하다.

Controller는 brick-system에서 실행되므로 대상 노드의 파일시스템에 접근할 수단이 없다. 따라서 스테이징 Job과 학습 Job의 init step이 검증 주체가 된다. 상세는 BrickDatasetCache-CRD-설계.md 참조.

PVC가 Bound 상태라는 사실만으로 캐시 존재를 판단하지 않는다. local PV는 하위 디렉터리가 삭제되어도 PV 오브젝트가 Bound로 유지되며 쿠버네티스가 이를 감지할 수단이 없다.

디스크 레이아웃 계약​

스테이징은 단순 복사가 아니다. 학습 프레임워크가 기대하는 디렉터리 구조로 실체화한다.

/data/
├── images/train/, images/val/
├── labels/train/, labels/val/ # YOLO
├── annotations/*.json # COCO
├── data.yaml
└── .complete

이 레이아웃은 스테이징 컨테이너의 인터페이스 계약으로 별도 문서화한다.

스테이징의 범위는 다운로드와 레이아웃 실체화까지다. 리사이즈·정규화·증강 등 실험 설정에 종속되는 전처리는 학습 Job이 담당한다. 전처리 결과를 캐시에 담으면 설정 변경 시마다 전체 재다운로드가 발생하므로, 캐시는 원본만 보관해 모든 실험 설정에서 재사용되도록 한다. 상세는 BrickDatasetCache-CRD-설계.md §2 참조.

다운로드 병렬화​

순차 다운로드는 왕복 지연으로 대역폭을 채우지 못한다. 16~32 병렬을 기본으로 한다 (mc mirror --parallel 16 이상). 대역폭이 상한이면 그 이상은 무의미하다.

크리덴셜​

학습 Job은 MinIO 접근이 필요 없다(PVC만 읽음). 크리덴셜은 스테이징 Job에만 주입하고 datasets/{datasetId}/*에 대한 s3:GetObject로 스코프한다.

노드별 독립 캐시​

사용자가 학습 실행 시 노드를 선택하므로 캐시는 노드별로 독립 관리한다. 동일 데이터셋이 여러 노드에 각각 스테이징될 수 있다.

  • 데이터셋을 특정 노드에 묶지 않는다. 사용자의 노드 선택 자유를 제품이 제한하게 되므로 UX 후퇴다
  • 캐시는 폐기 가능한 데이터이므로 중복 자체가 위험은 아니나, 용량 회계는 노드별로 계산한다

노드별 캐시 상태 UI 노출 (후순위)​

초기 구현에서는 제외한다. 캐시 상태를 UI에 노출하지 않으면 상태 불일치가 사용자에게 관측되지 않아 정합성 대응 부담이 사라진다. 캐시가 있으면 학습이 빨리 시작되고 없으면 "데이터셋 준비 중" 단계가 표시되는 것으로 충분하다.

도입 시에는 노드 선택 화면에 캐시 상태를 4단계(캐시됨 / 스테이징 필요 / 공간 확보 후 스테이징 필요 / 스테이징 진행 중)로 노출하고, 문구를 단정하지 않는다("즉시 시작" → "즉시 시작 예상"). 노드 상태 동기화를 위한 DaemonSet 에이전트가 함께 필요하다.

가치가 조건부임에 유의한다. 캐시가 있는 노드의 GPU가 점유되어 있으면 정보를 활용할 수 없다.

재현성​

MLflow run에 datasetId를 파라미터로 기록한다. 데이터셋이 불변이므로 이 기록만으로 재현이 보장된다.


7. 용량 산정​

MinIO 원시 용량
= 데이터셋 크기 × 데이터셋 수 × 내구성 오버헤드(RAID 또는 EC)
+ 미완료 업로드 여유 (재개 허용 기간 내)
+ log-archive 용량
+ 모델 아티팩트

노드별 스테이징 볼륨
= 데이터셋 크기 × 1.3 (포맷 변환 산출물 여유)
× 노드당 동시 캐시 데이터셋 수

업로드를 최종 위치로 직접 수행하므로(§4-⑦) 복사 구간의 용량 2배 소요가 발생하지 않는다.

예시: 60GB 데이터셋 (이미지 3,000장 × 20MB)​

항목용량
MinIO — 데이터셋 1개 (오버헤드 2x)120 GB
MinIO — 업로드 진행 중 데이터셋 여유+60 GB
MinIO — log-archive기존 사용량
노드별 스테이징 캐시 (데이터셋 2개)156 GB
노드 OS + 컨테이너 이미지100 GB+

미완료 업로드 정리 주기는 §4-⑦ 참조 (재개 허용 기간보다 길게 설정).


8. 고객사 사전 요구사항​

신규 배포 및 영상·이미지 과제 도입 시 고객사 인프라팀에 제시하는 요구사항.

항목요구미달 시
MinIO 백엔드 볼륨블록 스토리지, 용량은 §7 산정식 기준파일 프로토콜 허용 (§4-① 조건 및 감수사항 적용)
MinIO 백엔드 보호RAID 등 디스크 보호보호 없으면 4드라이브 이상 확보 필요
GPU 노드 스테이징 디스크OS 디스크와 분리된 전용 디스크, 데이터셋 크기 × 1.3 × 캐시 수실행 단위 재다운로드로 운영. GPU 유휴 및 학습 시작 지연 발생
스테이징 storage classRWO 블록. RWX 불필요—
GPU 노드 RAM데이터셋 크기 이상학습 I/O 성능 저하 가능
MinIO 엔드포인트 접근성사용자 PC에서 도달 가능 (사내망 기준, 인터넷 노출 아님)백엔드 스트리밍 프록시 폴백 필요
MinIO 엔드포인트 TLS사용자 PC 브라우저가 신뢰하는 인증서브라우저 직결 업로드 불가
네트워크 대역폭데이터셋 크기 / 허용 스테이징 시간캐시 필수화

참고: 스테이징 디스크 요구는 표준의 다른 항목보다 학습 성능에 직접적인 영향을 준다. 협의 우선순위를 여기에 둔다.


9. 배포 체크리스트​

MinIO​

  • replicas: 1 고정, strategy: Recreate
  • PVC 접근 모드 ReadWriteOnce
  • HPA 미부착 확인 (replicas가 1을 넘을 경로 차단)
  • 파일 프로토콜 백엔드인 경우 hard 마운트 확인
  • region 명시 (presigned URL 발급이 완전한 오프라인 연산이 되도록)
  • 버킷 CORS: AllowedMethods: PUT, ExposeHeaders: ETag
  • Console 포트(9001) 미노출 — S3 API 포트만 개방
  • 시계 동기화(NTP) 확인 — 서명 만료 판정에 영향

브라우저 직결 업로드 경로​

  • presigned URL 서명 엔드포인트 = 브라우저가 실제 요청하는 URL (문자 단위 일치)
  • MinIO 엔드포인트가 사용자 PC에서 도달 가능
  • TLS: BrickML 콘솔이 HTTPS면 MinIO도 HTTPS (mixed content 차단)
  • 사내 CA 인증서를 사용자 PC 브라우저가 신뢰하는지 확인
  • Ingress 경유 시:
    • proxy-body-size 상향 (기본 1MB → 413 오류)
    • proxy-request-buffering: "off"
    • proxy-read-timeout / proxy-send-timeout 상향
    • Host 헤더 원본 유지 (proxy_set_header Host $host)
    • CORS는 MinIO에서만 처리 (Ingress enable-cors 동시 사용 시 헤더 중복으로 브라우저가 거부)

스테이징·학습​

  • GPU 노드에 OS 디스크와 분리된 스테이징 디스크 마운트, XFS
  • storage class brick-staging-local, reclaimPolicy: Delete
  • 스테이징 Job에 GPU 미할당
  • 스테이징 Job과 학습 Job 모두 사용자가 선택한 노드로 명시적 고정
  • hostPath 미사용 확인
  • brickml-deployer에 노드별 스테이징 용량 선언
  • ResourceQuota의 requests.storage 및 persistentvolumeclaims 개수에 캐시 반영
  • BrickDatasetCache 관련 항목은 BrickDatasetCache-CRD-설계.md 체크리스트 참조

10. 적용 절차​

대상방침
신규 배포표준 즉시 적용. §5 토폴로지는 배포 전 확정 (사후 변경 불가)
기존 배포§9 MinIO 체크리스트(특히 Recreate)는 즉시 반영. 백엔드 마이그레이션은 별도 프로젝트로 띄우지 않고 정기 점검·메이저 업그레이드 시 기회주의적으로 수행
영상·이미지 과제 도입 사이트스테이징 디스크 요구사항 충족을 도입 전제조건으로 한다. MinIO 백엔드는 허용 수준을 유지해도 무방

세 번째 항목이 핵심 레버다. 신규 기능 도입이라는 명분이 있을 때가 고객사에 스토리지 요구사항을 제시하기 가장 좋은 시점이다.


11. 재검토 신호​

  • 데이터셋 오브젝트 수가 수만~수십만 개 규모로 증가 (메타데이터 연산 병목, ListObjects 검증 지연)
  • 동일 스토리지를 log-archive 등 다른 워크로드가 공유하며 경합 발생
  • 여러 데이터셋 동시 스테이징이 일상화
  • MinIO 로그에 락 관련 경고 발생
  • 학습 중 GPU 사용률이 I/O 대기로 지속 저하
  • 고객사가 스토리지 계층 고가용성을 명시적으로 요구

12. 미결 항목​

  • MinIO 버전별 패리티 기본값·정족수 확인 후 §5 수치 확정
  • 스테이징 컨테이너 디스크 레이아웃 계약 별도 문서화
  • canonical 어노테이션 포맷 확정 (학습 백엔드 종속 — Ultralytics 계열이면 YOLO, Detectron2/MMDetection 계열이면 COCO)
  • 모델 아티팩트·MLflow 백엔드 스토리지 표준 (별도 문서)
  • 기존 배포 사이트별 구성 현황 조사 → 대응 매트릭스 작성
  • 고객사 제출용 요구사항 문서(§8) 별도 서식화

부록 A. 용어​

문서에 등장하는 용어를 한 줄로 정리한다. 정확한 정의보다 문서 이해에 필요한 수준을 목표로 한다.

스토리지 일반​

용어설명
블록 스토리지디스크를 "빈 저장 공간" 그대로 제공하는 방식. 사용하는 쪽이 파일시스템(XFS 등)을 직접 만들어 쓴다. 로컬 SSD, iSCSI, FC가 여기 속한다
파일 스토리지 / 파일 프로토콜이미 만들어진 파일시스템을 네트워크로 공유하는 방식. NFS, SMB가 여기 속한다. 파일 열기·잠금 같은 동작이 네트워크를 오간다
SAN블록 스토리지를 네트워크로 제공하는 전용 스토리지 장비·망
NAS파일 스토리지를 네트워크로 제공하는 장비
JBOD디스크를 묶지 않고 각각 그대로 사용하는 구성. RAID의 반대
RAID여러 디스크에 데이터를 나누거나 복제해 디스크 하나가 고장나도 데이터를 유지하는 하드웨어·펌웨어 기능
장애 도메인하나가 고장나면 함께 죽는 범위. 같은 어레이에서 잘라낸 디스크들은 어레이가 죽으면 전부 사라지므로 하나의 장애 도메인이다
WORM한 번 쓰면 변경·삭제할 수 없게 잠그는 기능. 감사·규제 요건에 사용

MinIO​

용어설명
erasure coding (EC)데이터를 조각으로 쪼개고 복구용 조각(패리티)을 추가해 여러 드라이브에 나눠 저장하는 방식. 일부 조각이 사라져도 나머지로 복원한다. 전체 복사본을 만드는 복제와는 다르다
패리티복구용 조각. 패리티 개수만큼의 드라이브 손실을 견딜 수 있다
정족수(quorum)읽기·쓰기가 성립하기 위해 살아 있어야 하는 최소 드라이브 수
드라이브MinIO가 인식하는 저장 단위 하나. 보통 디스크 하나 또는 볼륨 하나에 대응
server pool분산 MinIO에서 함께 묶인 노드·드라이브 집합. 용량 확장은 새 pool을 추가하는 방식이며 기존 데이터는 재배치되지 않는다
SNSD / SNMD단일 노드·단일 드라이브 / 단일 노드·다중 드라이브 구성
prefix오브젝트 키의 앞부분. 파일 경로의 디렉터리에 해당한다 (datasets/ds-8f2a/ 등)
presigned URL백엔드가 서명해서 만든, 특정 오브젝트에 한시적으로 유효한 접근 URL. 브라우저가 저장소에 직접 업로드할 때 사용한다
bucket / site replication다른 MinIO 클러스터로 비동기 복제하는 재해복구 기능. erasure coding과는 다른 계층

쿠버네티스​

용어설명
PV / PVCPV는 실제 저장 공간, PVC는 그 공간을 달라는 요청서. 파드는 PVC를 통해 볼륨을 사용한다
RWO (ReadWriteOnce)노드 하나에서만 읽기·쓰기로 마운트 가능. 같은 노드의 여러 파드는 동시에 사용할 수 있다
RWX (ReadWriteMany)여러 노드에서 동시에 읽기·쓰기 가능. 파일 프로토콜에서만 안전하게 지원된다
local PV특정 노드의 디스크를 볼륨으로 제공하는 방식. 노드 정보가 볼륨 정의에 포함되어 스케줄러가 해당 노드로만 파드를 배치한다
hostPath노드의 특정 경로를 그대로 파드에 붙이는 방식. 노드 고정이 강제되지 않아 표준에서 금지한다
WaitForFirstConsumer볼륨을 미리 만들지 않고, 그 볼륨을 쓰는 파드가 어느 노드에 배치되는지 결정된 뒤 그 노드에 만드는 설정
reclaimPolicy: DeletePVC를 삭제하면 실제 저장 공간도 함께 정리하는 설정
emptyDir파드 수명 동안만 존재하는 임시 볼륨. 노드의 시스템 디스크를 사용하므로 대용량에는 주의가 필요하다
ephemeral-storage노드에서 컨테이너 이미지·로그·임시 볼륨이 함께 사용하는 저장 공간
disk pressure노드 디스크가 부족해진 상태. 쿠버네티스가 파드를 강제 종료한다
축출(eviction)노드 자원 부족으로 파드가 강제 종료되는 것
node affinity / nodeSelector파드를 특정 노드에 배치하도록 지정하는 설정
Recreate / RollingUpdate업데이트 방식. Recreate는 기존 파드를 완전히 종료한 뒤 새로 만들고, Deployment의 RollingUpdate는 새 파드를 먼저 띄운다
StatefulSet파드에 고정된 이름과 전용 볼륨을 부여하는 워크로드. 업데이트 시 기존 파드를 먼저 종료한다
volumeClaimTemplatesStatefulSet이 파드마다 별도 PVC를 자동 생성하도록 하는 설정
ResourceQuota네임스페이스별로 사용 가능한 자원(용량, 개수 등)의 상한
PSA (Pod Security Standards)파드에 허용되는 권한 수준을 강제하는 정책. restricted 수준에서는 hostPath가 금지된다
CSI외부 스토리지를 쿠버네티스에 연결하는 표준 인터페이스. 스토리지 벤더가 제공하는 드라이버가 이를 구현한다
CRD / ControllerCRD는 사용자 정의 리소스의 형식 정의, Controller는 그 리소스를 보고 실제 작업(파드·볼륨 생성 등)을 수행하는 프로그램
reconcileController가 "원하는 상태"와 "현재 상태"를 비교해 차이를 메우는 반복 동작
ownerReference리소스 간 소유 관계. 부모를 삭제하면 자식도 함께 삭제된다
finalizer리소스 삭제 전에 정리 작업을 수행하도록 삭제를 잠시 보류하는 장치

데이터셋·학습​

용어설명
스테이징학습 직전에 데이터셋을 MinIO에서 노드 디스크로 내려받아, 학습이 바로 읽을 수 있는 형태로 만드는 작업
실체화(materialize)저장소에 있던 데이터를 실제 파일·디렉터리 구조로 펼쳐 놓는 것
캐시한 번 스테이징한 결과를 노드에 남겨 두어 다음 학습에서 재사용하는 것
마커스테이징이 정상 완료되었음을 표시하는 파일(.complete). 내용에 검증용 기준값이 담긴다
매니페스트 해시데이터셋 파일 목록으로부터 계산한 값. 캐시 내용이 원본과 같은지 확인하는 데 사용
멱등(idempotent)여러 번 실행해도 결과가 같은 성질. 스테이징 Job은 이미 완료된 상태에서 다시 실행되면 즉시 종료된다
single-flight같은 작업이 동시에 두 번 실행되지 않도록 막는 것
TTL보존 기간. 이 시간이 지나면 정리 대상이 된다
LRU가장 오래 사용하지 않은 것부터 정리하는 방식
에폭(epoch)학습이 데이터셋 전체를 한 번 훑는 단위. 수십 회 반복되므로 데이터 읽기 속도가 누적으로 영향을 준다
페이지 캐시운영체제가 디스크에서 읽은 내용을 메모리에 남겨 두는 기능. 데이터셋이 RAM보다 작으면 두 번째 에폭부터 디스크를 거의 읽지 않는다
prefetch필요해지기 전에 미리 가져다 두는 것
canonical 포맷여러 입력 형식을 하나로 통일한 내부 표준 형식. 학습 코드가 형식 하나만 알면 되도록 한다
YOLO / COCO객체 검출 라벨 형식. YOLO는 이미지 1장당 텍스트 파일 1개에 비율 좌표를, COCO는 데이터셋 전체를 하나의 JSON에 절대 좌표로 담는다