OpenShift Data Foundation (ODF) を導入する

OpenShift 上のストレージ統合基盤である OpenShift Data Foundation (ODF、旧称: OpenShift Container Storage, OCS）をインストールする。

ODF は、主に Rook-Ceph と NooBaa によって構成される非常に強力なストレージ統合基盤である[^1]。ODF を導入すると、Ceph-Rook による PV の Dyanmic provisioning、および NooBaa による S3 Bucket の Dynamic provisioning が簡単に利用できるようになる。

ODF のインストールは Operator Hub から簡単に行うことができる。
本記事では、OKD4 で OpenShift Data Foundation を導入する方法を説明する。

## 前提条件
- 最低 3台の worker node
- 最低 3台の 未フォーマットディスク 
- (OKDの場合) Community 版以外の Operator を利用可能にしておく （参考：[OKD をインストールした｢次｣にすべき初期設定 - Qiita](https://qiita.com/sawa2d2/items/275ea119bd25ac2033a3)）

## ODF のインストール
### Local Storage Operator のインストール
ODF Operator は Local Storage Operator に依存するため、まずはこれをインストールする。
OpenShift のダッシュボード から Operator Hub を開き、"Local Storage" などで検索して Local Storage Operator を見つける。

![Screenshot from 2023-11-28 13-28-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/1a71444d-16fd-a9a8-a84a-edd350b4dcb4.png)


「インストール」をクリックする。
![Screenshot from 2023-11-28 13-28-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/45728e1f-9673-2f03-03a7-a5ae942ae206.png)

インストールが完了するまでしばらく待つ。

### OpenShift Data Foundation Operator のインストール

Operator Hub から "ODF" などで検索して "OpenShift Data Foundation" を見つける。

![Screenshot from 2023-11-28 13-06-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/b011d95d-4316-6e60-fa2c-c86af72d698f.png)

"インストール" をクリックする。
![Screenshot from 2023-11-28 13-06-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/ac420fa7-8e19-e5f0-a5c7-747dcdd9c1fb.png)

オプションはデフォルトのまま "インストール" をクリックする。
![Screenshot from 2023-11-28 13-07-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/f4b6cf54-c033-03cb-a50b-e2c761c73b29.png)

Operator のインストールが完了するまでしばらく待つ。

### StorageSystem の作成

Operator 画面より "Storage System の作成" をクリックすると、次のような ODF を設定するための専用 Web コンソールが現れる（もし見た目が違う場合は、ウェブブラウザを更新すれば表示される可能性がある）。

すべてデフォルトのまま「次へ」を押す。
![Screenshot from 2024-06-09 14-45-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/7667aaa2-e4c1-8e02-07ab-fa2a973bff19.png)

すると、Operator がノード上の未フォーマットディスクをスキャンする。完了までしばらく待つ。

![Screenshot from 2024-06-09 14-48-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/c1ec0d77-b656-83d0-1d2d-2bbd5b385633.png)

スキャンが終わり、node と disk の要件を満たしていれば次のように Local Block の設定ができるようになる（画面では 3Node, 3Disk が検知されている）。
LocalVolumeSet および StorageClass の名前は自由だが、慣習的にどちらも `localblock` を設定する。
その他の設定はすべてデフォルトのまま「次へ」をクリックする。

![Screenshot from 2024-02-02 09-19-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/76c30906-db79-0261-1772-c700da6da034.png)

以下の設定項目は主にストレージパフォーマンスに関わる設定なので、こだわりがなければすべてデフォルトのまま「次へ」をクリックする。

![Screenshot from 2024-06-09 17-18-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/ff718cac-5215-f91a-8af3-17614ec382b0.png)

:::note
ODF を構成するノードの vCPU の合計が30、Memory の合計が 72GiB に満たない場合、ODF は最小構成で構築される。これでも問題なく使えるのだが、Multicloud Object Gateway (NooBaa) が提供する Object Bucket Claim の機能は利用できない。
:::

デフォルトのまま「次へ」をクリックする。

![Screenshot from 2024-06-09 17-19-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/2fc0e99d-550e-9847-d734-8b7aff5d4af8.png)

デフォルトのまま「次へ」をクリックする
![Screenshot from 2024-06-09 17-19-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/fcd62b97-7bf6-0863-fbe1-2058df2f0aac.png)



最後に確認画面が現れるので、「StorageSystem の作成」をクリックする。


![Screenshot from 2024-06-09 17-19-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261727/2031c92d-3a5d-675c-521d-e0bfbf28d4fc.png)


### インストールの完了を待つ

StorageSystem のインストールが開始されるので、インストールが完了までしばらく待つ。
インストールが完了すると、各種 storageClass が利用できるようになり、ストレージリソースのダイナミックプロビジョニングが利用できるようになる。

```
$ oc get sc
NAME                                    PROVISIONER                             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
localblock                              kubernetes.io/no-provisioner            Delete          WaitForFirstConsumer   false                  16m
ocs-storagecluster-ceph-rbd (default)   openshift-storage.rbd.csi.ceph.com      Delete          Immediate              true                   10m
ocs-storagecluster-ceph-rgw             openshift-storage.ceph.rook.io/bucket   Delete          Immediate              false                  14m
ocs-storagecluster-cephfs               openshift-storage.cephfs.csi.ceph.com   Delete          Immediate              true                   10m
openshift-storage.noobaa.io             openshift-storage.noobaa.io/obc         Delete          Immediate              false                  9m29s
```

```
$ oc get pods -n openshift-storage -o wide
NAME                                                              READY   STATUS      RESTARTS        AGE     IP            NODE      NOMINATED NODE   READINESS GATES
csi-addons-controller-manager-bc6d99647-px6s9                     2/2     Running     0               14m     10.130.0.21   worker2   <none>           <none>
csi-cephfsplugin-526kg                                            2/2     Running     0               8m39s   10.0.0.21     worker0   <none>           <none>
csi-cephfsplugin-provisioner-fb6d544d5-2dnpb                      6/6     Running     0               8m39s   10.128.2.31   worker1   <none>           <none>
csi-cephfsplugin-provisioner-fb6d544d5-p8879                      6/6     Running     1 (7m40s ago)   8m39s   10.131.0.17   worker0   <none>           <none>
csi-cephfsplugin-thmd5                                            2/2     Running     0               8m39s   10.0.0.22     worker1   <none>           <none>
csi-cephfsplugin-xkb7h                                            2/2     Running     1 (7m56s ago)   8m39s   10.0.0.23     worker2   <none>           <none>
csi-rbdplugin-29dwl                                               3/3     Running     1 (7m57s ago)   8m39s   10.0.0.23     worker2   <none>           <none>
csi-rbdplugin-428q6                                               3/3     Running     0               8m39s   10.0.0.22     worker1   <none>           <none>
csi-rbdplugin-849zr                                               3/3     Running     1 (7m51s ago)   8m39s   10.0.0.21     worker0   <none>           <none>
csi-rbdplugin-provisioner-5958c5cbd8-2fmgl                        6/6     Running     2 (7m14s ago)   8m39s   10.130.0.25   worker2   <none>           <none>
csi-rbdplugin-provisioner-5958c5cbd8-ntq62                        6/6     Running     2 (7m41s ago)   8m39s   10.128.2.30   worker1   <none>           <none>
noobaa-core-0                                                     1/1     Running     0               3m32s   10.128.2.49   worker1   <none>           <none>
noobaa-db-pg-0                                                    1/1     Running     0               4m34s   10.128.2.44   worker1   <none>           <none>
noobaa-endpoint-598c668b96-qm5vz                                  1/1     Running     0               3m49s   10.128.2.48   worker1   <none>           <none>
noobaa-operator-557df4ff56-npcbn                                  1/1     Running     0               14m     10.128.2.25   worker1   <none>           <none>
ocs-metrics-exporter-5856bbf967-l5z2h                             1/1     Running     0               4m33s   10.128.2.43   worker1   <none>           <none>
ocs-operator-85558788df-dxrwp                                     1/1     Running     0               14m     10.128.2.23   worker1   <none>           <none>
odf-console-5b77c9fb5c-sgj8n                                      1/1     Running     0               15m     10.130.0.19   worker2   <none>           <none>
odf-operator-controller-manager-7bd49f9b9f-4szcs                  2/2     Running     0               15m     10.128.2.22   worker1   <none>           <none>
rook-ceph-crashcollector-worker0-6c79898755-c9vd4                 1/1     Running     0               5m26s   10.131.0.31   worker0   <none>           <none>
rook-ceph-crashcollector-worker1-5bcf44975b-cmxz7                 1/1     Running     0               5m59s   10.128.2.34   worker1   <none>           <none>
rook-ceph-crashcollector-worker2-7ff49cf8b9-kr6zb                 1/1     Running     0               5m24s   10.130.0.37   worker2   <none>           <none>
rook-ceph-exporter-worker0-58b4f448f8-qp2l4                       1/1     Running     0               5m23s   10.131.0.32   worker0   <none>           <none>
rook-ceph-exporter-worker1-7db69864b5-qm8qr                       1/1     Running     0               5m59s   10.128.2.35   worker1   <none>           <none>
rook-ceph-exporter-worker2-6f477d8d5b-5tqdh                       1/1     Running     0               5m21s   10.130.0.38   worker2   <none>           <none>
rook-ceph-mds-ocs-storagecluster-cephfilesystem-a-74b8856dtvhvr   2/2     Running     0               5m26s   10.131.0.30   worker0   <none>           <none>
rook-ceph-mds-ocs-storagecluster-cephfilesystem-b-7c6759d5jn59x   2/2     Running     0               5m24s   10.130.0.36   worker2   <none>           <none>
rook-ceph-mgr-a-8499d755b6-w4mkr                                  3/3     Running     0               6m9s    10.131.0.21   worker0   <none>           <none>
rook-ceph-mgr-b-d6d97fc67-p4hxv                                   3/3     Running     0               6m7s    10.130.0.29   worker2   <none>           <none>
rook-ceph-mon-a-d9dc6b7b4-t2d4m                                   2/2     Running     0               6m52s   10.131.0.20   worker0   <none>           <none>
rook-ceph-mon-b-744c58b4b6-sqtpb                                  2/2     Running     0               6m29s   10.128.2.33   worker1   <none>           <none>
rook-ceph-mon-c-674bd8dbfd-wcrd4                                  2/2     Running     0               6m19s   10.130.0.28   worker2   <none>           <none>
rook-ceph-operator-695c78fbb5-p2ppl                               1/1     Running     0               8m39s   10.131.0.18   worker0   <none>           <none>
rook-ceph-osd-0-78fd58b68c-pqzfz                                  2/2     Running     0               5m38s   10.131.0.25   worker0   <none>           <none>
rook-ceph-osd-1-8c65f64bc-tb7vg                                   2/2     Running     0               5m38s   10.130.0.33   worker2   <none>           <none>
rook-ceph-osd-2-56fb865976-vfvfd                                  2/2     Running     0               5m37s   10.128.2.37   worker1   <none>           <none>
rook-ceph-osd-prepare-248eb233129237034fc512221ad7b957-j9g7q      0/1     Completed   0               5m46s   10.130.0.32   worker2   <none>           <none>
rook-ceph-osd-prepare-953e15abcdfe43c19cf15cd789931683-kbkm9      0/1     Completed   0               5m46s   10.128.2.36   worker1   <none>           <none>
rook-ceph-osd-prepare-ae566fab2e0126d021ccbb76cf99da2e-kjjr2      0/1     Completed   0               5m46s   10.131.0.24   worker0   <none>           <none>
rook-ceph-rgw-ocs-storagecluster-cephobjectstore-a-6ccf557ptg45   2/2     Running     0               5m11s   10.131.0.33   worker0   <none>           <none>
ux-backend-server-865fb7b949-2j2f6                                2/2     Running     0               14m     10.131.0.13   worker0   <none>           <none>
```

:::note
最小構成で ODF を構築した場合、Multicloud Object Gateway (NooBaa) に関するサービスは立ち上がらない：
<details><summary>最小構成時の oc get sc 実行例</summary>

```
# oc get sc
NAME                          PROVISIONER                             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
localblock                    kubernetes.io/no-provisioner            Delete          WaitForFirstConsumer   false                  4h41m
ocs-storagecluster-ceph-rbd   openshift-storage.rbd.csi.ceph.com      Delete          Immediate              true                   4h5m
ocs-storagecluster-ceph-rgw   openshift-storage.ceph.rook.io/bucket   Delete          Immediate              false                  4h39m
ocs-storagecluster-cephfs     openshift-storage.cephfs.csi.ceph.com   Delete          Immediate              true                   4h13m
```
</details>

<details><summary>最小構成時の oc get pods 実行例</summary>

```
# oc get pods -n openshift-storage -o wide
NAME                                                              READY   STATUS      RESTARTS        AGE     IP                NODE      NOMINATED NODE   READINESS GATES
csi-addons-controller-manager-86c8845897-9pmr8                    2/2     Running     0               45s     10.130.0.170      master2   <none>           <none>
csi-cephfsplugin-fw5cb                                            2/2     Running     0               4h40m   192.168.126.103   master2   <none>           <none>
csi-cephfsplugin-hh2mq                                            2/2     Running     0               4h40m   192.168.126.101   master0   <none>           <none>
csi-cephfsplugin-j5jq7                                            2/2     Running     0               4h40m   192.168.126.102   master1   <none>           <none>
csi-cephfsplugin-provisioner-684cd54648-dms9b                     5/5     Running     0               4h40m   10.130.0.81       master2   <none>           <none>
csi-cephfsplugin-provisioner-684cd54648-vflj8                     5/5     Running     0               4h40m   10.129.0.97       master1   <none>           <none>
csi-rbdplugin-2d8t5                                               3/3     Running     0               4h40m   192.168.126.103   master2   <none>           <none>
csi-rbdplugin-5g8rx                                               3/3     Running     0               4h40m   192.168.126.102   master1   <none>           <none>
csi-rbdplugin-kktr7                                               3/3     Running     0               4h40m   192.168.126.101   master0   <none>           <none>
csi-rbdplugin-provisioner-6d9475547b-9sqbg                        6/6     Running     0               4h40m   10.128.0.81       master0   <none>           <none>
csi-rbdplugin-provisioner-6d9475547b-m2r7f                        6/6     Running     1 (4h26m ago)   4h40m   10.130.0.80       master2   <none>           <none>
noobaa-operator-77bdd4c4d5-2s4sv                                  0/2     Pending     0               4h14m   <none>            <none>    <none>           <none>
ocs-metrics-exporter-7bfd744777-k6dq6                             1/1     Running     0               4h58m   10.128.0.69       master0   <none>           <none>
ocs-operator-6c7d8b766f-kf9cp                                     1/1     Running     0               4h58m   10.129.0.89       master1   <none>           <none>
odf-console-bfcd7d6b7-42qkh                                       0/1     Pending     0               4h14m   <none>            <none>    <none>           <none>
odf-operator-controller-manager-67bc7f4b84-tqvc9                  0/2     Pending     0               4h9m    <none>            <none>    <none>           <none>
rook-ceph-crashcollector-master0-6d74f48f74-xxqsn                 1/1     Running     0               4h14m   10.128.0.91       master0   <none>           <none>
rook-ceph-crashcollector-master1-675558bf7f-gbvwg                 1/1     Running     0               4h14m   10.129.0.100      master1   <none>           <none>
rook-ceph-crashcollector-master2-fdfbdd88b-ds2vn                  1/1     Running     0               4h14m   10.130.0.91       master2   <none>           <none>
rook-ceph-exporter-master0-b8949dcfb-prv6b                        1/1     Running     0               4h14m   10.128.0.92       master0   <none>           <none>
rook-ceph-exporter-master1-585866f985-js4f9                       1/1     Running     0               4h14m   10.129.0.101      master1   <none>           <none>
rook-ceph-exporter-master2-5c96795676-zdp2h                       1/1     Running     0               4h14m   10.130.0.92       master2   <none>           <none>
rook-ceph-mds-ocs-storagecluster-cephfilesystem-a-86bfc6796g49m   0/2     Pending     0               4h14m   <none>            <none>    <none>           <none>
rook-ceph-mds-ocs-storagecluster-cephfilesystem-b-7c6d9957c5tp4   0/2     Pending     0               4h14m   <none>            <none>    <none>           <none>
rook-ceph-mgr-a-7ff95767f7-4jbvz                                  2/2     Running     0               4h14m   10.130.0.90       master2   <none>           <none>
rook-ceph-mon-a-7c5dcbfcb-6kw8g                                   2/2     Running     0               4h19m   10.130.0.87       master2   <none>           <none>
rook-ceph-mon-b-b79b47d79-qkt7c                                   2/2     Running     0               4h18m   10.128.0.89       master0   <none>           <none>
rook-ceph-mon-c-56fb588bd9-6xqt2                                  2/2     Running     0               4h18m   10.129.0.99       master1   <none>           <none>
rook-ceph-operator-8898bb758-rw4hk                                1/1     Running     0               4h40m   10.128.0.80       master0   <none>           <none>
rook-ceph-osd-0-7b65f476d8-wbf6w                                  2/2     Running     0               4h14m   10.129.0.228      master1   <none>           <none>
rook-ceph-osd-1-b98bc855f-tqm55                                   0/2     Pending     0               4h14m   <none>            <none>    <none>           <none>
rook-ceph-osd-2-86896567c9-k2nvz                                  2/2     Running     0               4h14m   10.128.0.102      master0   <none>           <none>
rook-ceph-osd-prepare-91ee1385653025dd09c26c66e657d415-sgqqv      0/1     Completed   0               4h14m   10.128.0.93       master0   <none>           <none>
rook-ceph-osd-prepare-b7a7405e6bfcde481796ca32d28c2274-l5nwb      0/1     Completed   0               4h14m   10.129.0.102      master1   <none>           <none>
rook-ceph-osd-prepare-ef22d8b1598af773971f64be25bcb10e-dhqff      0/1     Completed   0               4h14m   10.130.0.93       master2   <none>           <none>
rook-ceph-rgw-ocs-storagecluster-cephobjectstore-a-c45fd475jjt8   0/2     Pending     0               4h13m   <none>            <none>    <none>           <none>
```
</details>
:::

## Dynamic Provisioning の確認

次のような確認用の PVC および Pod の Manifest `rbdtest.yaml` を作成する：

```yaml:rbdtest.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbdtest-pvc
spec:
  storageClassName: ocs-storagecluster-ceph-rbd
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: rbdtest-bound-pod
spec:
  containers:
  - name: rbdtest-bound-container
    image: nginx
    volumeMounts:
    - mountPath: "/usr/share/nginx/html"
      name: rbdtest-volume
  volumes:
  - name: rbdtest-volume
    persistentVolumeClaim:
      claimName: rbdtest-pvc
```

リソースを作成する：
```
$ oc create -f rbdtest.yaml
persistentvolumeclaim/rbdtest-pvc created
pod/rbdtest-bound-pod created
```

PV が作成されていることを確認する：
```
$ oc get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM                                                      STORAGECLASS                  REASON   AGE
pvc-399f9ddc-a9fb-4ea5-9562-66ffe1eeba1d   1Gi        RWO            Delete           Bound         default/rbdtest-pvc                                        ocs-storagecluster-ceph-rbd            16s
```

確認が済んだら PVC と Pod は消す： 
```
$ oc delete -f rbdtest.yaml
persistentvolumeclaim "rbdtest-pvc" deleted
pod "rbdtest-bound-pod" deleted
```



[^1]: [CSIとRook-Ceph, NooBaaに見るCloud-native Storageの可能性@OpenShift Meetup #6 - Speaker Deck](https://speakerdeck.com/tutsunom/csitorook-ceph-noobaanijian-rucloud-native-storagefalseke-neng-xing-at-openshift-meetup-number-6)