이 글에서는 쿠버네티스 StatefulSet의 volumeClaimTemplates 기능을 활용하여 MinIO와 같은 상태 저장 애플리케이션의 스토리지 관리를 자동화하는 방법에 대해 알아보겠습니다. 볼륨 클레임 템플릿을 통해 복제본마다 고유한 PVC를 자동으로 생성하고 관리하는 방법을 중점적으로 설명합니다.
📌 StatefulSet과 볼륨 클레임 템플릿 개요
✅ StatefulSet 복습
StatefulSet은 상태 저장 애플리케이션을 위한 쿠버네티스 워크로드 리소스로, 각 Pod에 고유한 식별자와 안정적인 네트워크 ID를 부여합니다. Deployment와 달리 Pod가 삭제되고 재생성되어도 동일한 이름과 볼륨을 유지합니다.
▶️ StatefulSet의 주요 특징:
- 예측 가능하고 고유한 Pod 이름 (name-0, name-1, ...)
- 순차적인 배포, 확장, 롤백 지원
- 안정적인 네트워크 식별자 (서비스 이름.네임스페이스.svc.cluster.local)
- 개별 Pod마다 고유한 스토리지 볼륨 지원
✅ volumeClaimTemplates란?
volumeClaimTemplates는 StatefulSet의 특별한 기능으로, 각 Pod 복제본마다 고유한 PVC를 자동으로 생성합니다. 이를 통해 상태 저장 애플리케이션에 필요한 영구 스토리지를 효율적으로 관리할 수 있습니다.
▶️ volumeClaimTemplates 주요 특징:
- StatefulSet 생성 시 각 Pod마다 PVC 자동 생성
- Pod 이름 형식에 맞춰 PVC 이름도 자동 생성 (claimname-podname-ordinal)
- Pod가 삭제되어도 PVC는 유지되어 데이터 보존
- StatefulSet 확장 시 새 Pod에 대한 PVC도 자동 생성
apiVersion: apps/v1 # StatefulSet은 apps API 그룹의 리소스
kind: StatefulSet # 리소스 종류를 StatefulSet으로 지정
metadata:
name: minio # StatefulSet 이름, Pod 이름 접두사로 사용됨
namespace: minio-system # 네임스페이스 지정
spec:
serviceName: minio-headless # 헤드리스 서비스 이름, Pod DNS 이름에 사용됨
replicas: 4 # 생성할 Pod 복제본 수, 4개의 MinIO 서버 인스턴스 생성
selector:
matchLabels:
app: minio # Pod 선택을 위한 라벨 지정
template:
metadata:
labels:
app: minio # Pod에 적용될 라벨, selector와 일치해야 함
spec:
containers:
- name: minio # 컨테이너 이름
image: minio/minio:RELEASE.2023-07-21T21-12-44Z # 안정적인 MinIO 버전 사용
# ... (컨테이너 설정 생략) ...
volumeMounts:
- name: data # 볼륨 마운트 이름, volumeClaimTemplates의 이름과 일치
mountPath: /data # 컨테이너 내부 마운트 경로
volumeClaimTemplates: # 각 Pod마다 생성될 PVC 템플릿 정의
- metadata:
name: data # 볼륨 클레임 템플릿 이름, volumeMounts 이름과 일치해야 함
spec:
accessModes: ["ReadWriteOnce"] # 단일 노드에서 읽기/쓰기 접근 모드
storageClassName: standard # 사용할 스토리지 클래스 이름
resources:
requests:
storage: 10Gi # 각 PVC에 요청할 스토리지 용량
📌 볼륨 클레임 템플릿 작동 방식
✅ 자동 PVC 생성 프로세스
StatefulSet 컨트롤러는 다음과 같은 방식으로 볼륨 클레임 템플릿을 처리합니다:
- StatefulSet 생성 시 Pod 순서에 따라 PVC 자동 생성
- PVC 이름 형식: <볼륨 클레임 템플릿 이름>-<StatefulSet 이름>-<순번>
- 예: data-minio-0, data-minio-1, data-minio-2, data-minio-3
- 각 Pod는 자신의 순번에 맞는 PVC에만 연결됨
▶️ 생성된 PVC 확인 명령어:
kubectl get pvc -n minio-system
결과 예시:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-minio-0 Bound pvc-3f8b542a-6c5c-4b1c-8a2d-3c12e1f0a1b0 10Gi RWO standard 2m
data-minio-1 Bound pvc-7f8e432b-7d6d-5c2d-9b3e-4d23f2g1b2c1 10Gi RWO standard 2m
data-minio-2 Bound pvc-8d9f547c-8e7e-6d3e-0c4f-5e34g3h2c3d2 10Gi RWO standard 2m
data-minio-3 Bound pvc-9e0g658d-9f8f-7e4f-1d5g-6f45h4i3d4e3 10Gi RWO standard 2m
✅ PVC 수명주기 관리
볼륨 클레임 템플릿으로 생성된 PVC의 수명주기는 다음과 같이 관리됩니다:
- StatefulSet 생성: PVC 자동 생성 및 Pod에 연결
- Pod 재시작: 동일한 PVC 재사용 (데이터 유지)
- StatefulSet 스케일 다운: Pod는 삭제되지만 PVC는 유지
- StatefulSet 스케일 업: 새 Pod에 기존 PVC 재연결
- StatefulSet 삭제: 기본적으로 PVC는 유지 (수동 삭제 가능)
▶️ 주의사항: StatefulSet 삭제 시 PVC 자동 삭제를 위한 옵션 (cascading deletion)
# StatefulSet과 연관된 모든 리소스(PVC 포함) 삭제
kubectl delete statefulset minio -n minio-system --cascade=foreground
📌 MinIO를 위한 볼륨 클레임 템플릿 구성
✅ 분산 MinIO 설정을 위한 볼륨 클레임 템플릿
MinIO는 분산 모드에서 여러 서버로 구성될 수 있으며, 각 서버는 고유한 데이터 저장소가 필요합니다. 이때 볼륨 클레임 템플릿이 효과적인 솔루션이 됩니다.
apiVersion: apps/v1 # apps API 그룹 버전
kind: StatefulSet # 리소스 종류
metadata:
name: minio # StatefulSet 이름
namespace: minio-system # 네임스페이스
spec:
serviceName: minio-headless # 헤드리스 서비스 이름
replicas: 4 # MinIO 분산 모드를 위한 4개 복제본
selector:
matchLabels:
app: minio # Pod 선택자
template:
metadata:
labels:
app: minio # Pod 라벨
spec:
containers:
- name: minio # 컨테이너 이름
image: minio/minio:RELEASE.2023-07-21T21-12-44Z # MinIO 이미지
args:
- server # 서버 모드로 실행
- http://minio-{0...3}.minio-headless.minio-system.svc.cluster.local/data # 분산 모드 설정
ports:
- containerPort: 9000 # API 포트
name: api
- containerPort: 9001 # 콘솔 포트
name: console
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: minio-creds # 보안을 위한 Secret 참조
key: root-user
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: minio-creds # 보안을 위한 Secret 참조
key: root-password
volumeMounts:
- name: data # 볼륨 마운트 이름
mountPath: /data # 마운트 경로
volumeClaimTemplates: # 볼륨 클레임 템플릿 정의
- metadata:
name: data # 템플릿 이름
spec:
accessModes: ["ReadWriteOnce"] # 접근 모드
storageClassName: minio-storage # 스토리지 클래스
resources:
requests:
storage: 100Gi # 분산 환경에 적합한 용량
✅ 헤드리스 서비스 구성
StatefulSet과 볼륨 클레임 템플릿을 함께 사용할 때는 안정적인 네트워크 ID를 위해 헤드리스 서비스가 필요합니다.
apiVersion: v1 # 핵심 API 그룹 버전
kind: Service # 리소스 종류
metadata:
name: minio-headless # 헤드리스 서비스 이름
namespace: minio-system # 네임스페이스
spec:
clusterIP: None # 헤드리스 서비스 지정(clusterIP: None)
ports:
- port: 9000 # API 포트
name: api
- port: 9001 # 콘솔 포트
name: console
selector:
app: minio # Pod 선택자
📌 볼륨 클레임 템플릿 고급 설정
✅ 스토리지 클래스 선택
볼륨 클레임 템플릿에서 적절한 스토리지 클래스를 선택하는 것이 중요합니다.
▶️ MinIO를 위한 스토리지 클래스 고려사항:
- 읽기/쓰기 성능: SSD 기반 스토리지 선호
- 데이터 내구성: 복제 또는 백업 지원
- 동적 확장 가능성: allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1 # 스토리지 API 그룹 버전
kind: StorageClass # 리소스 종류
metadata:
name: minio-storage # 스토리지 클래스 이름
provisioner: kubernetes.io/aws-ebs # 예: AWS EBS 프로비저너
parameters:
type: gp3 # SSD 볼륨 타입
iopsPerGB: "10" # IOPS 설정
encrypted: "true" # 암호화 활성화
reclaimPolicy: Retain # PVC 삭제 시 PV 유지
allowVolumeExpansion: true # 볼륨 크기 확장 허용
volumeBindingMode: WaitForFirstConsumer # 효율적인 바인딩 모드
✅ 용량 계획 및 확장
볼륨 클레임 템플릿을 통해 생성된 PVC는 나중에 용량 확장이 필요할 수 있습니다.
- 초기 용량 계획:
- 각 MinIO 인스턴스의 예상 데이터 크기 고려
- 성장 예측을 포함한 적절한 초기 크기 할당
- 스토리지 오버헤드 감안 (일반적으로 10-20% 추가)
- PVC 용량 확장:
- allowVolumeExpansion: true 설정된 스토리지 클래스 사용
- kubectl edit 또는 patch 명령으로 PVC 크기 변경
# PVC 편집하여 크기 증가
kubectl edit pvc data-minio-0 -n minio-system
# 또는 patch 명령 사용
kubectl patch pvc data-minio-0 -n minio-system -p '{"spec":{"resources":{"requests":{"storage":"200Gi"}}}}'
▶️ 주의사항: PVC 용량은 증가만 가능하며 감소는 불가능합니다.
📌 볼륨 클레임 템플릿 백업 및 복구 전략
✅ MinIO 데이터 백업 방법
볼륨 클레임 템플릿으로 생성된 PVC에 저장된 MinIO 데이터를 백업하는 방법입니다.
- 스냅샷 기반 백업:
- 클라우드 제공업체의 볼륨 스냅샷 기능 활용
- VolumeSnapshot 리소스 사용 (필요한 컨트롤러 설치 필요)
apiVersion: snapshot.storage.k8s.io/v1 # 스냅샷 API 그룹
kind: VolumeSnapshot # 리소스 종류
metadata:
name: minio-data-0-snapshot # 스냅샷 이름
namespace: minio-system # 네임스페이스
spec:
volumeSnapshotClassName: csi-snapclass # 스냅샷 클래스
source:
persistentVolumeClaimName: data-minio-0 # 스냅샷 대상 PVC
- MinIO 자체 백업 도구 활용:
- mc 명령줄 도구를 통한 버킷 미러링
- MinIO 객체 수준 백업
apiVersion: batch/v1 # 배치 API 그룹
kind: CronJob # 리소스 종류
metadata:
name: minio-backup # CronJob 이름
namespace: minio-system # 네임스페이스
spec:
schedule: "0 1 * * *" # 매일 01:00에 실행
jobTemplate:
spec:
template:
spec:
containers:
- name: mc-backup # 컨테이너 이름
image: minio/mc # MinIO 클라이언트 이미지
command:
- /bin/sh
- -c
- |
# MinIO 클라이언트 설정
mc alias set source http://minio-0.minio-headless:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD
mc alias set target http://backup-storage:9000 $BACKUP_USER $BACKUP_PASSWORD
# 버킷 미러링
mc mirror --watch source/mybucket target/mybucket-backup
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: minio-creds
key: root-user
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: minio-creds
key: root-password
# ... (백업 자격 증명) ...
restartPolicy: OnFailure
✅ 데이터 복구 전략
볼륨 클레임 템플릿으로 관리되는 MinIO 데이터의 복구 전략입니다.
- 스냅샷에서 PVC 복원:
- VolumeSnapshotContent에서 새 PVC 생성
- StatefulSet을 일시 중지하고 복원된 볼륨 연결
apiVersion: v1 # 핵심 API 그룹
kind: PersistentVolumeClaim # 리소스 종류
metadata:
name: recovered-data-minio-0 # 복구된 PVC 이름
namespace: minio-system # 네임스페이스
spec:
dataSource:
name: minio-data-0-snapshot # 스냅샷 소스
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce # 접근 모드
resources:
requests:
storage: 100Gi # 스토리지 용량
- 객체 수준 복구:
- MinIO 클라이언트 도구를 사용한 객체 복원
- StatefulSet 재배포 및 데이터 검증
📌 볼륨 클레임 템플릿 모니터링 및 관리
✅ 스토리지 사용량 모니터링
볼륨 클레임 템플릿으로 생성된 PVC의 스토리지 사용량을 모니터링하는 방법입니다.
- 기본 모니터링 명령어:
# PVC 상태 확인
kubectl get pvc -n minio-system
# PV 상세 정보 확인
kubectl describe pv $(kubectl get pvc data-minio-0 -n minio-system -o jsonpath='{.spec.volumeName}')
- 고급 모니터링:
- Prometheus와 Grafana를 사용한 PV 사용량 모니터링
- kube-state-metrics를 통한 PVC 메트릭 수집
apiVersion: monitoring.coreos.com/v1 # Prometheus Operator API
kind: ServiceMonitor # 리소스 종류
metadata:
name: minio-pv-monitor # 모니터 이름
namespace: monitoring # 네임스페이스
spec:
selector:
matchLabels:
app: kube-state-metrics # 메트릭 수집 대상
endpoints:
- port: http-metrics # 메트릭 포트
interval: 30s # 수집 간격
path: /metrics # 메트릭 경로
✅ 효율적인 용량 관리
볼륨 클레임 템플릿으로 생성된 PVC의 용량을 효율적으로 관리하는 방법입니다.
- 사용량 경고 설정:
- 임계값 기반 알림 구성 (80% 이상 사용 시)
- 자동 확장 정책 구현 (선택적)
- 데이터 정리 및 최적화:
- MinIO 객체 수명 주기 정책 설정
- 임시 데이터 주기적 정리
# MinIO 버킷 수명 주기 정책 예시 (mc 명령어 대체)
{
"rules": [
{
"id": "expire-old-logs",
"status": "Enabled",
"filter": {
"prefix": "logs/"
},
"expiration": {
"days": 30
}
}
]
}
📌 Summary
- StatefulSet의 volumeClaimTemplates는 각 Pod 복제본마다 고유한 PVC를 자동 생성
- 복제본 번호에 맞게 PVC 이름이 생성되어 Pod와 1:1 매핑됨
- MinIO 분산 배포 시 각 서버 인스턴스에 안정적인 스토리지 제공
- 헤드리스 서비스와 함께 사용하여 안정적인 네트워크 ID 부여
- 스토리지 클래스 설정을 통해 성능과 데이터 내구성 최적화
- 볼륨 확장, 백업 및 복구 전략 구현 가능
- 모니터링 도구를 통해 스토리지 상태와 용량 관리 가능
- 자동화된 스토리지 관리로 운영 부담 감소