ラズパイkubernetesでRook/Cephクラスターを構築する

最近転職したりして忙しかったので久しぶりに書きます。

以前 hostPathで永続ボリュームを利用する手順 を書きましたが、
ちゃんとしたストレージが欲しいなと思ったのでRookのCephクラスターを構築してみることにしました。
なかなかうまくいかなかったのですが、とりあえず構築するところまではいけました。

物理構成

前提条件が重要なので詳しく書きます。
4台のRaspberry Pi 4を使ってkubeadmで構築したクラスターを利用します。
構成は以前構築したこちら とほぼ一緒です。
違うのはワーカノードを3台に増やしたところと(ドキュメントによると最低でも3台必要らしいです)、
ワーカーノード全てにHDDをUSB接続したところです。

ubuntu@k8s1:~$ kubectl get nodes
NAME   STATUS   ROLES                  AGE     VERSION
k8s1   Ready    control-plane,master   4m55s   v1.20.15
k8s2   Ready    <none>                 4m12s   v1.20.15
k8s3   Ready    <none>                 4m10s   v1.20.15
k8s4   Ready    <none>                 4m5s    v1.20.15

あとバージョンが微妙に上がっています。
最初は最新バージョンで試していたのですが、以下のエラーが出てOSDポッドが作られず、
試しにバージョンを落としてみたらうまくいったからです。

FileNotFoundError: [Errno 2] No such file or directory: 'udevadm': 'udevadm'. exit status 1.

ワーカーノードに接続したHDDは初期化が必要です。
こちら で コマンドが案内されているので実行します。
これもっと目立つところに書いておいて欲しいですね。
ちゃんと初期化できてなくてHDDを使ってくれず、ここも時間取られました。
あとデプロイ失敗した後にやり直す時は、全てのノードの/var/lib/rookは削除しといた方がいいです。

僕の場合、初期化時はこんな表示になりました。
OS(Ubuntu 20.04.4 64bit)はmicroSDにインストールしており、HDDは4台ともsdaになりました。

root@k8s2:~# lsblk -f
NAME        FSTYPE   LABEL       UUID                                 FSAVAIL FSUSE% MOUNTPOINT
loop0       squashfs                                                        0   100% /snap/core18/2127
loop1       squashfs                                                        0   100% /snap/core18/2289
loop2       squashfs                                                        0   100% /snap/lxd/21843
loop3       squashfs                                                        0   100% /snap/core20/1332
loop4       squashfs                                                        0   100% /snap/lxd/21032
loop5       squashfs                                                        0   100% /snap/snapd/12707
loop6       squashfs                                                        0   100% /snap/snapd/14553
sda                                                                                  
mmcblk0                                                                              
├─mmcblk0p1 vfat     system-boot 5496-E6C8                             131.9M    48% /boot/firmware
└─mmcblk0p2 ext4     writable    675ba907-3741-428c-afa4-c00f1b649e3c   23.4G    13% /
root@k8s2:~# fdisk -l /dev/sda
Disk /dev/sda: 1.84 TiB, 2000398934016 bytes, 3907029168 sectors
Disk model: 001-1CH164      
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

モデルからバレますが、使ったのは3台とも同じSeagateの3.5inch HDD2TBです。
USBだけじゃ給電できないので電源アダプター付きのを利用しています。
僕が今回利用したのは こちら ですが、生産終了しちゃったのか在庫切れですね。
まぁ1台違うの使ってますし似たようなのなら大丈夫だと思います。
2.5インチSSDとかだとUSBだけでもいけますが、
今回はHDDでの速度を確認したかったのでこの構成にしています。

物理的な見た目はこんな感じ。これはひどい。

rook_ceph_raspberrypi.jpg

デプロイ

前提条件がクリアできていれば公式ドキュメント の通りですんなりいけると思います。
Rookオペレーターをデプロイします。

ubuntu@k8s1:~$ git clone --single-branch --branch v1.8.6 https://github.com/rook/rook.git
ubuntu@k8s1:~$ cd rook/deploy/examples
ubuntu@k8s1:~/rook/deploy/examples$ kubectl create -f crds.yaml -f common.yaml -f operator.yaml
customresourcedefinition.apiextensions.k8s.io/cephblockpools.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephbucketnotifications.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephbuckettopics.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephclients.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephclusters.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephfilesystemmirrors.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephfilesystems.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephfilesystemsubvolumegroups.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephnfses.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephobjectrealms.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephobjectstores.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephobjectstoreusers.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephobjectzonegroups.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephobjectzones.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephrbdmirrors.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/objectbucketclaims.objectbucket.io created
customresourcedefinition.apiextensions.k8s.io/objectbuckets.objectbucket.io created
namespace/rook-ceph created
clusterrole.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created
clusterrole.rbac.authorization.k8s.io/cephfs-external-provisioner-runner created
clusterrole.rbac.authorization.k8s.io/psp:rook created
clusterrole.rbac.authorization.k8s.io/rbd-csi-nodeplugin created
clusterrole.rbac.authorization.k8s.io/rbd-external-provisioner-runner created
clusterrole.rbac.authorization.k8s.io/rook-ceph-cluster-mgmt created
clusterrole.rbac.authorization.k8s.io/rook-ceph-global created
clusterrole.rbac.authorization.k8s.io/rook-ceph-mgr-cluster created
clusterrole.rbac.authorization.k8s.io/rook-ceph-mgr-system created
clusterrole.rbac.authorization.k8s.io/rook-ceph-object-bucket created
clusterrole.rbac.authorization.k8s.io/rook-ceph-osd created
clusterrole.rbac.authorization.k8s.io/rook-ceph-system created
clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created
clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-nodeplugin created
clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-global created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-cluster created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-object-bucket created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-osd created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-system created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-system-psp created
clusterrolebinding.rbac.authorization.k8s.io/rook-csi-cephfs-plugin-sa-psp created
clusterrolebinding.rbac.authorization.k8s.io/rook-csi-cephfs-provisioner-sa-psp created
clusterrolebinding.rbac.authorization.k8s.io/rook-csi-rbd-plugin-sa-psp created
clusterrolebinding.rbac.authorization.k8s.io/rook-csi-rbd-provisioner-sa-psp created
podsecuritypolicy.policy/00-rook-privileged created
role.rbac.authorization.k8s.io/cephfs-external-provisioner-cfg created
role.rbac.authorization.k8s.io/rbd-csi-nodeplugin created
role.rbac.authorization.k8s.io/rbd-external-provisioner-cfg created
role.rbac.authorization.k8s.io/rook-ceph-cmd-reporter created
role.rbac.authorization.k8s.io/rook-ceph-mgr created
role.rbac.authorization.k8s.io/rook-ceph-osd created
role.rbac.authorization.k8s.io/rook-ceph-purge-osd created
role.rbac.authorization.k8s.io/rook-ceph-system created
rolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role-cfg created
rolebinding.rbac.authorization.k8s.io/rbd-csi-nodeplugin-role-cfg created
rolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role-cfg created
rolebinding.rbac.authorization.k8s.io/rook-ceph-cluster-mgmt created
rolebinding.rbac.authorization.k8s.io/rook-ceph-cmd-reporter created
rolebinding.rbac.authorization.k8s.io/rook-ceph-cmd-reporter-psp created
rolebinding.rbac.authorization.k8s.io/rook-ceph-default-psp created
rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr created
rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-psp created
rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-system created
rolebinding.rbac.authorization.k8s.io/rook-ceph-osd created
rolebinding.rbac.authorization.k8s.io/rook-ceph-osd-psp created
rolebinding.rbac.authorization.k8s.io/rook-ceph-purge-osd created
rolebinding.rbac.authorization.k8s.io/rook-ceph-system created
serviceaccount/rook-ceph-cmd-reporter created
serviceaccount/rook-ceph-mgr created
serviceaccount/rook-ceph-osd created
serviceaccount/rook-ceph-purge-osd created
serviceaccount/rook-ceph-system created
serviceaccount/rook-csi-cephfs-plugin-sa created
serviceaccount/rook-csi-cephfs-provisioner-sa created
serviceaccount/rook-csi-rbd-plugin-sa created
serviceaccount/rook-csi-rbd-provisioner-sa created
configmap/rook-ceph-operator-config created
deployment.apps/rook-ceph-operator created
ubuntu@k8s1:~/rook/deploy/examples$ kubectl -n rook-ceph get pod -w
NAME                                  READY   STATUS              RESTARTS   AGE
rook-ceph-operator-7b4f6fd594-xmmfq   0/1     ContainerCreating   0          47s
rook-ceph-operator-7b4f6fd594-xmmfq   1/1     Running             0          2m37s

オペレーターがRunningになったらCephクラスターを作成します。

ubuntu@k8s1:~/rook/deploy/examples$ kubectl create -f cluster.yaml
cephcluster.ceph.rook.io/rook-ceph created

しばらく待って、こんな感じになれば大丈夫だと思います。
30分かからずほぼ自動で構築できちゃうとかステキ!

ubuntu@k8s1:~/rook/deploy/examples$ kubectl -n rook-ceph get pod
NAME                                             READY   STATUS      RESTARTS   AGE
csi-cephfsplugin-cd5n5                           3/3     Running     0          17m
csi-cephfsplugin-gmfpp                           3/3     Running     0          17m
csi-cephfsplugin-k9hzk                           3/3     Running     0          17m
csi-cephfsplugin-provisioner-6d4bd9b669-f57gj    6/6     Running     0          17m
csi-cephfsplugin-provisioner-6d4bd9b669-xf5fp    6/6     Running     0          17m
csi-rbdplugin-kww8k                              3/3     Running     0          17m
csi-rbdplugin-pq8qq                              3/3     Running     0          17m
csi-rbdplugin-provisioner-6bcd78bb89-shznm       6/6     Running     0          17m
csi-rbdplugin-provisioner-6bcd78bb89-wcvqv       6/6     Running     0          17m
csi-rbdplugin-wck9w                              3/3     Running     0          17m
rook-ceph-crashcollector-k8s2-798b67c94b-cr9pz   1/1     Running     0          7m43s
rook-ceph-crashcollector-k8s3-5647d5d49f-xfzfk   1/1     Running     0          7m57s
rook-ceph-crashcollector-k8s4-7477ddd69b-k77mr   1/1     Running     0          6m29s
rook-ceph-mgr-a-8f6d4b66-wsdrb                   1/1     Running     0          8m10s
rook-ceph-mon-a-7677c85bb6-w25cw                 1/1     Running     0          15m
rook-ceph-mon-b-788c5c489c-d4b5l                 1/1     Running     0          13m
rook-ceph-mon-c-778565bf74-lx4kv                 1/1     Running     0          11m
rook-ceph-operator-7b4f6fd594-xmmfq              1/1     Running     0          24m
rook-ceph-osd-0-58595bf79f-x4jw5                 1/1     Running     0          6m36s
rook-ceph-osd-1-599fb475c9-plt8g                 1/1     Running     0          6m35s
rook-ceph-osd-2-544d65f8b4-qwkwp                 1/1     Running     0          6m29s
rook-ceph-osd-prepare-k8s2-psh4p                 0/1     Completed   0          7m
rook-ceph-osd-prepare-k8s3-5zw4h                 0/1     Completed   0          7m
rook-ceph-osd-prepare-k8s4-bzz7v                 0/1     Completed   0          7m

ステータスチェック

ツールボックス をデプロイしてステータスを確認します。

ubuntu@k8s1:~/rook/deploy/examples$ kubectl create -f toolbox.yaml
deployment.apps/rook-ceph-tools created
ubuntu@k8s1:~/rook/deploy/examples$ kubectl -n rook-ceph rollout status deploy/rook-ceph-tools
deployment "rook-ceph-tools" successfully rolled out
ubuntu@k8s1:~/rook/deploy/examples$ kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
[rook@rook-ceph-tools-55ddbc9f78-lz695 /]$ ceph status
  cluster:
    id:     55fe459f-0cc6-461b-9572-c489857ffb6d
    health: HEALTH_OK
 
  services:
    mon: 3 daemons, quorum a,b,c (age 22m)
    mgr: a(active, since 20m)
    osd: 3 osds: 3 up (since 20m), 3 in (since 20m)
 
  data:
    pools:   1 pools, 1 pgs
    objects: 0 objects, 0 B
    usage:   15 MiB used, 5.5 TiB / 5.5 TiB avail
    pgs:     1 active+clean
 

HEALTH_OKなので構築できたはず!
2TB×3台で5.5TB使えるっぽいですね。
これからオブジェクトストレージとか実際に使うところを試してみたいと思います。
ラズパイだったらノード増やしやすいし、速度が許容範囲なら新しい自宅ファイルサーバーに使えるかも?