Volume provisioning failed with infeasible error:
multi node access modes are only supported on rbd `block` type volumes
RBD 는 블록 장치다. 파일 시스템 모드(volumeMode: Filesystem)에서는 한 노드만 마운트할 수 있으므로 ReadWriteOnce 만 된다. ReadWriteMany 는 raw block 모드에서 제한적으로만 허용되는데, 그때는 파일 시스템 정합성을 애플리케이션이 직접 책임져야 해서 일반적인 용도에는 맞지 않는다.
| 접근 모드 | RBD (Filesystem) | CephFS |
|---|---|---|
| ReadWriteOnce | 가능 | 가능 |
| ReadWriteOncePod | 가능 | 가능 |
| ReadWriteMany | 불가 | 가능 |
선택지는 셋이다. 공유가 필요 없으면 ReadWriteOnce 로 바꾼다. 여러 파드가 같은 디렉터리를 읽어야 하면 CephFS StorageClass 를 쓴다. 그리고 애초에 볼륨이 필요한지 다시 본다 — 설정 파일이나 비밀번호 파일처럼 작고 변하지 않는 데이터는 ConfigMap 이나 Secret 으로 넣는 편이 맞다. 볼륨을 쓰면 접근 모드·프로비저닝·백업이 따라붙는다.
apiVersion: ceph.rook.io/v1
kind: CephFilesystem
metadata:
name: rook-cephfs-retain
namespace: rook-ceph
spec:
metadataPool:
replicated:
size: 3
dataPools:
- name: data1
replicated:
size: 3
preserveFilesystemOnDelete: true
metadataServer:
activeCount: 1
activeStandby: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: filesystem-sc-retain
provisioner: rook-ceph.cephfs.csi.ceph.com
parameters:
clusterID: rook-ceph
fsName: rook-cephfs-retain
pool: data1
csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
- noatime
pool 에 적는 이름은 CephFilesystem 의 dataPools[].name 과 같아야 한다. Rook 이 만드는 실제 풀 이름은 <파일시스템이름>-<풀이름> 형태지만 StorageClass 에는 풀 이름만 적는다.
invalid pool layout 'data0' -- need a valid data pool
StorageClass 의 pool 이 그 파일 시스템에 없는 이름이다. 파일 시스템을 여러 개 만들어 두고 서로 다른 풀 이름을 쓸 때 헷갈린다. 실제 값을 확인한다.
kubectl -n rook-ceph get cephfilesystem
kubectl -n rook-ceph get cephfilesystem rook-cephfs-retain -o jsonpath='{.spec.dataPools[*].name}'
kubectl -n rook-ceph exec deploy/rook-ceph-tools -- ceph fs ls
StorageClass 의 parameters 는 만든 뒤에 바꿀 수 없다. 클래스를 지웠다 다시 만들고, 실패한 PVC 도 지우고 다시 만들어야 반영된다.
Status: Pending
Normal ExternalProvisioning waiting for a volume to be created by external provisioner
이 메시지 자체는 정상 흐름이다. 다만 수십 초 안에 Bound 가 되지 않으면 아래를 순서대로 본다.
kubectl -n rook-ceph get cephfilesystem # Ready 여야 한다
kubectl -n rook-ceph get pod | grep -E 'mds|cephfsplugin' # MDS 와 CSI 파드
kubectl -n rook-ceph logs -l app=csi-cephfsplugin-provisioner -c csi-provisioner --tail=100
MDS 파드가 없으면 파일 시스템이 아직 준비되지 않은 것이라 PVC 는 계속 대기한다. StorageClass 를 고친 직후라면 프로비저너가 옛 값을 들고 있는 경우가 있어, 프로비저너 파드를 지워 다시 뜨게 하면 풀리기도 한다.
kubectl -n rook-ceph delete pod -l app=csi-cephfsplugin-provisioner
CSI 노드 플러그인은 DaemonSet 으로 모든 워커에 있어야 한다. 실제 마운트는 워커의 kubelet 이 수행하므로 노드 플러그인이 없는 노드에 스케줄된 파드는 볼륨을 붙이지 못한다.