Files
project-infra/docs/standards/infra/minio.md
T

10 KiB
Raw Blame History

MinIO 기준

목적

이 문서는 Kubernetes 환경에서 MinIO를 1000+ 서비스의 S3 호환 object storage로 운영하기 위한 기준을 고정한다.

  • MinIO Operator + Tenant CRD (minio.min.io/v2)를 기본 배포 모델로 둔다
  • Erasure coding 최소 요건 (servers × volumesPerServer ≥ 4)을 명시한다
  • KES sidecar + Vault transit backend로 SSE-KMS를 구성한다
  • STS + OIDC (Keycloak)로 서비스 인증을 수행한다
  • 버전 관리 / object lock / replication / lifecycle rule을 운영 필수 요소로 둔다

공식 의미 (MinIO Operator + Tenant CRD 기준)

  • MinIO Operator는 minio.min.io/v2 API group의 Tenant CR을 watch하여 StatefulSet, Service, PVC, 인증서를 자동 생성한다.
  • Tenant는 namespace당 1개를 권장한다 (namespace = 소유/정책/쿼터 경계).
  • MinIO는 erasure coding을 사용한다. servers × volumesPerServer는 최소 4이어야 기동한다. EC:N parity (기본 EC:4 ~ EC:8)는 parity drive 수를 결정하며, 장애 허용 drive 수 = parity 수.
  • MinIO pool은 불변이다(immutable). pool 내 servers / volumesPerServer는 Tenant 생성 후 변경 불가. 용량 확장은 새 pool 추가로 수행.
  • Health endpoints:
    • /minio/health/live — 프로세스 liveness (인증 없음)
    • /minio/health/clusterwrite quorum 기준 (rolling update 중 false 가능, readiness 비권장)
    • /minio/health/cluster/readread quorum 기준 (rolling update 허용, readiness 권장)
  • Metrics endpoints:
    • /minio/v2/metrics/cluster — cluster-wide (기본 Bearer token 필요)
    • /minio/v2/metrics/node — per-node
    • /minio/v2/metrics/bucket/api/<bucket> — bucket API metrics
    • mc admin prometheus generate 로 scrape config + token 생성. 또는 prometheusAuthType: public 설정으로 unauth scrape 허용.
  • KES (Key Encryption Service)는 별도 sidecar/Deployment로 Vault transit backend와 통신해 SSE-KMS / SSE-S3 per-object key를 발급한다.
  • MinIO service account는 root access key의 하위 derived credential이다(IAM role 개념 아님). 앱은 service account만 사용하고 root는 bootstrap 전용.
  • Object lock은 bucket 생성 시점에 활성화해야 하며, GOVERNANCE (bypass 권한자 우회 가능) vs COMPLIANCE (root도 우회 불가) 두 모드.
  • Site replication은 최대 16개 MinIO 클러스터를 동기화한다 (IAM, bucket config, object 전체). Bucket replication은 특정 bucket만 대상.
  • Console은 9090 port, API는 9000 port.

기본 규칙

1. 배포는 MinIO Operator + Tenant CR

기본:

  • kubectl apply -k "https://github.com/minio/operator?ref=v6.0.4" 또는 Helm minio-operator + tenant chart
  • Tenant CR로 pool, credential, TLS, KES, logging, monitoring 선언
  • 수제 StatefulSet 운영 금지

2. Tenant는 namespace당 1개

기본:

  • minio-prod namespace에 Tenant 1개
  • 테넌트 간 격리가 필요하면 namespace를 복수 생성
  • 동일 namespace에 다른 워크로드와 공존 금지

3. Erasure coding 요건: servers × volumesPerServer ≥ 4

기본 topology 후보:

servers volumesPerServer 총 drive 기본 EC parity 장애 허용 drive
4 4 16 EC:4 4
4 8 32 EC:4 4
8 4 32 EC:4 4
8 8 64 EC:4 ~ EC:8 4 ~ 8

기본:

  • 최소 4 × 4 = 16 drive 시작 (prod)
  • MINIO_STORAGE_CLASS_STANDARD=EC:4 이상, critical data는 EC:8
  • parity 증가 = 용량 감소 + 신뢰성 증가

기본 금지:

  • servers × volumesPerServer < 4 → Tenant가 기동 실패

4. Pool은 immutable — 확장은 새 pool 추가

기본:

  • 초기 pool의 servers, volumesPerServer, volumeClaimTemplate.size는 평생 고정
  • 용량 부족 시 spec.pools[]pool-1, pool-2 추가
  • pool 간 데이터 rebalance는 mc admin rebalance start

5. StorageClass 명시 (local-path 금지)

기본:

  • prod: volumeClaimTemplate.spec.storageClassName: ceph-rbd-retain / ebs-gp3 / local-volume-xfs (명시적)
  • 파일시스템은 xfs 권장 (MinIO는 ext4보다 xfs에 최적화)
  • reclaimPolicy: Retain + PVC 삭제 가드 (Tenant 삭제 시 데이터 소실 방어)

기본 금지:

  • k3s local-path prod 사용
  • default StorageClass fallback

6. Credential: root는 bootstrap 전용, 앱은 service account

기본:

  • spec.configuration.name에 root credential Secret (MINIO_ROOT_USER, MINIO_ROOT_PASSWORD)
  • Vault KV에 root credential 저장, VSO로 Secret 동기화
  • 앱용 access는 mc admin accesskey create로 서버 생성 credential을 발급하고 inline policy로 권한을 축소한다
  • 생성 결과의 secret key는 한 번만 수신해 stdin으로 Vault에 기록하며, --secret-key 또는 mc admin user add로 secret을 argv에 전달하지 않는다
  • service account는 최소 권한 policy 바인딩

7. TLS는 기본 활성화

기본:

  • spec.requestAutoCert: true → Operator가 Kubernetes CSR로 인증서 자동 발급 (MinIO 자체 CA)
  • 사내 PKI 사용 시 spec.externalCertSecret + cert-manager Certificate
  • API (9000), Console (9090), KES 전부 TLS

8. KES + Vault transit으로 SSE-KMS

기본:

  • spec.kes 필드에 KES 사이드카 spec
  • KES는 Vault transit engine을 key store로 사용
  • bucket 생성 시 mc encrypt set sse-kms minio-backup/critical key-id=my-app-key
  • per-object DEK를 KES에서 받아 암호화

기본 금지:

  • KES 없이 SSE-S3만 사용 (master key가 MinIO 내부에만 존재 → 분실 위험)
  • KES가 local filesystem key store 사용 (prod)

9. Versioning + Object Lock은 critical bucket 기본값

기본:

  • 금융/감사 데이터: mc version enable + Object Lock COMPLIANCE 모드
  • 백업 bucket: Object Lock GOVERNANCE + retention 30일
  • 일반 app bucket: versioning만 (실수 복구)
  • lifecycle rule로 오래된 버전 자동 정리 (mc ilm add --expire-noncurrent-days 90)

10. Replication: site vs bucket

기본:

  • 전체 IAM/config 동기화 필요: site replication (mc admin replicate add)
  • 특정 bucket만 cross-region 복제: bucket replication (mc replicate add)
  • async replication 특성 인지 (RPO > 0)
  • mc mirror는 DR 전략 아님 — 일회성 migration/sync 용도

11. STS + OIDC (Keycloak) 통합

기본:

  • Keycloak에 minio client 생성 (confidential)
  • MinIO 설정:
    mc admin config set ALIAS identity_openid \
      config_url="https://auth.example.com/realms/platform/.well-known/openid-configuration" \
      client_id="minio" \
      client_secret="..." \
      claim_name="policy" \
      scopes="openid,profile,email"
    
  • 앱은 AssumeRoleWithWebIdentity로 JWT → 임시 STS credential 교환
  • MinIO policy에 JWT policy claim으로 매핑

12. Health probe: read quorum을 readiness로

기본:

  • livenessProbe: /minio/health/live (프로세스 생존)
  • readinessProbe: /minio/health/cluster/read (read quorum) — rolling update 허용
  • startupProbe: /minio/health/live + failureThreshold 넉넉하게

기본 금지:

  • readinessProbe/minio/health/cluster (write quorum) 사용 → rolling update 시 전체 pod unready

13. Metrics: 내부 scrape 전용

기본:

  • spec.prometheus 또는 prometheusAuthType: public (내부 network만)
  • 또는 mc admin prometheus generate 로 scrape token 발급 후 bearerTokenSecret
  • ServiceMonitor는 /minio/v2/metrics/cluster 대상
  • 외부 Ingress 공개 금지

14. API Ingress — Console은 내부 전용

기본:

  • API (9000): 필요한 경우 Ingress로 공개 (S3 API host: s3.example.com)
  • Console (9090): 내부/운영자 전용, 외부 공개 금지 (별도 host + IP whitelist + OIDC forward-auth)
  • Console을 공개하면 root credential UI 로그인 표면 확장

15. Lifecycle rule로 용량 관리

기본:

  • 로그 bucket: 30~90일 expire
  • tmp / cache bucket: 7일 expire
  • versioning enabled bucket: noncurrent version 90일 expire
  • incomplete multipart upload: 7일 abort (mc ilm add --expire-incomplete-upload-days 7)

16. 로깅

기본:

  • spec.log.audit → bucket에 audit log 저장 또는 webhook으로 외부 전송
  • stdout으로 console log → fluent-bit / Loki 수집
  • audit log는 Object Lock bucket에 저장해 변조 방지

17. SecurityContext + Resource

기본:

  • spec.securityContext: runAsNonRoot: true, runAsUser: 1000, fsGroup: 1000, runAsGroup: 1000
  • Restricted PSS 준수
  • 단일 pod resource (4 server cluster 기준):
    • requests: cpu: 500m, memory: 2Gi
    • limits: cpu: 4, memory: 8Gi
    • 데이터 규모/동시 요청 수에 따라 조정

18. Anti-affinity + topologySpread

기본:

  • podAntiAffinity: hostname 기준 required (같은 node에 MinIO pod 복수 금지)
  • topologySpreadConstraints: zone 분산
  • EC:4 + 4-zone = 1 zone 장애 허용

19. Console은 분리, auth는 OIDC

기본:

  • Console endpoint에 MINIO_IDENTITY_OPENID_* OIDC 설정
  • root credential UI 로그인은 break-glass 전용
  • 일반 운영자는 OIDC 로그인 + group → policy 매핑

20. 현재 스택 기본 권장안

  • 배포: MinIO Operator + Tenant CR (minio.min.io/v2)
  • Topology: 최소 4 × 4 = 16 drive, prod는 8 × 4 = 32 이상
  • EC: EC:4 기본, critical data EC:8
  • StorageClass: 명시적 (xfs, Retain)
  • TLS: requestAutoCert: true
  • KMS: KES sidecar + Vault transit
  • 인증: root는 VSO 주입, 앱은 service account, 사용자는 Keycloak OIDC
  • Health: live / cluster-read (readiness)
  • Metrics: Prometheus bearer-token scrape
  • Versioning + Object Lock: critical bucket 기본값
  • Replication: site (전체) / bucket (부분) 구분
  • Console: 내부 전용

프로젝트 기준 요약

  • MinIO Operator + Tenant CR 기본 배포
  • namespace당 Tenant 1개
  • servers × volumesPerServer ≥ 4 erasure coding 요건
  • Pool immutable — 확장은 새 pool
  • StorageClass 명시 + xfs 권장 + Retain
  • KES + Vault transit으로 SSE-KMS
  • Root credential은 Vault → VSO → Secret 경로
  • 앱 접근은 service account, 사용자는 Keycloak OIDC STS
  • Health: /minio/health/live + /minio/health/cluster/read
  • Metrics: Bearer token scrape
  • Console 외부 비공개, API만 필요 시 Ingress
  • Versioning + Object Lock + Lifecycle rule로 데이터 보호
  • site/bucket replication으로 DR (mc mirror는 DR 아님)