ラズパイkubernetesに構築したRook/Cephクラスターを自宅ファイルサーバーにしてみた

結論:遅い!

では構築手順を書いていきます。
Rook/Cephクラスターを構築した 前回 の続きから始めます。

CephFSでStorageClassを作成する

公式ドキュメント によるとShared Filesystemなら複数のpodで読み書きができるようです。
せっかくクラスター組んでるのでこれを使ってみます。

手順は公式ドキュメント 通りで進めました。
構築時にcloneしたrook/deploy/examplesにあるfilesystem.yamlを利用します。

ubuntu@k8s1:~/rook/deploy/examples$ kubectl create -f filesystem.yaml
cephfilesystem.ceph.rook.io/myfs created

aとbの2つpodができました。
レプリカのサイズは3だったんだが?

ubuntu@k8s1:~/rook/deploy/examples$ kubectl -n rook-ceph get pod -l app=rook-ceph-mds
NAME                                    READY   STATUS    RESTARTS   AGE
rook-ceph-mds-myfs-a-57597db49d-l265b   0/1     Running           0          17s
rook-ceph-mds-myfs-b-9565d5c4-ksnlr     0/1     Running           0          17s

ステータスを確認してみます。
確かにmdsが増えているけどドキュメントと表示が違うんだが?

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 2d)
    mgr: a(active, since 2d)
    mds: 1/1 daemons up, 1 hot standby
    osd: 3 osds: 3 up (since 2d), 3 in (since 2d)
 
  data:
    volumes: 1/1 healthy
    pools:   3 pools, 65 pgs
    objects: 23 objects, 2.3 KiB
    usage:   18 MiB used, 5.5 TiB / 5.5 TiB avail
    pgs:     65 active+clean
 
  io:
    client:   1.2 KiB/s rd, 2 op/s rd, 0 op/s wr
 

とりあえず進めてみます。
storageclass.yamlはrook/deploy/examples/csi/cephfsにあります。

ubuntu@k8s1:~/rook/deploy/examples$ kubectl create -f csi/cephfs/storageclass.yaml 
storageclass.storage.k8s.io/rook-cephfs created

無事StorageClassが作成できたようです。

ubuntu@k8s1:~/rook/deploy/examples$ kubectl -n rook-ceph get sc
NAME          PROVISIONER                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
rook-cephfs   rook-ceph.cephfs.csi.ceph.com   Delete          Immediate           true                   44s

加えて他のステータス情報です。
良さそう?

ubuntu@k8s1:~/samba$ kubectl get cephfilesystems --all-namespaces
NAMESPACE   NAME   ACTIVEMDS   AGE   PHASE
rook-ceph   myfs   1           15m   Ready
ubuntu@k8s1:~/samba$ kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
[rook@rook-ceph-tools-55ddbc9f78-lz695 /]$ ceph fs status
myfs - 0 clients
====
RANK      STATE        MDS       ACTIVITY     DNS    INOS   DIRS   CAPS  
 0        active      myfs-b  Reqs:    0 /s    20     18     17      0   
0-s   standby-replay  myfs-a  Evts:    0 /s    13      9      8      0   
      POOL         TYPE     USED  AVAIL  
 myfs-metadata   metadata   360k  1769G  
myfs-replicated    data       0   1769G  
MDS version: ceph version 16.2.7 (dd0603118f56ab514f133c8d2e3adfc983942503) pacific (stable)

SambaでPVをマウントする

ファイル共有といえばSamba(?)。
調べてみるとdperson/samba のイメージが人気らしいですね。
arm64にも対応していたのでこちらを利用させていただきます。

以下こちらこちら の記事を参考にさせていただきました。

pvcを作成します。

ubuntu@k8s1:~/samba$ vi pvc.yaml
ubuntu@k8s1:~/samba$ cat pvc.yaml 
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: cephfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1000Gi
  storageClassName: rook-cephfs
ubuntu@k8s1:~/samba$ kubectl create -f pvc.yaml
persistentvolumeclaim/cephfs-pvc created
ubuntu@k8s1:~/samba$ kubectl -n rook-ceph get sc,pv
NAME                                      PROVISIONER                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
storageclass.storage.k8s.io/rook-cephfs   rook-ceph.cephfs.csi.ceph.com   Delete          Immediate           true                   3h21m

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
persistentvolume/pvc-1d7425a3-b11f-4e29-979b-4b48b9e24e6c   1000Gi     RWX            Delete           Bound    default/cephfs-pvc   rook-cephfs             11s

deploymentを作成します。

ubuntu@k8s1:~/samba$ vi samba-deployment.yaml
ubuntu@k8s1:~/samba$ cat samba-deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: samba
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: samba
  template:
    metadata:
      labels:
        app: samba
    spec:
      containers:
        - name: samba
          image: dperson/samba
          args: [
            "-u", "myuser;P@ssw0rd",
            "-s", "cephfs;/cephfs;yes;no;no;myuser",
            "-w", "WORKGROUP"
          ]
          ports:
            - containerPort: 139
              protocol: TCP
            - containerPort: 445
              protocol: TCP
          resources:
            limits:
              cpu: "250m"
              memory: "500Mi"
          livenessProbe:
            tcpSocket:
              port: 445
          volumeMounts:
          - name: cephfs
            mountPath: /cephfs
      volumes:
        - name: cephfs
          persistentVolumeClaim:
            claimName: cephfs-pvc
ubuntu@k8s1:~/samba$ kubectl create -f samba-deployment.yaml 
deployment.apps/samba created

serviceを作成します。
ロードバランサーはMetalLBを利用しています。
詳しくはこちら をご確認ください。

ubuntu@k8s1:~/samba$ vi samba-svc.yaml
ubuntu@k8s1:~/samba$ cat samba-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: samba
  namespace: default
spec:
  selector:
    app: samba
  type: LoadBalancer
  loadBalancerIP: 192.168.10.245
  ports:
    - name: netbios
      port: 139
      targetPort: 139
    - name: smb
      port: 445
      targetPort: 445
ubuntu@k8s1:~/samba$ kubectl create -f samba-svc.yaml 
service/samba created

これにて構築完了です。
ちゃんとpodがワーカーノードに分散しているようですね。

ubuntu@k8s1:~/samba$ kubectl get po,svc -o wide
NAME                         READY   STATUS    RESTARTS   AGE     IP            NODE   NOMINATED NODE   READINESS GATES
pod/samba-5d4bfdc7b7-fgnv7   1/1     Running   0          9m29s   10.244.3.29   k8s4   <none>           <none>
pod/samba-5d4bfdc7b7-h5sxq   1/1     Running   0          9m29s   10.244.1.18   k8s2   <none>           <none>
pod/samba-5d4bfdc7b7-qqjds   1/1     Running   0          9m29s   10.244.2.29   k8s3   <none>           <none>

NAME                 TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)                       AGE     SELECTOR
service/kubernetes   ClusterIP      10.96.0.1      <none>           443/TCP                       3d1h    <none>
service/samba        LoadBalancer   10.100.68.34   192.168.10.245   139:30388/TCP,445:30627/TCP   6m57s   app=samba

動作確認

Windowsのエクスプローラーでロードバランサーの外部IPにアクセスしてみます。

rook_ceph_raspberrypi_samba_01.png

deploymentのargsで指定したユーザー名とパスワードを入力します。

rook_ceph_raspberrypi_samba_02.png

アクセスできました!

rook_ceph_raspberrypi_samba_03.png

書き込みもできました!

rook_ceph_raspberrypi_samba_04.png

ネットワークドライブに割り当てましたが、設定通り1TBのようですね。

rook_ceph_raspberrypi_samba_05.png

ベンチマーク

今回やりたかったのはこれ。果たして実用に耐えうるのか。
CrystalDiskMark を使って試してみました。

rook_ceph_raspberrypi_samba_06.png

遅いぃぃぃ

参考にこちら今使っているRaidZのファイルサーバーで同じ条件でベンチマークした結果です。

rook_ceph_raspberrypi_samba_07.png

半分も出てないですね。

数GBのファイルをコピーしてみましたが、確かにそんなもんですね。

rook_ceph_raspberrypi_samba_08.png

これは耐えられませんわ。

耐障害テスト

障害に強ければワンチャン採用もあるかも?
せっかく冗長化しているので障害を起こしてみます。

ステータスをみるとmyfs-bがアクティブとありますね。

ubuntu@k8s1:~$ kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
[rook@rook-ceph-tools-55ddbc9f78-lz695 /]$ ceph fs status
myfs - 3 clients
====
RANK      STATE        MDS       ACTIVITY     DNS    INOS   DIRS   CAPS  
 0        active      myfs-b  Reqs:    0 /s    30     27     22     11   
0-s   standby-replay  myfs-a  Evts:    0 /s    24     18     13      0   
      POOL         TYPE     USED  AVAIL  
 myfs-metadata   metadata  2724k  1764G  
myfs-replicated    data    16.0G  1764G  
MDS version: ceph version 16.2.7 (dd0603118f56ab514f133c8d2e3adfc983942503) pacific (stable)

ということはrook-ceph-mds-myfs-b-9565d5c4-ksnlrのpodがアクティブなんですかね。
試しにそのpodが乗ってるノード(k8s3)の電源をぶち抜いてみます。

ubuntu@k8s1:~$ kubectl -n rook-ceph get pod -l app=rook-ceph-mds -o wide
NAME                                    READY   STATUS    RESTARTS   AGE   IP            NODE   NOMINATED NODE   READINESS GATES
rook-ceph-mds-myfs-a-57597db49d-l265b   1/1     Running   0          16h   10.244.3.24   k8s4   <none>           <none>
rook-ceph-mds-myfs-b-9565d5c4-ksnlr     1/1     Running   0          16h   10.244.2.25   k8s3   <none>           <none>

○ね!

rook_ceph_raspberrypi_samba_09.jpg

無事○にました。

ubuntu@k8s1:~$ kubectl get nodes
NAME   STATUS     ROLES                  AGE     VERSION
k8s1   Ready      control-plane,master   3d13h   v1.20.15
k8s2   Ready      <none>                 3d13h   v1.20.15
k8s3   NotReady   <none>                 3d13h   v1.20.15
k8s4   Ready      <none>                 3d13h   v1.20.15

おーmyfs-aがアクティブに切り替わってますね。
Sambaへのアクセスも途切れることなく継続できました。

ubuntu@k8s1:~$ kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
[rook@rook-ceph-tools-55ddbc9f78-lz695 /]$ ceph fs status
myfs - 2 clients
====
RANK      STATE        MDS       ACTIVITY     DNS    INOS   DIRS   CAPS  
 0        active      myfs-a  Reqs:    0 /s    33     27     22      7   
0-s   standby-replay  myfs-b  Evts:    0 /s    24     18     13      0   
      POOL         TYPE     USED  AVAIL  
 myfs-metadata   metadata  2804k  2646G  
myfs-replicated    data    16.0G  2646G  
MDS version: ceph version 16.2.7 (dd0603118f56ab514f133c8d2e3adfc983942503) pacific (stable)
[rook@rook-ceph-tools-55ddbc9f78-lz695 /]$ ceph status
  cluster:
    id:     55fe459f-0cc6-461b-9572-c489857ffb6d
    health: HEALTH_WARN
            1/3 mons down, quorum a,c
            1 osds down
            1 host (1 osds) down
            Degraded data redundancy: 1395/4185 objects degraded (33.333%), 49 pgs degraded, 65 pgs undersized
 
  services:
    mon: 3 daemons, quorum a,c (age 2m), out of quorum: b
    mgr: a(active, since 2d)
    mds: 1/1 daemons up, 1 hot standby
    osd: 3 osds: 2 up (since 119s), 3 in (since 3d)
 
  data:
    volumes: 1/1 healthy
    pools:   3 pools, 65 pgs
    objects: 1.40k objects, 5.3 GiB
    usage:   16 GiB used, 5.4 TiB / 5.5 TiB avail
    pgs:     1395/4185 objects degraded (33.333%)
             49 active+undersized+degraded
             16 active+undersized
 
  io:
    client:   1.2 KiB/s rd, 2 op/s rd, 0 op/s wr
 

電源を入れたら自動でHEALTH_OKに戻りました。
イイね!

というわけで、ラズパイを使ったRook/Cephファイルサーバーは
可用性や拡張性は高そうだけど読み書き速度的に実用性が低いですね。
これチューニングしたらマシになるんですかね。
SSDにすれば使えるかもですがまだまだ1TBで1万円強ですしねぇ。
まぁストレージとして色々使えるので他にも試してみようと思います。