10 KiB
10 KiB
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/v2API 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/cluster— write quorum 기준 (rolling update 중 false 가능, readiness 비권장)/minio/health/cluster/read— read 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 metricsmc 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 권한자 우회 가능) vsCOMPLIANCE(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"또는 Helmminio-operator+tenantchart- Tenant CR로 pool, credential, TLS, KES, logging, monitoring 선언
- 수제 StatefulSet 운영 금지
2. Tenant는 namespace당 1개
기본:
minio-prodnamespace에 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 = 16drive 시작 (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 LockCOMPLIANCE모드 - 백업 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에
minioclient 생성 (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
policyclaim으로 매핑
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 - 데이터 규모/동시 요청 수에 따라 조정
- requests:
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 = 16drive, prod는8 × 4 = 32이상 - EC:
EC:4기본, critical dataEC: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 ≥ 4erasure 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 아님)