개요
Rook-Ceph 구축 이후 Ceph StorageClass를 활용하면 Kubernetes Pod에서 PVC(PersistentVolumeClaim)를 통해 Ceph RBD(RADOS Block Device) 기반의 영구 볼륨을 동적으로 프로비저닝할 수 있습니다. Pod가 삭제되거나 재스케줄링되어도 데이터가 Ceph에 안전하게 보존됩니다.
이 글에서는 Ceph RBD StorageClass를 생성하고, PVC가 포함된 MySQL과 WordPress Deployment를 배포하는 전체 절차를 정리합니다. MetalLB LoadBalancer를 통해 WordPress에 외부 IP가 할당되어 실제 서비스 접근까지 확인합니다. 이 구성은 Rook-Ceph 구축이 완료된 환경을 전제합니다.
사전 준비
이 절차를 진행하기 전에 다음 구성 요소가 준비되어 있어야 합니다.
- Rook-Ceph 클러스터가 정상 기동 중 (
ceph status에서HEALTH_OK) - MetalLB가 구성되어 있고 LoadBalancer IP 풀이 설정된 상태
- Rook 저장소 클론이 로컬에 존재 (
rook/deploy/examples/디렉토리 필요)
Rook 예제 디렉토리에는 mysql.yaml, wordpress.yaml, csi/rbd/storageclass.yaml이 포함되어 있습니다. 이 파일들을 기반으로 StorageClass를 생성하고 WordPress와 MySQL을 배포합니다.
Ceph StorageClass 생성
Rook 저장소의 csi/rbd/storageclass.yaml을 적용하면 rook-ceph-block StorageClass가 생성됩니다. 이후 Pod에서 storageClassName: rook-ceph-block으로 PVC를 요청하면 Ceph RBD 볼륨이 자동으로 생성·마운트됩니다.
StorageClass의 reclaimPolicy: Delete는 PVC 삭제 시 볼륨도 함께 삭제됨을 의미합니다. 데이터를 보존해야 하는 경우 Retain으로 변경해야 합니다. allowVolumeExpansion: true로 설정되어 있어 운영 중에도 PVC의 용량을 늘릴 수 있습니다.
kubectl apply -f csi/rbd/storageclass.yaml kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true

MySQL Deployment 배포 (PVC 포함)
Service, PersistentVolumeClaim, Deployment가 포함된 MySQL manifest를 배포합니다. PVC가 생성되면 Rook CSI 드라이버가 Ceph 클러스터에 RBD 이미지를 자동으로 생성하고, kubelet이 해당 볼륨을 Pod에 마운트합니다. PVC Status가 Bound이면 Ceph RBD 볼륨이 정상 마운트된 것입니다.
MySQL Deployment의 환경변수(MYSQL_ROOT_PASSWORD 등)는 실제 운영 환경에서 Secret 리소스로 분리하는 것을 권장합니다. 또한 MySQL 데이터 디렉토리(/var/lib/mysql)를 PVC에 마운트하므로, Pod를 재시작하거나 노드가 변경되어도 데이터가 보존됩니다.
kubectl create -f mysql.yaml service/wordpress-mysql created persistentvolumeclaim/mysql-pv-claim created deployment.apps/wordpress-mysql created kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mysql-pv-claim Bound pvc-6d458ff1-54bf-4f34-b010-a0f4b2a0966e 20Gi RWO rook-ceph-block 94s
WordPress Deployment 배포 (PVC 포함)
MySQL과 동일하게 Service, PVC, Deployment가 포함된 WordPress manifest를 배포합니다. WordPress는 업로드 파일 등을 /var/www/html에 저장하는데, 이 디렉토리가 PVC에 마운트되어 Pod 재시작 후에도 데이터가 유지됩니다. WordPress 서비스 타입은 LoadBalancer로 설정되어 MetalLB로부터 외부 IP를 할당받습니다.
kubectl create -f wordpress.yaml service/wordpress created persistentvolumeclaim/wp-pv-claim created deployment.apps/wordpress created kubectl get pod NAME READY STATUS RESTARTS AGE wordpress-7cf5c5c8b-5cgqk 1/1 Running 0 42s wordpress-mysql-6f99c59595-9vs7z 1/1 Running 0 4m8s
MetalLB로 외부 접근 확인
MetalLB가 구성된 환경에서는 WordPress Service에 외부 IP가 자동 할당됩니다. 해당 IP로 브라우저에서 접속하면 WordPress 설치 화면이 표시되며, Ceph 기반 영구 스토리지 구성이 완료된 것입니다.
이 구성에서 WordPress와 MySQL은 서로 다른 Ceph RBD PVC를 사용합니다. 스토리지 레이어가 Ceph로 추상화되어 있기 때문에, 향후 WordPress나 MySQL Pod를 다른 Worker 노드로 재스케줄링해도 동일한 데이터에 접근할 수 있습니다. PVC의 accessMode: ReadWriteOnce(RWO) 특성상 한 번에 한 Pod만 볼륨에 마운트할 수 있으며, 수평 확장이 필요한 경우에는 CephFS(RWX)를 사용해야 합니다.
kubectl get svc wordpress NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE wordpress LoadBalancer x.x.x.x x.x.x.x 80:31494/TCP 27s
배포 결과 및 볼륨 확인
모든 리소스 배포 후 아래 명령어로 최종 상태를 확인합니다. PVC가 Bound, Pod가 Running, Service에 외부 IP가 할당된 것이 정상 상태입니다.
# PVC 상태 확인 (Bound이면 정상) kubectl get pvc # Pod 상태 확인 kubectl get pods # WordPress Service 외부 IP 확인 kubectl get svc wordpress # Ceph에서 실제 RBD 이미지 확인 (Toolbox Pod 내에서) kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash rbd ls replicapool
PVC가 Pending 상태에서 멈추는 경우 주요 원인으로는 Ceph 클러스터 상태 이상(HEALTH_WARN 이상), StorageClass 미적용, 또는 Rook CSI 드라이버 Pod 이상이 있습니다. kubectl describe pvc <pvc-name>으로 이벤트를 확인하고 조치합니다.
참고
관련 포스트:
참고 문서: Rook Ceph Block Storage 공식 문서 · Kubernetes Persistent Volumes 공식 문서


