MinIO
MinIO는 S3 호환 분산 오브젝트 스토리지입니다. Lumie 플랫폼에서 파일 업로드, 백업 저장소, WAL 아카이브 등 다양한 용도로 사용됩니다.
개요
주요 기능
| 기능 | 설명 |
|---|---|
| S3 호환성 | AWS S3 API 완전 호환 |
| 분산 스토리지 | Erasure Coding으로 데이터 보호 |
| 고가용성 | 4개 노드 분산 배치 |
| 웹 콘솔 | 브라우저 기반 관리 인터페이스 |
| 메트릭 | Prometheus 통합 모니터링 |
아키텍처
설치 및 구성
분산 모드 설정
# MinIO Helm Values - Distributed Mode
replicas: 4
drivesPerNode: 1
# 4개 노드 × 1개 드라이브 = 4개 드라이브 총합
# Erasure Coding: EC:2 (2개 패리티)
이미지 설정
image:
repository: quay.io/minio/minio
tag: RELEASE.2025-01-20T14-49-07Z
pullPolicy: IfNotPresent
부트스트랩 단계에서는 외부 레지스트리(quay.io)를 사용합니다. Zot 레지스트리가 아직 사용 불가능하기 때문입니다.
스토리지 설정
전용 스토리지 클래스
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: minio-local
provisioner: kubernetes.io/no-provisioner
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
PersistentVolume 구성
# 노드별 전용 PV (각 45Gi, /mnt/minio-data)
- name: minio-pv-worker1 # k3s-master (worker-1 디스크 이전)
nodeAffinity: k3s-master
- name: minio-pv-worker2 # k3s-worker-2
nodeAffinity: k3s-worker-2
- name: minio-pv-worker3 # k3s-worker-3
nodeAffinity: k3s-worker-3
- name: minio-pv-worker4 # k3s-worker-4
nodeAffinity: k3s-worker-4
디스크 할당:
| PV 이름 | 노드 | 계정 | 비고 |
|---|---|---|---|
minio-pv-worker1 | k3s-master | 0214 | 구 worker-1 디스크 이전 (2026-04) |
minio-pv-worker2 | k3s-worker-2 | 0214 | |
minio-pv-worker3 | k3s-worker-3 | 0213 | |
minio-pv-worker4 | k3s-worker-4 | 0213 |
k3s-worker-1은 2026-04에 제거되었습니다. 해당 노드의 MinIO 디스크 데이터는 k3s-master의 /mnt/minio-data로 이전되었습니다.
Helm 차트 추가 설정
# MinIO Helm Values - Additional Configuration
enableServiceLinks: false # Kubernetes 서비스 링크 비활성화 (MINIO_SERVICE_PORT 충돌 방지)
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule # 마스터 노드 스케줄링 허용
priorityClassName: high-priority # 중요 스토리지 인프라를 위한 높은 우선순위
customCommandJob:
resources:
requests:
cpu: 10m
memory: 128Mi
limits:
memory: 128Mi # Kyverno 정책 준수를 위한 리소스 제한
보안 설정
자격 증명 관리
# Vault Static Secret을 통한 자격 증명 관리
existingSecret: minio-root-password
rootUserSecretKey: root-user
rootPasswordSecretKey: root-password
Vault 경로: infrastructure/minio
CORS 설정
environment:
MINIO_API_CORS_ALLOW_ORIGIN: "*"
브라우저에서 직접 파일 업로드를 위한 CORS 허용 설정입니다.
네트워킹
업로드 프록시 IngressRoute
MinIO Helm 차트의 표준 Ingress는 비활성화되어 있습니다(ingress.enabled: false, consoleIngress.enabled: false). 외부 노출은 Traefik 전용 IngressRoute CRD로만 이루어집니다.
# bootstrap/minio/manifests/upload-proxy-ingress.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: minio-upload-proxy
namespace: minio
spec:
entryPoints:
- websecure
routes:
- match: Host(`lumie-edu.com`) && PathPrefix(`/lumie/tmp/`) && (Method(`PUT`) || Method(`OPTIONS`))
kind: Rule
services:
- name: minio
port: 9000
- match: Host(`dev.lumie-infra.com`) && PathPrefix(`/lumie-dev/tmp/`) && (Method(`PUT`) || Method(`OPTIONS`))
kind: Rule
services:
- name: minio
port: 9000
tls: {}
특징:
- 표준
Ingress사용 안 함: Traefik 표준 Ingress는 메서드 필터 미들웨어를 지원하지 않아, 메서드 매칭이 가능한IngressRouteCRD를 사용 - 경로 제한:
prod→/lumie/tmp/,dev→/lumie-dev/tmp/(임시 업로드 경로만 노출) - 메서드 제한:
PUT(업로드)와OPTIONS(CORS preflight)만 허용; IngressRoute 라우터 규칙에서 직접 처리 - 인증: JWT 없음 — Presigned URL의 AWS Signature V4로 인증
- TLS:
tls: \{\}(빈 설정) — Traefik이 SNI를 통해 인증서 스토어에서 자동 선택
콘솔 UI
커스텀 콘솔 배포
components:
- name: minio-ui
replicaCount: 1
image:
repository: zot.lumie-infra.com/minio/console
tag: "v1.9.1"
containerPort: 9090
env:
- name: CONSOLE_MINIO_SERVER
value: "http://minio.minio.svc.cluster.local:9000"
접근 방법:
- 내부:
minio-ui.minio.svc.cluster.local:9090 - 외부: Teleport Web App 터널
Helm 차트의 기본 콘솔 대신 별도 배포를 사용하여 더 나은 제어와 보안을 제공합니다.
성능 최적화
CPU 최적화
environment:
# 복제 워커 수 제한 (CPU 사용량 감소)
MINIO_API_REPLICATION_MAX_WORKERS: "1"
MINIO_API_REPLICATION_MAX_LRG_WORKERS: "1"
MINIO_API_TRANSITION_WORKERS: "1"
MINIO_SCANNER_SPEED: "slowest"
# Go 런타임 CPU 매칭
GOMAXPROCS: "2"
리소스 할당
resources:
requests:
cpu: 15m
memory: 256Mi
limits:
memory: 422Mi
# CPU 제한 없음 (안정성 우선)
안티 어피니티
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- minio
topologyKey: kubernetes.io/hostname
각 MinIO Pod를 서로 다른 노드에 배치하여 고가용성을 보장합니다.
데이터 관리
버킷 구조
| 버킷 | 용도 | 보존 정책 |
|---|---|---|
lumie | 애플리케이션 파일 (시험지, OMR 이미지 등) | 영구 보존 (omr/tmp/ 제외) |
velero-backups | Kubernetes 리소스 + PVC 백업 (Velero) | 7일 (168h TTL) |
CloudNativePG WAL 아카이브와 베이스 백업은 MinIO가 아닌 Cloudflare R2(
s3://lumie-dr/cnpg/*)에 저장됩니다.
ILM (Information Lifecycle Management)
customCommands:
- command: ilm rule add myminio/lumie --prefix "omr/tmp/" --expire-days 1
자동 정리 규칙:
- 경로:
omr/tmp/(임시 OMR 이미지) - 보존 기간: 24시간
- 목적: 스토리지 공간 절약
백업 제외 설정
podAnnotations:
backup.velero.io/backup-volumes-excludes: export
MinIO 데이터 볼륨을 Velero 백업에서 제외합니다. 순환 백업(velero-backups 버킷 백업)을 방지하기 위함입니다.
모니터링
Prometheus 메트릭
metrics:
serviceMonitor:
enabled: true
includeNode: true
additionalLabels:
release: prometheus
interval: 30s
scrapeTimeout: 10s
주요 메트릭
| 메트릭 | 설명 |
|---|---|
minio_cluster_nodes_online_total | 온라인 노드 수 |
minio_cluster_drive_online_total | 온라인 드라이브 수 |
minio_bucket_usage_total_bytes | 버킷별 사용량 |
minio_s3_requests_total | S3 API 요청 수 |
minio_s3_errors_total | S3 API 오류 수 |
알림 규칙
# 예시 알림 규칙
- alert: MinIONodeDown
expr: minio_cluster_nodes_online_total < 4
for: 5m
labels:
severity: critical
annotations:
summary: "MinIO node is down"
description: "MinIO cluster has {{ $value }} nodes online, expected 4"
운영 가이드
클러스터 상태 확인
# Pod 상태 확인
kubectl get pods -n minio -l app=minio
# 서비스 상태 확인
kubectl get svc -n minio
# PVC 상태 확인
kubectl get pvc -n minio
MinIO 클라이언트 사용
# mc 클라이언트 설치
kubectl run mc --rm -it --image=minio/mc --restart=Never -- /bin/bash
# MinIO 서버 추가
mc alias set myminio http://minio.minio.svc.cluster.local:9000 $ACCESS_KEY $SECRET_KEY
# 버킷 목록 확인
mc ls myminio
# 버킷 생성
mc mb myminio/new-bucket
# 파일 업로드
mc cp local-file.txt myminio/lumie/path/to/file.txt
백업 및 복구
설정 백업
# MinIO 설정 내보내기
mc admin config export myminio > minio-config.json
# 정책 내보내기
mc admin policy list myminio
mc admin policy info myminio readwrite > policy-readwrite.json
데이터 미러링
# 다른 MinIO 클러스터로 미러링
mc mirror myminio/lumie remote-minio/lumie-backup
보안
네트워크 보안
- 클러스터 내부: 모든 API 접근은 클러스터 내부에서만 가능
- 업로드 프록시: Traefik IngressRoute로 임시 경로(
/lumie/tmp/,/lumie-dev/tmp/)만 외부 접근 허용 - 콘솔 접근: Teleport를 통해서만 접근 가능
자격 증명 보안
# Vault Static Secret 설정
vaultStaticSecrets:
- name: minio-vss
path: infrastructure/minio
destination:
name: minio-root-password
transformation:
templates:
root-user: "{{ .Secrets.MINIO_ROOT_USER }}"
root-password: "{{ .Secrets.MINIO_ROOT_PASSWORD }}"
접근 제어
# 사용자 생성
mc admin user add myminio newuser newpassword
# 정책 적용
mc admin policy set myminio readwrite user=newuser
# 서비스 계정 생성
mc admin user svcacct add myminio newuser
문제 해결
일반적인 문제
1. Pod가 시작되지 않음
# 이벤트 확인
kubectl describe pod minio-0 -n minio
# 스토리지 확인
kubectl get pv | grep minio
kubectl describe pv minio-pv-worker1
일반적인 원인:
- PV가 노드에 마운트되지 않음
- 디스크 공간 부족
- 권한 문제
2. 클러스터 형성 실패
# MinIO 로그 확인
kubectl logs minio-0 -n minio
# 네트워크 연결 테스트
kubectl exec minio-0 -n minio -- nslookup minio-1.minio-headless.minio.svc.cluster.local
3. 업로드 실패
# IngressRoute 상태 확인 (표준 Ingress 아님)
kubectl get ingressroute -n minio
# Traefik 라우터 확인
kubectl describe ingressroute minio-upload-proxy -n minio
# CORS preflight 확인
curl -H "Origin: https://lumie-edu.com" \
-H "Access-Control-Request-Method: PUT" \
-H "Access-Control-Request-Headers: X-Requested-With" \
-X OPTIONS \
https://lumie-edu.com/lumie/tmp/test
성능 문제
느린 업로드/다운로드
# 네트워크 대역폭 테스트
kubectl exec minio-0 -n minio -- mc speedtest myminio
# 디스크 I/O 확인
kubectl exec minio-0 -n minio -- iostat -x 1
높은 CPU 사용률
# CPU 최적화 설정 확인
environment:
GOMAXPROCS: "2"
MINIO_SCANNER_SPEED: "slowest"
고급 설정
암호화
# 서버 사이드 암호화 (향후 구성)
environment:
MINIO_KMS_SECRET_KEY: "my-minio-key:OSMM+vkKUTCvQs9YL/CVMIMt43HFhkUpqJxTmGl6rYw="
압축
environment:
MINIO_COMPRESS: "on"
MINIO_COMPRESS_EXTENSIONS: ".txt,.log,.csv,.json"
MINIO_COMPRESS_MIME_TYPES: "text/*,application/json,application/xml"
알림 설정
# Webhook 알림 설정
mc admin config set myminio notify_webhook:1 \
endpoint="https://hooks.slack.com/services/..." \
auth_token="Bearer token"
# 버킷 이벤트 알림
mc event add myminio/lumie arn:minio:sqs::1:webhook --event put,delete
이 문서는 MinIO의 설치, 구성, 운영에 대한 포괄적인 가이드를 제공합니다. 분산 스토리지 환경에서의 고가용성과 성능 최적화에 대한 추가 정보는 MinIO 공식 문서를 참조하세요.