1️⃣ 개요
쿠버네티스에서 StatefulSet을 사용할 때 Persistent Volume(PV)을 수동으로 생성하는 것은 운영상의 부담이 될 수 있습니다.
이를 해결하기 위해 StorageClass를 활용한 동적 프로비저닝(Dynamic Provisioning)을 적용하면, PVC가 요청될 때 자동으로 PV가 생성됩니다.
이번 글에서는 StatefulSet에서 동적 스토리지 프로비저닝을 설정하는 방법과, 이를 효과적으로 활용하는 전략을 설명하겠습니다. 🚀
2️⃣ StatefulSet에서 동적 프로비저닝이 필요한 이유
📌 동적 프로비저닝이 필요한 이유
문제점 | 기존 방식 (수동 PV 생성) | 동적 프로비저닝 활용 시 장점 |
운영 부담 | 관리자가 직접 PV를 생성해야 함 | PVC 요청 시 자동으로 PV 할당 |
유연성 부족 | 사전에 PV 크기를 고정해야 함 | 필요할 때 자동 확장 가능 |
스토리지 낭비 | 미리 생성된 PV가 사용되지 않을 수도 있음 | 필요한 만큼만 생성되어 리소스 절약 |
✅ StorageClass를 활용하면 StatefulSet이 필요할 때만 PV를 자동으로 생성하고, 불필요한 리소스를 절약할 수 있습니다.
3️⃣ StatefulSet에서 동적 프로비저닝 설정 방법
✅ 1. StorageClass 생성하기
StorageClass는 PVC 요청이 발생할 때 PV를 자동으로 생성하는 역할을 합니다.
📌 AWS EBS를 사용하는 StorageClass 예제
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
reclaimPolicy: Retain
allowVolumeExpansion: true # PVC 크기 확장 가능
📌 StorageClass 적용
kubectl apply -f storageclass.yaml
✅ 이제 fast-storage StorageClass를 사용하여 StatefulSet이 자동으로 PV를 생성할 수 있습니다.
✅ 2. StatefulSet에서 동적 프로비저닝 적용하기
이제 StatefulSet에서 StorageClass를 지정하여 PVC가 자동 생성되도록 설정합니다.
📌 StorageClass를 활용한 StatefulSet 예제
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
storageClassName: fast-storage # StorageClass 지정
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
📌 StatefulSet 적용 후 PVC 자동 생성 확인
kubectl get pvc
출력 예시:
NAME STATUS VOLUME CAPACITY STORAGECLASS ACCESS MODES
mysql-data-mysql-0 Bound pvc-1234abcd 10Gi fast-storage RWO
mysql-data-mysql-1 Bound pvc-5678efgh 10Gi fast-storage RWO
mysql-data-mysql-2 Bound pvc-9101ijkl 10Gi fast-storage RWO
✅ 이제 StatefulSet이 생성될 때마다 자동으로 PV가 할당됩니다.
4️⃣ StatefulSet에서 동적 프로비저닝 활용 전략
✅ 1. PVC 크기 동적 확장 (Allow Volume Expansion)
기본적으로 PVC는 크기를 변경할 수 없지만, allowVolumeExpansion: true를 설정하면 동적으로 크기를 조정할 수 있습니다.
📌 PVC 크기 변경 예제
kubectl patch pvc mysql-data-mysql-0 -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
✅ 이제 기존 PVC의 크기를 10Gi → 20Gi로 확장할 수 있습니다.
✅ 2. PVC 자동 삭제 설정 (Reclaim Policy)
PV가 더 이상 사용되지 않을 때 자동으로 삭제되도록 설정할 수 있습니다.
• Retain → PV를 유지 (데이터 복구 가능)
• Delete → PV를 자동 삭제 (완전히 제거됨)
📌 기본적으로 StatefulSet은 Retain을 사용하는 것이 안전
reclaimPolicy: Retain
✅ 데이터 복구가 필요한 경우 Retain을 설정하고, 자동 삭제가 필요한 경우 Delete를 설정하면 됩니다.
✅ 3. 특정 노드에 스토리지 고정 (Node Affinity)
특정 노드에서만 PV를 사용할 수 있도록 제한할 수도 있습니다.
📌 PV를 특정 노드에서만 사용하도록 설정하는 예제
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-mysql-0
spec:
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node-1
accessModes:
- ReadWriteOnce
capacity:
storage: 10Gi
hostPath:
path: "/mnt/data/mysql-0"
✅ 이제 node-1에서만 PV를 사용할 수 있도록 제한됩니다.
5️⃣ StatefulSet의 PVC 동적 프로비저닝 문제 해결 방법
✅ 1. PVC가 Pending 상태에서 멈춰 있을 때
📌 PVC가 Pending 상태인지 확인
kubectl get pvc
📌 스토리지 클래스가 올바르게 설정되었는지 확인
kubectl get storageclass
📌 PVC가 바인딩되지 않는 경우 강제로 삭제 후 재생성
kubectl delete pvc mysql-data-mysql-0
kubectl rollout restart statefulset mysql
✅ PVC가 Pending 상태에서 해결되지 않는 경우, StorageClass 설정을 다시 점검해야 합니다.
✅ 2. PV가 자동 삭제되지 않는 경우
📌 PV 상태 확인
kubectl get pv
📌 PV를 수동으로 삭제
kubectl delete pv pv-mysql-0
✅ StorageClass의 reclaimPolicy가 Retain으로 설정된 경우, 수동으로 삭제해야 할 수도 있습니다.
🔥 6️⃣ 결론
✔ StorageClass를 활용하면 StatefulSet의 PVC를 자동으로 생성할 수 있어 운영 부담이 줄어듦
✔ allowVolumeExpansion: true 설정을 통해 PVC 크기를 동적으로 확장 가능
✔ Retain 또는 Delete 설정을 통해 PV 자동 삭제 여부를 결정할 수 있음
✔ Node Affinity를 활용하면 특정 노드에서만 PV를 사용하도록 제한 가능
✔ PVC가 Pending 상태에서 멈춘 경우 StorageClass 설정을 다시 확인해야 함