はじめに
- Kubernetes上でシステムを構築・運用していると、Namespace間でPVCを共有したいと思ったことはありませんか?
- Namespace間でのデータの受け渡しであれば、Amazon S3のようなオブジェクトストレージであったりメッセージキューであったりを使えばいいのですが、手っ取り早くPVC自体を共有できたらいいのにという場面はあると思います。
- 本記事では、ネットアップが提供するCSI driver「Astra Trident」を使ってNamespace間でPVCを共有してみます。
いきなり結論:できた
設定内容
- Namespace間でのPVCの共有には以下の設定が必要です。
PersistentVolumeClaim(PVC)への設定
- PVCのマニフェスト内で
shareToNamespace
というアノテーションを使って共有先となるNamespaceを以下のように定義します。(Namespace「ns1」の「pvc1」をNamespace「ns2」に共有する場合)pvc1.yamlkind: PersistentVolumeClaim apiVersion: v1 metadata: annotations: trident.netapp.io/shareToNamespace: ns2 name: pvc1 namespace: ns1 spec: accessModes: - ReadWriteMany storageClassName: fsx-sc resources: requests: storage: 10Gi
- 共有される側のPVCのマニフェスト内でも、
shareFromPVC
というアノテーションを使って以下のように定義します。(Namespace「ns2」にNamespace「ns1」の「pvc1」が共有される場合)pvc2.yamlkind: PersistentVolumeClaim apiVersion: v1 metadata: annotations: trident.netapp.io/shareFromPVC: ns1/pvc1 name: pvc2 namespace: ns2 spec: accessModes: - ReadWriteMany storageClassName: fsx-sc resources: requests: storage: 10Gi
TridentVolumeReference(TVR)の作成
- これはAstra Tridentが使用するアクセス制御用のKubernetesのカスタムリソースで、共有される側のNamespace(今回の例では「ns2」)で以下のように定義します。
tvr-ns1-to-ns2.yaml
apiVersion: trident.netapp.io/v1 kind: TridentVolumeReference metadata: name: tvr-ns1-to-ns2 namespace: ns2 spec: pvcName: pvc1 pvcNamespace: ns1
注意事項
- Astra Tridentでは、共有されたボリュームに対する共有先のNamespaceからの書き込みを防ぐことはできません。必要に応じてファイルロックなどで制御する必要があります。
- PVCのマニフェスト内のアノテーション
shareToNamespace
、shareFromPVC
やTridentVolumeReferenceを削除しても共有先PVCへのアクセスを取り消すことはできません。アクセスを取り消すには、共有先PVC自体を削除する必要があります。 - 共有先PVCではSnapshotやcloneを使うことはできません。
ここから先は具体的な手順になるので、興味が無ければ読み飛ばしても問題ありません。
やったこと
前提
- 以下は準備済みとします。
- Kubernetesクラスタ
- ONTAPが動くストレージ(今回はAmazon FSx for NetApp ONTAPを使用)
- KubernetesクラスタへのAstra Trident(v22.10)のインストールとバックエンドの設定(詳細手順はこちら)
StorageClass作成
- バックエンド設定を確認します。
# tridentctl -n trident get backend +-------------+----------------+--------------------------------------+--------+---------+ | NAME | STORAGE DRIVER | UUID | STATE | VOLUMES | +-------------+----------------+--------------------------------------+--------+---------+ | fsx_backend | ontap-nas | 98f0f5f9-eeb1-4c13-b390-a8377cb5c8fb | online | 0 | +-------------+----------------+--------------------------------------+--------+---------+
- StorageClassのマニフェストは以下の通りです。
fsx-sc.yaml
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fsx-sc provisioner: csi.trident.netapp.io parameters: backendType: "ontap-nas" fsType: "ext4"
- StorageClassを作成します。
# kubectl apply -f fsx-sc.yaml storageclass.storage.k8s.io/fsx-sc created
- StorageClassが作成されていることを確認します。
# kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE fsx-sc csi.trident.netapp.io Delete Immediate false 10s
- ちなみに、ストレージ側を見てみると、まだ何もボリュームは作られていません。(
st_trident_svm1_root
とvol1
はデフォルトで作成されるボリュームなのでノーカウント。)::> volume show Vserver Volume Aggregate State Type Size Available Used% -------------- -------------------- ------------ ---------- ---- ---------- ---------- ----- st-trident-svm1 st_trident_svm1_root aggr1 online RW 1GB 972.2MB 0% st-trident-svm1 vol1 aggr1 online RW 10GB 9.50GB 0% 2 entries were displayed.
Namespace作成
- Namespace「ns1」を作成します。
# kubectl create namespace ns1 namespace/ns1 created
- Namespace「ns2」を作成します。
# kubectl create namespace ns2 namespace/ns2 created
- Namespaceが作成されていることを確認します。
# kubectl get namespaces NAME STATUS AGE default Active 23m kube-flannel Active 22m kube-node-lease Active 23m kube-public Active 23m kube-system Active 23m ns1 Active 20s ns2 Active 10s trident Active 17m
PVC1作成
- PVC1のマニフェストは以下の通りです。
pvc1.yaml
kind: PersistentVolumeClaim apiVersion: v1 metadata: annotations: trident.netapp.io/shareToNamespace: ns2 name: pvc1 namespace: ns1 spec: accessModes: - ReadWriteMany storageClassName: fsx-sc resources: requests: storage: 10Gi
- PVC1を作成します。
# kubectl apply -f pvc1.yaml persistentvolumeclaim/pvc1 created
- ストレージ側を見てみると、Astra Tridentによって作成されたボリューム(
trident_pvc_
で始まるもの)が1つできていました。::> volume show Vserver Volume Aggregate State Type Size Available Used% -------------- ------------------------------------------------ ------------ ---------- ---- ---------- ---------- ----- st-trident-svm1 st_trident_svm1_root aggr1 online RW 1GB 972.2MB 0% st-trident-svm1 trident_pvc_5d442ce8_f79c_4613_b896_be78860a9c90 aggr1 online RW 10GB 10.00GB 0% st-trident-svm1 vol1 aggr1 online RW 10GB 9.50GB 0% 3 entries were displayed.
TridentVolumeReference作成
- TridentVolumeReferenceのマニフェストは以下の通りです。
tvr-ns1-to-ns2.yaml
apiVersion: trident.netapp.io/v1 kind: TridentVolumeReference metadata: name: tvr-ns1-to-ns2 namespace: ns2 spec: pvcName: pvc1 pvcNamespace: ns1
- TridentVolumeReferenceを作成します。
# kubectl apply -f tvr-ns1-to-ns2.yaml tridentvolumereference.trident.netapp.io/tvr-ns1-to-ns2 created
PVC2作成
- PVC2のマニフェストは以下の通りです。
pvc2.yaml
kind: PersistentVolumeClaim apiVersion: v1 metadata: annotations: trident.netapp.io/shareFromPVC: ns1/pvc1 name: pvc2 namespace: ns2 spec: accessModes: - ReadWriteMany storageClassName: fsx-sc resources: requests: storage: 10Gi
- PVC2を作成します。
# kubectl apply -f pvc2.yaml persistentvolumeclaim/pvc2 created
- 作成されているPVCを確認します。
# kubectl get pvc --all-namespaces NAMESPACE NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE ns1 pvc1 Bound pvc-5d442ce8-f79c-4613-b896-be78860a9c90 10Gi RWX fsx-sc 6m34s ns2 pvc2 Bound pvc-6a5a270e-e0fe-4967-a1aa-e9ca54f3336a 10Gi RWX fsx-sc 26s
- Astra Trident側で確認するとこんな感じでした。
# tridentctl get volume -n trident +------------------------------------------+--------+---------------+----------+--------------------------------------+-------------+---------+ | NAME | SIZE | STORAGE CLASS | PROTOCOL | BACKEND UUID | STATE | MANAGED | +------------------------------------------+--------+---------------+----------+--------------------------------------+-------------+---------+ | pvc-5d442ce8-f79c-4613-b896-be78860a9c90 | 10 GiB | fsx-sc | file | 98f0f5f9-eeb1-4c13-b390-a8377cb5c8fb | online | true | | pvc-6a5a270e-e0fe-4967-a1aa-e9ca54f3336a | 10 GiB | fsx-sc | file | 98f0f5f9-eeb1-4c13-b390-a8377cb5c8fb | subordinate | true | +------------------------------------------+--------+---------------+----------+--------------------------------------+-------------+---------+
- ストレージ側を見てみると、Astra Tridentによって作成されたボリューム(
trident_pvc_
で始まるもの)が1つだけでした。2つのPVCで1つのボリュームを共有していることがわかります。::> volume show Vserver Volume Aggregate State Type Size Available Used% -------------- ------------------------------------------------ ------------ ---------- ---- ---------- ---------- ----- st-trident-svm1 st_trident_svm1_root aggr1 online RW 1GB 972.2MB 0% st-trident-svm1 trident_pvc_5d442ce8_f79c_4613_b896_be78860a9c90 aggr1 online RW 10GB 10.00GB 0% st-trident-svm1 vol1 aggr1 online RW 10GB 9.50GB 0% 3 entries were displayed.
PVCをマウントしてみて確認
PVC1をマウントするPodを作成
- Namespace「ns1」に作成するPodのマニフェストは以下の通りです。
ns1-centos-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: ns1-centos namespace: ns1 labels: app: ns1-centos spec: selector: matchLabels: app: ns1-centos template: metadata: labels: app: ns1-centos spec: containers: - image: centos:8 name: ns1-centos command: - "/sbin/init" volumeMounts: - name: ns1-pvc1 mountPath: /mnt securityContext: allowPrivilegeEscalation: true capabilities: {} privileged: true readOnlyRootFilesystem: false seLinuxOptions: {} volumes: - name: ns1-pvc1 persistentVolumeClaim: claimName: pvc1
- Namespace「ns1」にCentOSのPodを作成します。
# kubectl apply -f ns1-nccentos-deployment.yaml deployment.apps/ns1-centos created
- Podが作成されていることを確認します。
# kubecrtl get pods -n ns1 NAME READY STATUS RESTARTS AGE ns1-centos-787447579d-xfnx4 0/1 ContainerCreating 0 11s
PVC1にファイルを書き込み
- PVC1がマウントされているPodのシェルを取得します。
# kubectl exec -n ns1 -it ns1-centos-787447579d-xfnx4 /bin/bash
- PVCがマウントされていることを確認します。
# df Filesystem 1K-blocks Used Available Use% Mounted on overlay 8376300 4492116 3884184 54% / tmpfs 65536 0 65536 0% /dev tmpfs 991916 0 991916 0% /sys/fs/cgroup 10.0.1.48:/trident_pvc_5d442ce8_f79c_4613_b896_be78860a9c90 10485760 320 10485440 1% /mnt /dev/nvme0n1p1 8376300 4492116 3884184 54% /etc/hosts shm 65536 0 65536 0% /dev/shm tmpfs 991916 8204 983712 1% /run
- 適当にファイルを書き込んでみます。
# echo "Hello from ns1." > /mnt/test.txt
- ファイルの中身を確認します。
# cat /mnt/test.txt Hello from ns1.
PVC2をマウントするPodを作成
- Namespace「ns2」に作成するPodのマニフェストは以下の通りです。
ns2-centos-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: ns2-centos namespace: ns2 labels: app: ns2-centos spec: selector: matchLabels: app: ns2-centos template: metadata: labels: app: ns2-centos spec: containers: - image: centos:8 name: ns2-centos command: - "/sbin/init" volumeMounts: - name: ns2-pvc2 mountPath: /mnt securityContext: allowPrivilegeEscalation: true capabilities: {} privileged: true readOnlyRootFilesystem: false seLinuxOptions: {} volumes: - name: ns2-pvc2 persistentVolumeClaim: claimName: pvc2
- Namespace「ns2」にCentOSのPodを作成します。
# kubectl apply -f ns2-nccentos-deployment.yaml deployment.apps/ns2-centos created
- Podが作成されていることを確認します。
# kubecrtl get pods -n ns2 NAME READY STATUS RESTARTS AGE ns1-centos-787447579d-xfnx4 0/1 ContainerCreating 0 11s
PVC2の中身を確認
- PVC2がマウントされているPodのシェルを取得します。
# kubectl exec -n ns2 -it ns2-centos-6dd94ccd9c-t4x2n /bin/bash
- PVCがマウントされていることを確認します。PVC1と同じパスです。
# df Filesystem 1K-blocks Used Available Use% Mounted on overlay 8376300 4492888 3883412 54% / tmpfs 65536 0 65536 0% /dev tmpfs 991916 0 991916 0% /sys/fs/cgroup 10.0.1.48:/trident_pvc_5d442ce8_f79c_4613_b896_be78860a9c90 10485760 320 10485440 1% /mnt /dev/nvme0n1p1 8376300 4492888 3883412 54% /etc/hosts shm 65536 0 65536 0% /dev/shm tmpfs 991916 8208 983708 1% /run
- PVC内のファイルの中身を確認します。PVC1で書き込んだファイルがありました。
# cat /mnt/test.txt Hello from ns1.
- できました!
まとめ
- このような感じで、Astra Tridentの機能で簡単にNamespace間で動的にPVCを共有することができました。