はじめに
Rookが管理するストレージサービスは複数存在し、そのひとつにNFSがあります。Rookではnfsservers.nfs.rook.io
というCRDを利用することで、Kubernetes上にNFSを用意し、アプリケーションから利用することができます。
※参考リンク:
一方で、Rookの管理する別のストレージサービスであるCephにもNFSを利用できる機能が備わっています。Rook-CephではNFS-Ganeshaを利用してゲートウェイを用意し、CephのストレージリソースをNFS Gatewayを通じて利用できます。
Rook-Ceph NFS GatewayとRook NFS Serverとは、以下の点で違いがあります。
- それぞれ専用のOperatorを利用し、他方のOperatorを必要としない
- NFS server PodはバックエンドにCephFS / RGWを利用し、CephFS / RGWをPVC経由でNFS Podにマウントする必要はない
Rook-Ceph NFS Gatewayはcephnfs.ceph.rook.io
というCRDが用意されており、これをデプロイすることでNFS Gatewayがデプロイされます。一方、Cephの公式ブログなどではこのCRDを利用せず、NFS関連の設定をイチから行う例が紹介されています。
今回は①手動でNFS用リソースを用意する場合②cephnfs.ceph.rook.io
CRDを利用する場合の2つを紹介します。
検証環境
今回は以下の検証環境を利用しました。
- Rook version: v1.2
- Kubernetes version:v1.17.4
- Kubernetes構成:master / worker それぞれ1ノードずつ用意
- その他:AzureVM上にkubeadmを利用して構築、CNIはflannelを利用
事前準備
今回の紹介内容に共通で必要となるRook-Cephクラスターをあらかじめ用意しておきます。
# 3つのyamlファイルをデプロイ [root@rookmaster ceph]# kubectl apply -f common.yaml [root@rookmaster ceph]# kubectl apply -f operator.yaml [root@rookmaster ceph]# kubectl apply -f cluster-test.yaml [root@rookmaster ceph]# kubectl get pods -n rook-ceph NAME READY STATUS RESTARTS AGE csi-cephfsplugin-cdtdj 3/3 Running 0 22m csi-cephfsplugin-provisioner-7b8fbf88b4-78j7l 4/4 Running 0 22m csi-cephfsplugin-provisioner-7b8fbf88b4-rqsqp 4/4 Running 0 22m csi-rbdplugin-9xvv4 3/3 Running 0 22m csi-rbdplugin-provisioner-6b8b4d558c-rzbdd 5/5 Running 0 22m csi-rbdplugin-provisioner-6b8b4d558c-spvjz 5/5 Running 0 22m rook-ceph-crashcollector-rookworker-58db759fb9-nwlvh 1/1 Running 0 19m rook-ceph-mgr-a-5955db5c76-wn56j 1/1 Running 0 20m rook-ceph-mon-a-7b99cd7876-lt55t 1/1 Running 0 20m rook-ceph-operator-69f856fc5f-z85hd 1/1 Running 0 23m rook-ceph-osd-0-769b8db464-flv6l 1/1 Running 0 19m rook-ceph-osd-prepare-rookworker-x5n8k 0/1 Completed 0 20m rook-discover-ts7j2 1/1 Running 0 22m [root@rookmaster ceph]#
今回利用したcluster-test.yaml
は以下の通りです。
apiVersion: ceph.rook.io/v1 kind: CephCluster metadata: name: rook-ceph namespace: rook-ceph spec: cephVersion: image: ceph/ceph:v14.2.8 allowUnsupported: true dataDirHostPath: /var/lib/rook skipUpgradeChecks: false continueUpgradeAfterChecksEvenIfNotHealthy: false mon: count: 1 allowMultiplePerNode: true dashboard: enabled: true ssl: true monitoring: enabled: false rulesNamespace: rook-ceph network: hostNetwork: false rbdMirroring: workers: 0 crashCollector: disable: false mgr: modules: - name: pg_autoscaler enabled: true storage: useAllNodes: true useAllDevices: false config: databaseSizeMB: "1024" journalSizeMB: "1024" osdsPerDevice: "1" ## デバイスを指定 ## devices: - name: "sdc"
なお、今回は検証のためOSDの数が少なく、ceph status
で確認するとクラスターの状態はWarning状態となりますが、今回はここは気にせずに検証を行いました。
[root@rookmaster ceph]# kubectl apply -f toolbox.yaml [root@rookmaster ceph]# kubectl exec -it -n rook-ceph $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- ceph status cluster: id: 5a17c461-19ee-4561-a704-5a727d11bdca health: HEALTH_WARN OSD count 1 < osd_pool_default_size 3 services: mon: 1 daemons, quorum a (age 25m) mgr: a(active, since 25m) osd: 1 osds: 1 up (since 24m), 1 in (since 24m) data: pools: 0 pools, 0 pgs objects: 0 objects, 0 B usage: 1.0 GiB used, 63 GiB / 64 GiB avail pgs: [root@rookmaster ceph]#
※参考リンク:
Rook Docs - Ceph Examples (v1.2)
Rook Docs - Ceph Cluster CRD (v1.2)
1. 手動でリソースを用意する場合
まずは手動で各種リソースを用意する場合です。こちらは以下のリンクを参考にしています。なお、以下リンク先ではminikubeの利用を前提としております。
※参考リンク:
Ceph blog - Deploying a Ceph+NFS Server Cluster with Rook
CephFS Filesystemの作成
まずはCephFSを作成します。ここではToolbox Podから各種コマンドを実行して作成します。またデフォルトではOSD replicated sizeは3になりますが、今回はOSDを1つしか用意していないため、ここでは1に設定を変更します。
# Toolbox Podにログイン [root@rookmaster ceph]# kubectl exec -it -n rook-ceph $(kubectl get pods -n rook-ceph -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') bash bash: warning: setlocale: LC_CTYPE: cannot change locale (en_US.UTF-8): No such file or directory bash: warning: setlocale: LC_COLLATE: cannot change locale (en_US.UTF-8): No such file or directory bash: warning: setlocale: LC_MESSAGES: cannot change locale (en_US.UTF-8): No such file or directory bash: warning: setlocale: LC_NUMERIC: cannot change locale (en_US.UTF-8): No such file or directory bash: warning: setlocale: LC_TIME: cannot change locale (en_US.UTF-8): No such file or directory # CephFS作成 [root@rook-ceph-tools-565698c784-hjzxg /]# ceph fs volume create myfs [root@rook-ceph-tools-565698c784-hjzxg /]# ceph fs ls name: myfs, metadata pool: cephfs.myfs.meta, data pools: [cephfs.myfs.data ] # OSD size変更 [root@rook-ceph-tools-565698c784-hjzxg /]# ceph osd pool set cephfs.myfs.meta size 1 set pool 1 size to 1 [root@rook-ceph-tools-565698c784-hjzxg /]# ceph osd pool set cephfs.myfs.data size 1 set pool 2 size to 1 [root@rook-ceph-tools-565698c784-hjzxg /]# ceph osd pool ls cephfs.myfs.meta cephfs.myfs.data
NFS Server Clusterの作成
次にNFS Server用のクラスターを作成します。NFS Ganeshaにはクライアントデータを保護するためのリカバリー機能があり、このデータの保存先としてRADOSを利用することができます。Rookはこのリカバリー機能を利用するよう自動的に設定を行い、再起動時のリカバリーコンフリクトが発生するのを防ぎます。
※参考リンク:
Active/Active NFS Server Recovery over CephFS (PDF)
# NFS Ganesha用のPoolを作成 [root@rook-ceph-tools-565698c784-hjzxg /]# ceph osd pool create nfs-ganesha 64 pool 'nfs-ganesha' created [root@rook-ceph-tools-565698c784-hjzxg /]# ceph osd pool set nfs-ganesha size 1 set pool 3 size to 1 # NFS Server Cluster作成 [root@rook-ceph-tools-565698c784-hjzxg /]# ceph orchestrator nfs add mynfs nfs-ganesha ganesha # 確認 [root@rook-ceph-tools-565698c784-hjzxg /]# ceph osd pool ls cephfs.myfs.meta cephfs.myfs.data nfs-ganesha [root@rook-ceph-tools-565698c784-hjzxg /]# ceph orchestrator service ls mds myfs.a rookworker rook-ceph-mds-myfs-a-6bbdb8dfb9-9rpmx None None mds myfs.b rookworker rook-ceph-mds-myfs-b-85d5cdf8-jjtw6 None None mgr a rookworker rook-ceph-mgr-a-5955db5c76-wn56j None None mon a rookworker rook-ceph-mon-a-7b99cd7876-lt55t None None nfs mynfs.a rookworker rook-ceph-nfs-mynfs-a-74d7d4444b-r5w5l None rados://nfs-ganesha/ganesha/conf-mynfs.a osd 0 rookworker rook-ceph-osd-0-769b8db464-flv6l None None [root@rook-ceph-tools-565698c784-hjzxg /]#
なお、上記クラスターはceph orchestrator nfs update
でスケールアウトすることができます。
[root@rook-ceph-tools-565698c784-hjzxg /]# ceph orchestrator nfs update mynfs 2 [root@rook-ceph-tools-565698c784-hjzxg /]# ceph orchestrator service ls mds myfs.a rookworker rook-ceph-mds-myfs-a-6bbdb8dfb9-9rpmx None None mds myfs.b rookworker rook-ceph-mds-myfs-b-85d5cdf8-jjtw6 None None mgr a rookworker rook-ceph-mgr-a-5955db5c76-wn56j None None mon a rookworker rook-ceph-mon-a-7b99cd7876-lt55t None None nfs mynfs.a rookworker rook-ceph-nfs-mynfs-a-74d7d4444b-r5w5l None rados://nfs-ganesha/ganesha/conf-mynfs.a nfs mynfs.b rookworker rook-ceph-nfs-mynfs-b-649cf6469f-gw625 None rados://nfs-ganesha/ganesha/conf-mynfs.b osd 0 rookworker rook-ceph-osd-0-769b8db464-flv6l None None
ここまでの操作により、Kubernetes上では以下のようにPodが作成されています。
[root@rookmaster ceph]# kubectl get pods -n rook-ceph NAME READY STATUS RESTARTS AGE csi-cephfsplugin-cdtdj 3/3 Running 0 37m csi-cephfsplugin-provisioner-7b8fbf88b4-78j7l 4/4 Running 0 37m csi-cephfsplugin-provisioner-7b8fbf88b4-rqsqp 4/4 Running 0 37m csi-rbdplugin-9xvv4 3/3 Running 0 37m csi-rbdplugin-provisioner-6b8b4d558c-rzbdd 5/5 Running 0 37m csi-rbdplugin-provisioner-6b8b4d558c-spvjz 5/5 Running 0 37m rook-ceph-crashcollector-rookworker-bc69898c5-nhw6w 1/1 Running 0 7m31s rook-ceph-mds-myfs-a-6bbdb8dfb9-9rpmx 1/1 Running 0 7m31s ★ rook-ceph-mds-myfs-b-85d5cdf8-jjtw6 1/1 Running 0 7m30s ★ rook-ceph-mgr-a-5955db5c76-wn56j 1/1 Running 0 35m rook-ceph-mon-a-7b99cd7876-lt55t 1/1 Running 0 36m rook-ceph-nfs-mynfs-a-74d7d4444b-r5w5l 2/2 Running 0 5m7s ★ rook-ceph-operator-69f856fc5f-z85hd 1/1 Running 0 38m rook-ceph-osd-0-769b8db464-flv6l 1/1 Running 0 34m rook-ceph-osd-prepare-rookworker-x5n8k 0/1 Completed 0 35m rook-ceph-tools-565698c784-hjzxg 1/1 Running 0 14m rook-discover-ts7j2 1/1 Running 0 38m
NFS-Ganesha Exportの設定
この時点ではNFS ServerにはExportの設定がされておらず、外部から利用することはできません。ここでは、Ceph Dashboard経由でExport用の設定を追加し、外部からNFS Serverを利用できるようにします。
まずはCeph Dashboardにアクセスできるよう、ServiceリソースのタイプをNodePort
に変更します。
# Serviceの確認 [root@rookmaster ceph]# kubectl get service -n rook-ceph NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE csi-cephfsplugin-metrics ClusterIP 10.100.141.23 <none> 8080/TCP,8081/TCP 34m csi-rbdplugin-metrics ClusterIP 10.110.84.171 <none> 8080/TCP,8081/TCP 34m rook-ceph-mgr ClusterIP 10.107.200.238 <none> 9283/TCP 32m rook-ceph-mgr-dashboard ClusterIP 10.102.243.246 <none> 8443/TCP 32m rook-ceph-mon-a ClusterIP 10.100.24.136 <none> 6789/TCP,3300/TCP 33m rook-ceph-nfs-mynfs-a ClusterIP 10.104.188.15 <none> 2049/TCP 2m13s # NodePortに変更 [root@rookmaster ceph]# kubectl patch service -n rook-ceph -p '{"spec":{"type": "NodePort"}}' rook-ceph-mgr-dashboard service/rook-ceph-mgr-dashboard patched # 変更後 [root@rookmaster ceph]# kubectl get service -n rook-ceph NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE csi-cephfsplugin-metrics ClusterIP 10.100.141.23 <none> 8080/TCP,8081/TCP 35m csi-rbdplugin-metrics ClusterIP 10.110.84.171 <none> 8080/TCP,8081/TCP 35m rook-ceph-mgr ClusterIP 10.107.200.238 <none> 9283/TCP 33m rook-ceph-mgr-dashboard NodePort 10.102.243.246 <none> 8443:32314/TCP 34m rook-ceph-mon-a ClusterIP 10.100.24.136 <none> 6789/TCP,3300/TCP 34m rook-ceph-nfs-mynfs-a ClusterIP 10.104.188.15 <none> 2049/TCP 3m37s [root@rookmaster ceph]#
続いて、設定変更用のjsonファイルを用意します。ここではexport.json
という以下のファイルを用意します。
{ "cluster_id": "mynfs", "path": "/", "fsal": {"name": "CEPH", "user_id":"admin", "fs_name": "myfs", "sec_label_xattr": null}, "pseudo": "/cephfs", "tag": null, "access_type": "RW", "squash": "no_root_squash", "protocols": [4], "transports": ["TCP"], "security_label": true, "daemons": ["mynfs.a"], "clients": [] }
各項目は以下のように利用します。
- path:関連するCephFSプール内のExport Path
- fsal:File System Abstraction Layerの設定
- name:NFS Ganeshaの利用するバックエンドを指定。CephFSの場合は
CEPH
、RGWの場合はRGW
- name:NFS Ganeshaの利用するバックエンドを指定。CephFSの場合は
- pseudo:ターゲットNFSのExport Path。マウント時はここで指定したパスを指定します。
- access_type:RO / RWなどアクセス方式を選択
- squash:ルート権限無効化のオプション
- protocols:NFSプロトコル。
- daemons:利用するDaemonを指定
※参考リンク:
debian manpages - GANESHA-EXPORT-CONFIG(8)
SUSE Doc - 14 NFS Ganesha: NFS経由でのCephデータのエクスポート
次に上記jsonファイルをCeph Dashboard経由で反映するためのスクリプトを用意します。ここではrun-backend-rook-api-request.shというファイルを利用します。スクリプトの内容は以下の通りです。
#!/bin/bash # # Query k8s to determine where the mgr is running and how to reach the # dashboard from the local machine. This assumes that the dashboard is being # exposed via a nodePort service CURR_DIR=`pwd` K8S_NAMESPACE='rook-ceph' HOST=$(kubectl get pods -n $K8S_NAMESPACE -l "app=rook-ceph-mgr" -o json | jq .items[0].spec.nodeName | sed s/\"//g) if [ "$HOST" = "minikube" ]; then HOST=$(minikube ip) fi PORT=$(kubectl get service -n $K8S_NAMESPACE rook-ceph-mgr-dashboard -o yaml | grep nodePort: | awk '{print $2}') API_URL="https://${HOST}:${PORT}" # # Rook automagically sets up an "admin" account with a random PW and stuffs # that into a k8s secret. This fetches it. # PASSWD=$(kubectl -n $K8S_NAMESPACE get secret rook-ceph-dashboard-password -o yaml | grep "password:" | awk '{print $2}' | base64 --decode) if [ "$API_URL" = "null" ]; then echo "Couldn't retrieve API URL, exiting..." >&2 exit 1 fi cd $CURR_DIR TOKEN=`curl --insecure -s -H "Content-Type: application/json" -X POST \ -d "{\"username\":\"admin\",\"password\":\"${PASSWD}\"}" $API_URL/api/auth \ | jq .token | sed -e 's/"//g'` echo "METHOD: $1" echo "URL: ${API_URL}${2}" echo "DATA: $3" echo "" curl --insecure -s -b /tmp/cd-cookie.txt -H "Authorization: Bearer $TOKEN " \ -H "Content-Type: application/json" -X $1 -d "$3" ${API_URL}$2 | jq
上記スクリプトではjq
コマンドを利用しているため、コマンドをインストールしていない場合は適宜インストールします。
では上記スクリプトを実行します。実行結果でエラー等が返ってこなければjsonファイルの反映に成功しています。
# スクリプト実行 [root@rookmaster ceph]# ./run-backend-rook-api-request.sh POST /api/nfs-ganesha/export "$(cat export.json)" METHOD: POST URL: https://rookworker:32314/api/nfs-ganesha/export DATA: { "cluster_id": "mynfs", "path": "/", "fsal": {"name": "CEPH", "user_id":"admin", "fs_name": "myfs", "sec_label_xattr": null}, "pseudo": "/cephfs", "tag": null, "access_type": "RW", "squash": "no_root_squash", "protocols": [4], "transports": ["TCP"], "security_label": true, "daemons": ["mynfs.a"], "clients": [] } { "squash": "no_root_squash", "access_type": "RW", "tag": null, "cluster_id": "mynfs", "fsal": { "fs_name": "myfs", "sec_label_xattr": null, "user_id": "admin", "name": "CEPH" }, "daemons": [ "mynfs.a" ], "path": "/", "export_id": 1, "protocols": [ 4 ], "clients": [], "pseudo": "/cephfs", "security_label": true, "transports": [ "TCP" ] }
NFS Serverの利用
ここまででNFS Ganeshaの設定は完了しました。あとはNFS ServerのServiceリソースをNodePort
タイプに変更し、外部からアクセスできるようにします。
# Serviceの確認 [root@rookmaster ceph]# kubectl get service -n rook-ceph NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE csi-cephfsplugin-metrics ClusterIP 10.100.141.23 <none> 8080/TCP,8081/TCP 44m csi-rbdplugin-metrics ClusterIP 10.110.84.171 <none> 8080/TCP,8081/TCP 44m rook-ceph-mgr ClusterIP 10.107.200.238 <none> 9283/TCP 42m rook-ceph-mgr-dashboard NodePort 10.102.243.246 <none> 8443:32314/TCP 42m rook-ceph-mon-a ClusterIP 10.100.24.136 <none> 6789/TCP,3300/TCP 43m rook-ceph-nfs-mynfs-a ClusterIP 10.104.188.15 <none> 2049/TCP 12m # NodePortに変更 [root@rookmaster ceph]# kubectl patch service -n rook-ceph -p '{"spec":{"type": "NodePort"}}' rook-ceph-nfs-mynfs-a service/rook-ceph-nfs-mynfs-a patched [root@rookmaster ceph]# # 変更後 [root@rookmaster ceph]# kubectl get service -n rook-ceph NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE csi-cephfsplugin-metrics ClusterIP 10.100.141.23 <none> 8080/TCP,8081/TCP 45m csi-rbdplugin-metrics ClusterIP 10.110.84.171 <none> 8080/TCP,8081/TCP 45m rook-ceph-mgr ClusterIP 10.107.200.238 <none> 9283/TCP 43m rook-ceph-mgr-dashboard NodePort 10.102.243.246 <none> 8443:32314/TCP 43m rook-ceph-mon-a ClusterIP 10.100.24.136 <none> 6789/TCP,3300/TCP 43m rook-ceph-nfs-mynfs-a NodePort 10.104.188.15 <none> 2049:30969/TCP 13m
これでNFS Serverを外部から利用できるようになりました。今回はテストとして、Kubernetes MasterノードからNFS Serverをマウントし、テスト用ファイルが編集できるかを確認してみます。
# マウント [root@rookmaster ceph]# mkdir -p /mnt/rook [root@rookmaster ceph]# mount -t nfs -o port=30969 10.5.0.5:/cephfs /mnt/rook/ [root@rookmaster ceph]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 3.9G 0 3.9G 0% /dev tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs 3.9G 9.6M 3.9G 1% /run (中略) 10.5.0.5:/cephfs 60G 0 60G 0% /mnt/rook # ファイルの書き込み [root@rookmaster ceph]# touch /mnt/rook/test.txt [root@rookmaster ceph]# ls -l /mnt/rook/ total 0 -rw-r--r-- 1 nobody nobody 0 Apr 4 00:58 test.txt [root@rookmaster ceph]# dd if=/dev/zero of=/mnt/rook/testfile bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 22.4873 s, 47.7 MB/s [root@rookmaster ceph]# ls -l /mnt/rook/ total 1048576 -rw-r--r-- 1 nobody nobody 1073741824 Apr 4 01:01 testfile -rw-r--r-- 1 nobody nobody 0 Apr 4 00:58 test.txt [root@rookmaster ceph]#
2. CRDを利用する場合
次にcephnfs.ceph.rook.io
CRDを利用する場合を紹介します。といっても、基本的な流れは1つ目の方法と同じで、各種リソースの作成にCRDを利用する点が違うだけです。
Ceph Filesystemの作成
まずはcephfilesystem.ceph.rook.io
CRDをデプロイしCephFSを用意します。
# CephFS作成 [root@rookmaster ceph]# kubectl apply -f filesystem-test.yaml # 確認 [root@rookmaster ceph]# kubectl get cephfilesystem.ceph.rook.io -n rook-ceph NAME ACTIVEMDS AGE myfs 1 23s [root@rookmaster ceph]# kubectl get pods -n rook-ceph NAME READY STATUS RESTARTS AGE csi-cephfsplugin-kb9r4 3/3 Running 0 10m csi-cephfsplugin-provisioner-7b8fbf88b4-kg59m 4/4 Running 0 10m csi-cephfsplugin-provisioner-7b8fbf88b4-w248r 4/4 Running 0 10m csi-rbdplugin-c2ck4 3/3 Running 0 10m csi-rbdplugin-provisioner-6b8b4d558c-lkx62 5/5 Running 0 10m csi-rbdplugin-provisioner-6b8b4d558c-tz7pg 5/5 Running 0 10m rook-ceph-crashcollector-rookworker-58db759fb9-zqtkz 1/1 Terminating 0 9m14s rook-ceph-crashcollector-rookworker-bc69898c5-z8dzr 1/1 Running 0 23s rook-ceph-mds-myfs-a-75fb544555-5nqc6 1/1 Running 0 23s rook-ceph-mds-myfs-b-749854fc88-6468d 1/1 Running 0 23s rook-ceph-mgr-a-5c558f45fd-gqvtk 1/1 Running 0 10m rook-ceph-mon-a-7c698b79cd-jdrgn 1/1 Running 0 10m rook-ceph-operator-69f856fc5f-zhhtk 1/1 Running 0 11m rook-ceph-osd-0-65f9d5b7cd-lzm9m 1/1 Running 0 9m14s rook-ceph-osd-prepare-rookworker-rnw7j 0/1 Completed 0 9m55s rook-discover-6w4mr 1/1 Running 0 11m # Poolも自動的に作成される [root@rookmaster ceph]# kubectl apply -f toolbox.yaml [root@rookmaster ceph]# kubectl exec -it -n rook-ceph $(kubectl get pods -n rook-ceph -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- ceph osd pool ls myfs-metadata myfs-data0
今回利用したfilesystem-test.yaml
は以下の通りです。
apiVersion: ceph.rook.io/v1 kind: CephFilesystem metadata: name: myfs namespace: rook-ceph spec: metadataPool: replicated: size: 1 dataPools: - failureDomain: osd replicated: size: 1 preservePoolsOnDelete: false metadataServer: activeCount: 1 activeStandby: true
※参考リンク:
Rook Docs - Ceph Shared Filesystem CRD (v1.2)
TECHSTEP - Rook-Cephの機能紹介(File Storage編)
NFS Server Clusterの作成
続いてcephnfs.ceph.rook.io
CRDをデプロイします。今回はnfs-test.yaml
という以下のyamlファイルを利用します。
apiVersion: ceph.rook.io/v1 kind: CephNFS metadata: name: my-nfs namespace: rook-ceph spec: rados: pool: myfs-data0 # RADOS namespace where NFS client recovery data is stored in the pool. namespace: nfs-ns server: active: 1
各パラメータは以下のような設定内容です。
spec.rados.pool
:NFSクライアントのリカバリデータを保存するRADOSプールspec.rados.namespace
:上記RADOSプールのあるnamespacespec.server.active
:アクティブなNFSサーバーの数
それでは上記ファイルをデプロイします。
# デプロイ [root@rookmaster ceph]# kubectl apply -f nfs-test.yaml # 確認 [root@rookmaster ceph]# kubectl get cephnfs.ceph.rook.io -n rook-ceph NAME AGE my-nfs 29s [root@rookmaster ceph]# kubectl get pods -n rook-ceph NAME READY STATUS RESTARTS AGE csi-cephfsplugin-kb9r4 3/3 Running 0 15m csi-cephfsplugin-provisioner-7b8fbf88b4-kg59m 4/4 Running 0 15m csi-cephfsplugin-provisioner-7b8fbf88b4-w248r 4/4 Running 0 15m csi-rbdplugin-c2ck4 3/3 Running 0 15m csi-rbdplugin-provisioner-6b8b4d558c-lkx62 5/5 Running 0 15m csi-rbdplugin-provisioner-6b8b4d558c-tz7pg 5/5 Running 0 15m rook-ceph-crashcollector-rookworker-bc69898c5-z8dzr 1/1 Running 0 5m14s rook-ceph-mds-myfs-a-75fb544555-5nqc6 1/1 Running 0 5m14s rook-ceph-mds-myfs-b-749854fc88-6468d 1/1 Running 0 5m14s rook-ceph-mgr-a-5c558f45fd-gqvtk 1/1 Running 0 15m rook-ceph-mon-a-7c698b79cd-jdrgn 1/1 Running 0 15m rook-ceph-nfs-my-nfs-a-5b74794589-r6k9j 2/2 Running 0 40s rook-ceph-operator-69f856fc5f-zhhtk 1/1 Running 0 15m rook-ceph-osd-0-65f9d5b7cd-lzm9m 1/1 Running 0 14m rook-ceph-osd-prepare-rookworker-rnw7j 0/1 Completed 0 14m rook-ceph-tools-565698c784-68lct 1/1 Running 0 4m3s rook-discover-6w4mr 1/1 Running 0 15m [root@rookmaster ceph]# kubectl get service -n rook-ceph NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE csi-cephfsplugin-metrics ClusterIP 10.104.106.152 <none> 8080/TCP,8081/TCP 16m csi-rbdplugin-metrics ClusterIP 10.103.195.149 <none> 8080/TCP,8081/TCP 16m rook-ceph-mgr ClusterIP 10.97.164.91 <none> 9283/TCP 15m rook-ceph-mgr-dashboard ClusterIP 10.96.186.101 <none> 8443/TCP 15m rook-ceph-mon-a ClusterIP 10.99.213.248 <none> 6789/TCP,3300/TCP 16m rook-ceph-nfs-my-nfs-a ClusterIP 10.104.9.170 <none> 2049/TCP 80s [root@rookmaster ceph]#
NFS-Ganesha Exportの設定 / NFS Serverの利用
さて、ここまででNFS Serverのデプロイが完了しましたが、先ほど紹介した1つ目の方法と同様に、デフォルトではExport設定がなく外部からアクセスすることができません。これ以降は1つ目の方法と全く同じ手順で外部からのアクセスを可能にします。
# ServiceをNodePortタイプに変更 [root@rookmaster ceph]# kubectl patch service -n rook-ceph -p '{"spec": {"type": "NodePort"}}' rook-ceph-mgr-dashboard [root@rookmaster ceph]# kubectl patch service -n rook-ceph -p '{"spec":{"type": "NodePort"}}' rook-ceph-nfs-my-nfs-a [root@rookmaster ceph]# kubectl get service -n rook-ceph NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE csi-cephfsplugin-metrics ClusterIP 10.104.106.152 <none> 8080/TCP,8081/TCP 5h55m csi-rbdplugin-metrics ClusterIP 10.103.195.149 <none> 8080/TCP,8081/TCP 5h55m rook-ceph-mgr ClusterIP 10.97.164.91 <none> 9283/TCP 5h54m rook-ceph-mgr-dashboard NodePort 10.96.186.101 <none> 8443:32110/TCP 5h55m rook-ceph-mon-a ClusterIP 10.99.213.248 <none> 6789/TCP,3300/TCP 5h55m rook-ceph-nfs-my-nfs-a NodePort 10.104.9.170 <none> 2049:30070/TCP 5h40m # Ceph Dashboard経由でExport設定を反映 # export-nfscrd.jsonはdaemons設定のみ"my-nfs.a"に変更 [root@rookmaster ceph]# ./run-backend-rook-api-request.sh POST /api/nfs-ganesha/export "$(cat export-nfscrd.json)" METHOD: POST URL: https://rookworker:32110/api/nfs-ganesha/export DATA: { "cluster_id": "mynfs", "path": "/", "fsal": {"name": "CEPH", "user_id":"admin", "fs_name": "myfs", "sec_label_xattr": null}, "pseudo": "/cephfs", "tag": null, "access_type": "RW", "squash": "no_root_squash", "protocols": [4], "transports": ["TCP"], "security_label": true, "daemons": ["my-nfs.a"], "clients": [] } { "squash": "no_root_squash", "access_type": "RW", "tag": null, "cluster_id": "mynfs", "fsal": { "fs_name": "myfs", "sec_label_xattr": null, "user_id": "admin", "name": "CEPH" }, "daemons": [ "my-nfs.a" ], "path": "/", "export_id": 1, "protocols": [ 4 ], "clients": [], "pseudo": "/cephfs", "security_label": true, "transports": [ "TCP" ] } # マウント [root@rookmaster ceph]# mount -t nfs -o port=30070 10.5.0.5:/cephfs /mnt/rook/ [root@rookmaster ceph]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 3.9G 0 3.9G 0% /dev tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs 3.9G 9.6M 3.9G 1% /run (中略) 10.5.0.5:/cephfs 60G 0 60G 0% /mnt/rook [root@rookmaster ceph]# touch /mnt/rook/test.txt [root@rookmaster ceph]# ls -l /mnt/rook/ total 0 -rw-r--r-- 1 nobody nobody 0 Apr 4 08:14 test.txt [root@rookmaster ceph]# dd if=/dev/zero of=/mnt/rook/testfile bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 22.4502 s, 47.8 MB/s [root@rookmaster ceph]#
また、cephnfs.ceph.rook.io
CRDをデプロイすると、NFS Server Pod毎のConfigMapが作成されます。この中身はganesha.conf
の設定内容であり、こちらを編集してPodを再起動することでExportの設定を行うことができると思われますが、今回はこちらの検証は行っていません。
[root@rookmaster ceph]# kubectl get cm -n rook-ceph NAME DATA AGE local-device-rookworker 1 25h rook-ceph-csi-config 1 25h rook-ceph-mon-endpoints 4 25h rook-ceph-nfs-my-nfs-a 1 24h rook-ceph-operator-config 0 25h rook-config-override 1 25h [root@rookmaster ceph]# kubectl describe cm rook-ceph-nfs-my-nfs-a -n rook-ceph Name: rook-ceph-nfs-my-nfs-a Namespace: rook-ceph Labels: app=rook-ceph-nfs ceph_nfs=my-nfs instance=a rook_cluster=rook-ceph Annotations: <none> Data ==== config: ---- NFS_CORE_PARAM { Enable_NLM = false; Enable_RQUOTA = false; Protocols = 4; } CACHEINODE { Dir_Chunk = 0; NParts = 1; Cache_Size = 1; } EXPORT_DEFAULTS { Attr_Expiration_Time = 0; } NFSv4 { Delegations = false; RecoveryBackend = 'rados_cluster'; Minor_Versions = 1, 2; } RADOS_KV { ceph_conf = '/etc/ceph/ceph.conf'; userid = admin; nodeid = my-nfs.a; pool = "myfs-data0"; namespace = "nfs-ns"; } RADOS_URLS { ceph_conf = '/etc/ceph/ceph.conf'; userid = admin; watch_url = 'rados://myfs-data0/nfs-ns/conf-my-nfs.a'; } %url rados://myfs-data0/nfs-ns/conf-my-nfs.a Events: <none> [root@rookmaster ceph]#