ROCK64 + Rook で作る、お家最強のお父さんCeph [後編] (Rook Deploy)

# はじめに
前回の「Kubernetes構築編」では、High Availability 構成の 4ノード k8s クラスタを構築しました。

[ROCK64 + Rook で作る、お家最強のお父さんCeph [前編]](https://qiita.com/rev4t/items/3108b78e1f9be9e06781)

今回のドキュメントでは、前回に引き続いて k8s クラスタ上に Rook を用いて Ceph をデプロイします。

インストール手順については、Rook の公式ドキュメントを参考に、若干 ROCK64 向けの設定を施したCephCluster を作成します。

https://rook.io/docs/rook/v1.0/ceph-quickstart.html

# ROCK64のハマりどころ
Rook を用いたデプロイについては AMD64 アーキテクチャについては簡単にできますが、ROCK64 を用いる場合には対応が必要な Known Issue が3つ存在しております。

1. [Ceph common issues; Rook Agent rbd module missing error](https://rook.io/docs/rook/v1.0/ceph-common-issues.html#rook-agent-rbd-module-missing-error)
  - [modprobe: FATAL: Module rbd not found on ARM #1985](https://github.com/rook/rook/issues/1985)
  - [Feature request: CONFIG_BLK_DEV_RBD=m #211](https://github.com/ayufan-rock64/linux-build/issues/211)
2. [Attempt to map rbd image from ceph jewel/luminous hangs](https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1728739)
  - ROCK64 が公式に対応している kernel version は 4.4 になり、Ubuntu xenial と同一世代になります
  - 4.4 系の kernel に組み込まれている RBD client は Ceph jewel 以降で利用される feature Ceph CRUSH_TUNABLES5) に対応していないため、(Ceph server 側の feature を disable にしない限りは) rbd map ができません
3. [Plugins are not compatible with ARM64 when running on rook](https://github.com/ceph/ceph-csi/issues/671)
  - CSI driver について、2019年10月現在は ARM64 の Container Image が提供されていません
  - 従来の flexvolume を使用するか、または自身で Container Image をビルドする必要があります

ROCK64 では最新版の Ubuntu18.04LTS等 が提供されておりますが、Kernel については ayufan-rock64 と呼ばれる、ROCK64のハードウェア対応パッチが適用済みの独自 Kernel が使用されております。
また、ayufan-rock64 の github Issue を見た限りでは、rbd module を公式版の kernel に組み込む予定はない模様です。

このため、少々面倒ではありますが、kernel を自前でビルドする必要があります。

## rbd module のビルド
現在稼働中の kernel version を 'uname -a' コマンド等で確認した上で、対応する ayufan-rock64 の kernel source をダウンロードします。

```bash

# ROCK64 で使用してる linux kernel の source code をダウンロードします
wget https://github.com/ayufan-rock64/linux-kernel/archive/4.4.132-1092-rockchip-ayufan.tar.gz
tar zxvf 4.4.132-1092-rockchip-ayufan.tar.gz
cd linux-kernel-4.4.132-1092-rockchip-ayufan
cp /boot/config-4.4.132-1075-rockchip-ayufan-ga83beded8524 .config
vi .config

# kernel RBD client の feature を jewel 以降に対応させるために、次の back-port patch を適用します
# 副作用として cephfs の mount が出来なる可能性がありますが、4.4 系 kernel だと cephfs の動作については
# あまり期待できないので、rbd client の　feature を優先させます
wget https://gist.githubusercontent.com/sogabe/cd79bdc84be8e7f05c64cb96d380e928/raw/90d444d0982e7c45f5bda97ad861740a0fe7455d/gistfile1.txt
patch -p1 < gistfile1.txt

# RBD client モジュールを kernel に組み込みます
vi .config
+++ (追加するコンフィグ)
CONFIG_BLK_DEV_RBD=m
CONFIG_CEPH_LIB=m
CONFIG_CEPH_FS=m
+++

# kernel package をビルドします
make -j5 bindeb-pkg
```

## Rook のデプロイ
rbd module が組み込まれた kernel をインストールした上で 、Rook のデプロイを実施します。
今回は、Rook v1.1.2 を使用しました。

下記の手順で、Rook operator のデプロイを実施します。

```bash
git clone http://github.com/rook/rook
cd rook
git checkout -b v1.1.2 refs/tags/v1.1.2

cd cluster/examples/kubernetes/ceph

kubectl create -f common.yaml
cp operator.yaml my-operator.yaml
vi my-operator.yaml
kubectl create -f my-operator.yaml
```

operator.yaml に CSI の image を設定できる箇所があるので、次のように変更します。

```my-operator.yaml
      - name: ROOK_CSI_CEPH_IMAGE
        value: "sogabe/cephcsi:v1.2.1"
      - name: ROOK_CSI_REGISTRAR_IMAGE
        value: "sogabe/csi-node-driver-registrar:v1.1.0"
      - name: ROOK_CSI_PROVISIONER_IMAGE
        value: "sogabe/csi-provisioner:v1.3.0"
      - name: ROOK_CSI_SNAPSHOTTER_IMAGE
        value: "sogabe/csi-snapshotter:v1.2.0"
      - name: ROOK_CSI_ATTACHER_IMAGE
        value: "sogabe/csi-attacher:v1.2.0"
```

続いて、Ceph Cluster のデプロイを実施します。operator.yaml については、examples にて提供されているデフォルト設定をそのまま使用すると、既存disk を scan する際にエラーが発生してしまい、正しく osd のデプロイが出来ませんでした。

回避方法としては、下記の 'my-cluster.yaml' のように、deviceFilter: "sd." のように明示的なデバイス名の設定をすることで、不必要なデバイススキャンを抑止できます。

```bash
# rook-ceph operator の Pod が起動していることを確認します
kubectl -n rook-ceph get pod

# example として提供されている cluster.yaml を元に、my-cluster.yaml をカスタマイズします
cp cluster.yaml my-cluster.yaml
vi my-cluster.yaml

# Ceph Cluster のデプロイを実施します
kubectl create -f my-cluster.yaml
```

```my-cluster.yaml
...(snip)
hostNetwork: true
...(snip)

storage: # cluster level storage configuration and selection
  useAllNodes: true
  useAllDevices: true
  deviceFilter: "^sd."
```

# Rook Pod稼働状況の確認
Rook による Ceph のデプロイが完了すると、rook-ceph namespace に次のように Pod が起動します。
もし Error となっている Pod 等があれば、rook-ceph-operator Pod の log を確認することで原因を切り分けます。

```bash
rock64@node01:~/rook/cluster/examples/kubernetes/ceph$ kubectl -n rook-ceph get pod -o wide
NAME                                           READY   STATUS      RESTARTS   AGE     IP              NODE     NOMINATED NODE   READINESS GATES
csi-cephfsplugin-9nhfk                         3/3     Running     0          9m44s   192.168.3.201   node01   <none>           <none>
csi-cephfsplugin-dx85w                         3/3     Running     0          9m43s   192.168.3.202   node02   <none>           <none>
csi-cephfsplugin-l7fqx                         3/3     Running     0          9m43s   192.168.3.203   node03   <none>           <none>
csi-cephfsplugin-nx6p5                         3/3     Running     0          9m42s   192.168.3.204   node04   <none>           <none>
csi-cephfsplugin-provisioner-778d7d9cc-nrrm9   4/4     Running     1          9m43s   10.244.3.153    node04   <none>           <none>
csi-cephfsplugin-provisioner-778d7d9cc-sn5sq   4/4     Running     0          9m44s   10.244.2.101    node03   <none>           <none>
csi-rbdplugin-4twx5                            3/3     Running     0          9m45s   192.168.3.202   node02   <none>           <none>
csi-rbdplugin-c9986                            3/3     Running     0          9m45s   192.168.3.201   node01   <none>           <none>
csi-rbdplugin-nrs8r                            3/3     Running     0          9m45s   192.168.3.203   node03   <none>           <none>
csi-rbdplugin-provisioner-6cffbcf556-56w6l     5/5     Running     0          9m45s   10.244.0.141    node01   <none>           <none>
csi-rbdplugin-provisioner-6cffbcf556-w9wzs     5/5     Running     2          9m45s   10.244.3.152    node04   <none>           <none>
csi-rbdplugin-z5fl5                            3/3     Running     0          9m45s   192.168.3.204   node04   <none>           <none>
rook-ceph-mgr-a-68669cd78b-2xj8f               1/1     Running     2          6m54s   192.168.3.202   node02   <none>           <none>
rook-ceph-mon-a-8b55dbb74-6sql6                1/1     Running     0          8m54s   192.168.3.202   node02   <none>           <none>
rook-ceph-mon-b-665c9fc996-nhkkn               1/1     Running     0          8m24s   192.168.3.203   node03   <none>           <none>
rook-ceph-mon-c-54fdcc9f6f-bfvdq               1/1     Running     0          7m51s   192.168.3.201   node01   <none>           <none>
rook-ceph-operator-f444fbc5-5hxtf              1/1     Running     2          10m     10.244.3.150    node04   <none>           <none>
rook-ceph-osd-0-6f59c77cfc-dzzhh               1/1     Running     0          29s     192.168.3.204   node04   <none>           <none>
rook-ceph-osd-1-fd8f6d66c-42r7p                1/1     Running     0          36s     192.168.3.201   node01   <none>           <none>
rook-ceph-osd-2-59f5ff7bcc-mghpc               1/1     Running     0          31s     192.168.3.203   node03   <none>           <none>
rook-ceph-osd-3-86f6c78cb8-5cdk9               1/1     Running     0          35s     192.168.3.202   node02   <none>           <none>
rook-ceph-osd-prepare-node01-hgwc6             0/1     Completed   0          47s     192.168.3.201   node01   <none>           <none>
rook-ceph-osd-prepare-node02-zdwfs             0/1     Completed   0          45s     192.168.3.202   node02   <none>           <none>
rook-ceph-osd-prepare-node03-cww9f             0/1     Completed   0          43s     192.168.3.203   node03   <none>           <none>
rook-ceph-osd-prepare-node04-bdn28             0/1     Completed   0          41s     192.168.3.204   node04   <none>           <none>
rook-discover-29sz7                            1/1     Running     0          10m     10.244.2.100    node03   <none>           <none>
rook-discover-bh46r                            1/1     Running     0          10m     10.244.1.118    node02   <none>           <none>
rook-discover-g7ljp                            1/1     Running     0          10m     10.244.3.151    node04   <none>           <none>
rook-discover-hxjxw                            1/1     Running     0          10m     10.244.0.140    node01   <none>           <none>
```

# Rook toolbox Pod の起動
Ceph の稼働状況を簡単に確認できる Tool が Pod として提供されているので、次の手順にて k8s にデプロイを実施しておきます。

```bash
# Rook toolbox のデプロイ
kubectl create -f toolbox.yaml

# toolbox の起動方法
kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') bash
```

toolbox Pod では、ceph admin の Credential が設定済のため、ceph client の設定をしなくても次のように ceph コマンドを叩くだけで Ceph の動作確認が出来ます。
運用管理の観点で k8s のノードに ceph-common のパッケージをインストールしたく無い場合は、toolbox Pod を使うのが便利です。

```bash
[root@node04 /]# ceph -s
  cluster:
    id:     2af2c49c-788b-4c57-bdc7-b983c65bf9bd
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum a,b,c (age 6m)
    mgr: a(active, since 3m)
    osd: 4 osds: 4 up (since 2m), 4 in (since 2m)

  data:
    pools:   0 pools, 0 pgs
    objects: 0 objects, 0 B
    usage:   4.0 GiB used, 1.8 TiB / 1.8 TiB avail
    pgs:

[root@node04 /]# ceph osd status
+----+--------+-------+-------+--------+---------+--------+---------+-----------+
| id |  host  |  used | avail | wr ops | wr data | rd ops | rd data |   state   |
+----+--------+-------+-------+--------+---------+--------+---------+-----------+
| 0  | node04 | 1025M |  463G |    0   |     0   |    0   |     0   | exists,up |
| 1  | node03 | 1025M |  463G |    0   |     0   |    0   |     0   | exists,up |
| 2  | node02 | 1025M |  463G |    0   |     0   |    0   |     0   | exists,up |
| 3  | node01 | 1025M |  463G |    0   |     0   |    0   |     0   | exists,up |
+----+--------+-------+-------+--------+---------+--------+---------+-----------+

[root@node04 /]# ceph df
RAW STORAGE:
    CLASS     SIZE        AVAIL       USED        RAW USED     %RAW USED
    hdd       1.8 TiB     1.8 TiB     6.8 MiB      4.0 GiB          0.22
    TOTAL     1.8 TiB     1.8 TiB     6.8 MiB      4.0 GiB          0.22

POOLS:
    POOL     ID     STORED     OBJECTS     USED     %USED     MAX AVAIL

[root@node04 /]# rados df
POOL_NAME USED OBJECTS CLONES COPIES MISSING_ON_PRIMARY UNFOUND DEGRADED RD_OPS RD WR_OPS WR USED COMPR UNDER COMPR

total_objects    0
total_used       4.0 GiB
total_avail      1.8 TiB
total_space      1.8 TiB
```

# k8s Storage Class の作成
k8s から Dynamic Provisioning を用いた Persistent Volume を使えるようにするために、Storage Class を作成します。
ここでは、Rook の example ディレクトリに用意されている storageclass.yaml を変更せずに使用しました。

```bash
# Kubernetes storage class の作成
cd csi/rbd
kubectl create -f storageclass.yaml

rock64@node01:~/rook/cluster/examples/kubernetes/ceph/csi/rbd$ kubectl get sc
NAME              PROVISIONER                  AGE
rook-ceph-block   rook-ceph.rbd.csi.ceph.com   9s
```

# PVC の作成
続いて、PVC を作成します。次のコマンドを実行します。

```bash
kubectl create -f pvc.yaml

rock64@node01:~/rook/cluster/examples/kubernetes/ceph/csi/rbd$ kubectl get pvc
NAME      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
rbd-pvc   Bound    pvc-67891e72-8a9b-4ab7-b2d9-b940e5fdd772   1Gi        RWO            rook-ceph-block   72s

kubectl create -f pod.yaml

rock64@node01:~/rook/cluster/examples/kubernetes/ceph/csi/rbd$ kubectl get pod -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
csirbd-demo-pod   1/1     Running   0          32s   10.244.1.30   node02   <none>           <none>

# mount | grep rbd
/dev/rbd0 on /var/lib/www/html type ext4 (rw,relatime,stripe=1024,data=ordered)

rock64@node01:~/rook/cluster/examples/kubernetes/ceph/csi/rbd$ kubectl exec -it csirbd-demo-pod sh
# du -h /var/lib/www/html
16K     /var/lib/www/html/lost+found
20K     /var/lib/www/html

rock64@node02:~$ mount | grep rbd0
/dev/rbd0 on /var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-67891e72-8a9b-4ab7-b2d9-b940e5fdd772/globalmount/0001-0009-rook-ceph-0000000000000001-c3df3f23-f17c-11e9-88d9-9650f8d1b915 type ext4 (rw,relatime,stripe=1024,data=ordered)
/dev/rbd0 on /var/lib/kubelet/pods/6c49a710-f59a-43f3-b284-d99772386f9e/volumes/kubernetes.io~csi/pvc-67891e72-8a9b-4ab7-b2d9-b940e5fdd772/mount type ext4 (rw,relatime,stripe=1024,data=ordered)
```

# ストレージのベンチマーク結果
Ceph RBD の性能を測定するために、fio を用いたベンチマークを実施しました。
測定内容としては、次のように random read / random write について確認します。

```bench.sh
#!/bin/sh

fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=1024k --time_based=1 --runtime=180 --name=fio_direct_write_test_1024k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=256k --time_based=1 --runtime=180 --name=fio_direct_write_test_256k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=128k --time_based=1 --runtime=180 --name=fio_direct_write_test_128k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=64k --time_based=1 --runtime=180 --name=fio_direct_write_test_64k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=32k --time_based=1 --runtime=180 --name=fio_direct_write_test_32k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=16k --time_based=1 --runtime=180 --name=fio_direct_write_test_16k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=8k --time_based=1 --runtime=180 --name=fio_direct_write_test_8k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=4k --time_based=1 --runtime=180 --name=fio_direct_write_test_4k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=2k --time_based=1 --runtime=180 --name=fio_direct_write_test_2k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randwrite --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=1k --time_based=1 --runtime=180 --name=fio_direct_write_test_1k

fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=1024k --time_based=1 --runtime=180 --name=fio_direct_read_test_1024k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=256k --time_based=1 --runtime=180 --name=fio_direct_read_test_256k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=128k --time_based=1 --runtime=180 --name=fio_direct_read_test_128k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=64k --time_based=1 --runtime=180 --name=fio_direct_read_test_64k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=32k --time_based=1 --runtime=180 --name=fio_direct_read_test_32k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=16k --time_based=1 --runtime=180 --name=fio_direct_read_test_16k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=8k --time_based=1 --runtime=180 --name=fio_direct_read_test_8k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=4k --time_based=1 --runtime=180 --name=fio_direct_read_test_4k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=2k --time_based=1 --runtime=180 --name=fio_direct_read_test_2k
fio --filename=/var/rbd/fio.test --direct=1 --rw=randread --size=1G --randrepeat=0 --ioengine=libaio --group_reporting=1 --numjobs=1 --iodepth=128 --bs=1k --time_based=1 --runtime=180 --name=fio_direct_read_test_1k
```

| block size (kB)  | Read IOPS | Write IOPS |
|:-----------------|-----------|------------|
| 1                | 1692.11   | 869.62     |
| 2                | 1815.70   | 858.14     |
| 4                | 1786.29   | 937.58     |
| 8                | 1680.98   | 861.11     |
| 16               | 1555.00   | 737.84     |
| 32               | 1353.08   | 557.62     |
| 64               | 1146.64   | 502.13     |
| 128              | 811.52    | 372.57     |
| 256              | 419.00    | 218.16     |
| 1024             | 105.83    | 59.96      |

ベースラインの Random I/O 性能(SSD XFS)
![overall-disk-performance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96389/f1069c6d-853f-fecf-4517-98c10e53e0fc.png)

Ceph RBD Random I/O 性能 (4-OSD, 3-replica)
![overall-disk-performance-rbd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96389/3e704c9a-dae7-0d7c-09b4-16d3dd94f7f6.png)


結果としては、ceph-osd 4ノード構成ではベースライン性能と比べて Small Size Write で 1/5 程度、Large Size Write だと 同程度の性能に近づくことが分かりました。今回は ROCK64 の制約により RBD client が古い kernel version となっている点を考慮すると、ROCK64 の Ceph RBD はとても良い性能が出ていると考えられます。

# k8s リソース消費量についての考察
k8s を導入すると様々なメリットがある反面、k8s 自体が CPU/Memory 等のリソースを消費するため、どの程度のコストとなっているのかについて考えてみます。
k8s master を 3-node 冗長で運用した場合、4-node のクラスタ全体でどの程度の CPU/Memory を消費しているのかを計算します。

top コマンドにて kubelet, kube-apiserver および etcd のリソース消費量を調べたところ、次のようになりました。

| Process | Resource | node1   | node2   | node3   | node4  |
|:--------|:---------|:--------|:--------|:--------|:-------|
| kubelet | RSS      | 92344   | 116716  | 113032  | 107172 |
| kubelet | CPU%     | 24.3   | 23.6  | 22.7  | 17.5 |
| kubelet | MEM%     | 2.2   | 2.9  | 2.8  | 2.6 |
| kube-apiserver | RSS      | 375996   | 379248  | 461772  |  |
| kube-apiserver | CPU%     | 17.0   | 17.1  | 16.2  | |
| kube-apiserver | MEM%     | 9.3   | 9.4  | 11.4  | |
| etcd | RSS      | 115428   | 115184  | 126576  |  |
| etcd | CPU%     | 18.8   | 19.7  | 19.8  | |
| etcd | MEM%     | 2.8   | 2.8  | 3.1  | |

上記の表から1ノードあたりの Memory/CPU 消費量を計算すると、次のようになりました。各コンポーネントを合計すると、1ノードあたり CPU 12% 程度、Memory 500MB 程度を消費することになります。

- Memory 消費量 (1ノードあたり)
  - kubelet
    - 107 MB
  - kube-apiserver
    - 304 MB
  - etcd
    - 89 MB
- CPU 消費量 (1ノードあたり)
  - kubelet
    - 5.5 %
  - kube-apiserver
    - 3.1 %
  - etcd
    - 3.6 %

Ceph には自己修復機能やクラスタ管理の機能が内蔵されているため、実際のところは k8s が無くても支障なくクラスタを運用することが出来ます。
もし k8s を使って他のアプリを管理する用途が全く無い場合は、Ceph のデプロイについては ceph-ansible を使う方がコストの観点では有利になります。

Container を用いた Ceph の運用管理についてはメリットも大きいので、Container が使えれば十分であれば ceph-ansible の Container Deployment を検討してみると良いと思います。

# おわりに
今回は「ROCK64 + Rook で作る、お家最強のお父さんCeph」を作るプロジェクトに取り組んできましたが、当初の目的であった「5万円前後で」で「そこそこの性能が出る」「お家に置ける」Ceph クラスタ を無事に構築することができました。
また、おまけとして、冗長構成の Kubernetes クラスタ と Rook による Ceph管理機能 も付いてきたので、お得感も満載(?)になりました。

ARM系の Single Board Computer で使われている System on Chip (SoC) はスマホ普及のおかげで量産効果による価格低減が既に実現しております。また、ARMの特長である消費電力あたりのCPU性能が圧倒的に高い点のおかげで、家庭で Ceph クラスタを置くことが現実的な選択肢に入ってきたと考えられます。

皆様のご家庭にも是非、Ceph を1クラスタ置いてみてはいかがでしょうか。


# 参考情報: CSI Driver Container Image のビルド方法
CSIドライバの Container Image を自分でビルドする場合は、次のような手順を実施します。

```bash
# Golang をインストールします
mkdir ~/ceph-csi-build
cd ~/ceph-csi-build
wget https://dl.google.com/go/go1.13.3.linux-arm64.tar.gz
sudo tar -C /usr/local -xzf go1.13.3.linux-arm64.tar.gz
export PATH=$PATH:/usr/local/go/bin
mkdir $HOME/golang
cd $HOME/golang
export GOPATH=$HOME/golang
export PATH=$GOPATH/bin:$PATH

# ceph-csi Container をビルドします
go get -d github.com/ceph/ceph-csi
cd $GOPATH/src/github.com/ceph/ceph-csi
git checkout -b v1.2.1 refs/tags/v1.2.1
ls -l _output

# Dockerhub に Container Image を Push するための設定を予めしておきます
export DOCKER_USERNAME=foo
docker login

# Container Image の build, push を実施します
make push-image-cephcsi CSI_IMAGE_NAME=${DOCKER_USERNAME}/cephcsi

# node-driver-registrar Container を Build/Push します
go get -d github.com/kubernetes-csi/node-driver-registrar
cd $GOPATH/src/github.com/kubernetes-csi/node-driver-registrar
git checkout -b v1.1.1 refs/tags/v1.1.0
make container
make push REGISTRY_NAME=${DOCKER_USERNAME}

# external-provisioner Container を Build/Push します
go get -d github.com/kubernetes-csi/external-provisioner
cd $GOPATH/src/github.com/kubernetes-csi/external-provisioner
git checkout -b v1.3.0 refs/tags/v1.3.0
make push REGISTRY_NAME=${DOCKER_USERNAME}

# external-attacher Container を Build/Push します
go get -d github.com/kubernetes-csi/external-attacher
cd $GOPATH/src/github.com/kubernetes-csi/external-attacher
git checkout -b v1.2.0 refs/tags/v1.2.0
make push REGISTRY_NAME=${DOCKER_USERNAME}

# external-snapshotter を Build/Push します
go get -d github.com/kubernetes-csi/external-snapshotter
cd $GOPATH/src/github.com/kubernetes-csi/external-snapshotter
git checkout -b v1.2.0 refs/tags/v1.2.0
vi release-tools/build.make
# image の architecture を arm64 に指定するため、option --platform arm を追加
# docker の version が新しくないと error になります
make push REGISTRY_NAME=${DOCKER_USERNAME}
```