Zum Hauptinhalt springen

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-worker1k3s-master0214구 worker-1 디스크 이전 (2026-04)
minio-pv-worker2k3s-worker-20214
minio-pv-worker3k3s-worker-30213
minio-pv-worker4k3s-worker-40213

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는 메서드 필터 미들웨어를 지원하지 않아, 메서드 매칭이 가능한 IngressRoute CRD를 사용
  • 경로 제한: 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-backupsKubernetes 리소스 + 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_totalS3 API 요청 수
minio_s3_errors_totalS3 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 공식 문서를 참조하세요.