Db2 11.5.5 on OpenShift デプロイ手順 -OCSストレージ利用構成-

Db2 on OpenShift の永続ボリュームとして、 OpenShift Container Storage(OCS) を利用する構成でデプロイした手順のメモと、各種コマンド実行ログです。
今後同様の作業を行うときの参考とできるように備忘録として残します。

環境：

 - OpenShift Container Platform (OCP) V4.6.19
 - OpenShift Container Storage (OCS) V4.6.3
 - Db2 on OpenShift V11.5.5.0-cn2 (Db2 Operator V1.0.3)

## Db2 on OpenShift におけるデータの永続性

データベースをコンテナ化するにあたって、最も重要なのはデータの永続性です。
コンテナ内にデータを格納してしまうと、コンテナが異常停止した時にDBデータが失われてしまいます。
想定外のタイミングでコンテナ障害が発生した場合にもデータは最新の状態で保持できるよう、Db2 on OpenShift のデータは PersistentVolume (PV) に配置されます。
ここで言う「データ」には以下の内訳があり、いずれも Persistent Volume に保持されます。


 __① メタデータ - System & Backup storage [Shared with RWX]__

 - Db2 instance home directory
 - Diagnostic logs
 - Other global configuration directories
 - Backups, Restore or Load locations


__② ユーザデータ - User storage [Exclusive with RWO]__

 - Database storage paths
 - Transaction logs


※「①メタデータ」のうちBackups用領域を別PVに分け、合計3PV構成とすることも可能

Db2では、データを保持するためのストレージとして、下記の種類のストレージをサポートしています。

 - IBM Spectrum® Scale Container Storage Interface 2.0 or higher
 - OpenShift Container Storage(OCS) 4.5
 - IBM® Cloud File Storage (ibmc-file-gold-gid storage class)
 - Portworx 2.6.2
 - Traditional storage:
	 - NFS
	 - IBM Spectrum Scale
	 - Local storage

参考：[Certified storage options for Db2 on Red Hat OpenShift](https://www.ibm.com/support/knowledgecenter/SSEPGG_11.5.0/com.ibm.db2.luw.db2u_openshift.doc/doc/c_db2u_cert-storage.html)

今回は、OCSにデータを保持する構成で、Db2をデプロイします。


##OpenShift Container Storage(OCS) とは
OpenShift Container Storage(OCS)は、OpenShift上のアプリケーションとしてストレージを構成し、他のアプリケーションに対してストレージサービスを提供できるようにするソフトウェアです。いわゆるCloud(Container) Native Storageです。
　出典：[赤帽エンジニアブログ](https://rheb.hatenablog.com/entry/ocs/01#:~:text=OpenShift%20Container%20Storage(OCS)%E3%81%AF,(Container)%20Native%20Storage%E3%81%A7%E3%81%99%E3%80%82)

OCSは OCP上のアプリケーションとして稼働しているストレージサービスで、Dynamic Provisioningに対応しています。
OCS をバックエンドとする StorageClass 名を指定してDb2uCluster(※)をデプロイすることにより、PVCが作成されます。PVC作成後、Dynamic Provisioning の仕組みに則りPVの要求が実行され、その要求を受けてPVが作成されます。このPVの実体は、OCSによって作成されたボリュームとなります。
(※)Db2uCluster：シングル構成Db2インスタンスのクラスタリソース定義(CRD)

Db2 on OpenShift では、以下のOCSストレージクラスを指定します。

|配置データ種別 |ストレージクラス名 |アクセスモード |
|:-:|:-:|:-:|
|メタデータ(System/backup data)   |ocs-storagecluster-cephfs   |ReadWriteMany (RWX)   |
|ユーザーデータ(User data)   |ocs-storagecluster-ceph-rbd   |ReadWriteOnce (RWO)   |


**補足：**
[マニュアル](https://www.ibm.com/support/knowledgecenter/SSEPGG_11.5.0/com.ibm.db2.luw.db2u_openshift.doc/doc/c_db2u_cert-storage.html)上、User data の欄に「4K sector size」と記載がありますが、これは 4K セクターサイズのストレージ(HDD)が必要という意味ではなく、4Kセクターサイズのストレージも利用可能であり、512バイトセクターサイズのストレージも4Kセクターサイズのストレージも、両方利用可能です。

むしろ、オンプレ版においてもコンテナ版においても、Db2ではデフォルトで512バイトセクターサイズのストレージが想定され、4Kセクターサイズのストレージを利用する場合には以下のレジストリー変数を設定しておく必要があります。


```
db2set DB2_4K_DEVICE_SUPPORT=ON
```

上記のレジストリー変数が設定されていない状態で 4K セクターサイズのストレージ上にDb2データベースを作成しようとすると、以下のようなエラーメッセージが発生し、DB作成が出来ません。

(標準出力) SQL0293N Error accessing a table space container. SQLSTATE=57048
(db2diag.log) DIA8501C A buffer pool logic error has occured.


OpenShift版の場合はYamlに記述します。

```yaml:Db2uCluster(一部抜粋)
spec:
  version: "11.5.5.0-cn2"

  environment:
    dbType: db2oltp
    database:
      name: sampledb
    instance:
      registry:
        DB2_4K_DEVICE_SUPPORT: "ON"
```



## Db2 デプロイ手順

OCS / Db2 Operator は導入済である前提で進めます。
Db2そのもののdeploy手順は以下の2ステップ。とってもシンプルです。

1. Yaml編集
2. Db2uClusterインスタンス作成

※Db2 Operator導入などの Db2 on OpenShift 導入作業の全体像・手順はこちらにまとめています。
---> [「Db2 11.5.5 on OpenShift デプロイ手順 -NFSストレージ利用構成- 」](https://qiita.com/mi-kana/items/6266fcdcdc3b71d8a0fb)

### Step1. Yaml編集
カスタムリソース Db2uCluster のインスタンスを作成します。
[Db2製品マニュアル](https://www.ibm.com/support/knowledgecenter/SSEPGG_11.5.0/com.ibm.db2.luw.db2u_openshift.doc/doc/c_db2ucluster_api.html)に掲載されるyamlサンプルYamlを必要に応じて編集します。
主要な項目としては、例えば下記プロパティを編集します。

**【主要な編集項目】**

 - metadata.name　... デプロイ毎に、固有となる名前
 - spec.environment.database.name　... Pod内で作成されるDB名
 - spec.environment.instance.password ... インスタンスオーナーdb2inst1ユーザのパスワード

**【ストレージ関連の編集項目】**

 - spec.storage.spec.storageClassName ... OCSストレージクラス名を指定
 - spec.storage.spec.resources.requests.storage ... ストレージサイズ<br>(無指定だとデフォルトで100GB確保されます)

```yaml:db2ucluster-ocs1.yaml
apiVersion: db2u.databases.ibm.com/v1
kind: Db2uCluster
metadata:
  name: db2ucluster-ocs1
spec:
  license:
    accept: true
  account:
    privileged: true
    imagePullSecrets:
      - ibm-registry    
  version: "11.5.5.0-cn2"
  size: 1
  podConfig:
    db2u:
      resource:
        db2u:
          requests:
            cpu: 2
            memory: 4Gi
          limits:
            cpu: 2
            memory: 4Gi
  environment:
    dbType: db2oltp
    database:
      name: sampledb
    instance:
      password: cicdtest
  addOns:    
    rest:     
      enabled: false
    graph:     
      enabled: false
  storage:
    - name: meta
      type: "create"
      spec:
        storageClassName: ocs-storagecluster-cephfs
        accessModes:
          - ReadWriteMany
        resources:
          requests:
            storage: 10Gi
    - name: data
      type: "create"
      spec:
        storageClassName: ocs-storagecluster-ceph-rbd
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 10Gi
```

### Step2. Db2uClusterインスタンス作成
Step1.で作成したyamlを用いて、Db2のデプロイを実行します。(→即時に応答が戻ります)

```
$ oc create -f db2ucluster-ocs1.yaml
db2ucluster.db2u.databases.ibm.com/db2ucluster-ocs1 created
```

Db2uCluster インスタンスが作成されていることを確認します。

```
oc get Db2uCluster db2ucluster-ocs1
```

yaml定義の通り、メタデータ、ユーザデータ用に2つの永続ストレージが作成されていることを確認します。
2つのPVC/PVが作成されていることを確認します。

【PVC】
PVCはネーミングルールとして、「c-＜Db2uClusterインスタンス名＞]が先頭に付与されています。

```
$ oc get pvc
NAME                      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS                  AGE
c-db2ucluster-ocs1-data   Bound    pvc-146c2d44-fbf0-477b-bece-d01e79200d8d   10Gi       RWO            ocs-storagecluster-ceph-rbd   19s
c-db2ucluster-ocs1-meta   Bound    pvc-c348fb5d-aa38-412c-ac0d-e9b18c9deed9   10Gi       RWX            ocs-storagecluster-cephfs     19s

```

【PV】
自動作成されるため、名前は任意文字列となります。CLAIM列にて、対応するPVCの名前がわかるため、どのPVがDb2用途のものか識別可能です。

```
$ oc get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                             STORAGECLASS                  REASON   AGE
pvc-146c2d44-fbf0-477b-bece-d01e79200d8d   10Gi       RWO            Delete           Bound    db2u-ocs1/c-db2ucluster-ocs1-data                                 ocs-storagecluster-ceph-rbd            44s
pvc-c348fb5d-aa38-412c-ac0d-e9b18c9deed9   10Gi       RWX            Delete           Bound    db2u-ocs1/c-db2ucluster-ocs1-meta                                 ocs-storagecluster-cephfs              40s

```


### (Step3. デプロイ完了待ち～デプロイ完了確認)

oc create コマンド自体は即時に応答が戻りますが、実際にデプロイが完了するまではもう少し時間がかかります。(十数分～数十分。環境に依存します)
しばらくの間 oc get all コマンドを実行してもそれらしい出力が一切出てこないため不安になりますが、しばらく待ちます。
以下の状態になっていればデプロイ完了し、Db2インスタンスが利用可能な状態になっています。

 - 「<Db2uClusterインスタンス名>-restore-morph-*」の Pod の状態が「Completed」
 - 「<Db2uClusterインスタンス名>-db2u-0」の Pod の状態が「Running」

```
oc get pods -o wide
NAME                                        READY   STATUS      RESTARTS   AGE   IP             NODE      NOMINATED NODE   READINESS GATES
c-db2ucluster-ocs1-db2u-0                   1/1     Running     0          54m   10.129.3.103   worker2   <none>           <none>
c-db2ucluster-ocs1-etcd-0                   1/1     Running     0          54m   10.128.4.16    worker6   <none>           <none>
c-db2ucluster-ocs1-instdb-ckt77             0/1     Completed   0          60m   10.130.2.6     worker4   <none>           <none>
c-db2ucluster-ocs1-ldap-7dfc5c6968-lv4vw    1/1     Running     0          60m   10.131.2.8     worker5   <none>           <none>
c-db2ucluster-ocs1-restore-morph-kzqg5      0/1     Completed   0          39m   10.128.4.17    worker6   <none>           <none>
c-db2ucluster-ocs1-tools-756dcd89b5-nhp24   1/1     Running     0          60m   10.128.4.15    worker6   <none>           <none>
db2u-operator-manager-5c8d59f5db-ckl5g      1/1     Running     4          82m   10.131.2.6     worker5   <none>           <none>
```

デプロイ完了時点の oc get all コマンド出力：

```
$ oc get all
NAME                                            READY   STATUS      RESTARTS   AGE
pod/c-db2ucluster-ocs1-db2u-0                   1/1     Running     0          54m
pod/c-db2ucluster-ocs1-etcd-0                   1/1     Running     0          55m
pod/c-db2ucluster-ocs1-instdb-ckt77             0/1     Completed   0          60m
pod/c-db2ucluster-ocs1-ldap-7dfc5c6968-lv4vw    1/1     Running     0          60m
pod/c-db2ucluster-ocs1-restore-morph-kzqg5      0/1     Completed   0          39m
pod/c-db2ucluster-ocs1-tools-756dcd89b5-nhp24   1/1     Running     0          60m
pod/db2u-operator-manager-5c8d59f5db-ckl5g      1/1     Running     4          82m

NAME                                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                           AGE
service/c-db2ucluster-ocs1-db2u            ClusterIP   172.30.130.18    <none>        50000/TCP,50001/TCP,25000/TCP,25001/TCP,25002/TCP,25003/TCP,25004/TCP,25005/TCP   54m
service/c-db2ucluster-ocs1-db2u-engn-svc   NodePort    172.30.117.152   <none>        50000:31178/TCP,50001:31288/TCP                                                   54m
service/c-db2ucluster-ocs1-db2u-internal   ClusterIP   None             <none>        50000/TCP,9443/TCP                                                                55m
service/c-db2ucluster-ocs1-etcd            ClusterIP   None             <none>        2379/TCP,2380/TCP                                                                 55m
service/c-db2ucluster-ocs1-ldap            ClusterIP   172.30.161.127   <none>        50389/TCP                                                                         60m
service/c-db2ucluster-ocs1-tools           ClusterIP   172.30.28.191    <none>        53/TCP,53/UDP                                                                     60m

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/c-db2ucluster-ocs1-ldap    1/1     1            1           60m
deployment.apps/c-db2ucluster-ocs1-tools   1/1     1            1           60m
deployment.apps/db2u-operator-manager      1/1     1            1           82m

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/c-db2ucluster-ocs1-ldap-7dfc5c6968    1         1         1       60m
replicaset.apps/c-db2ucluster-ocs1-tools-756dcd89b5   1         1         1       60m
replicaset.apps/db2u-operator-manager-5c8d59f5db      1         1         1       82m

NAME                                       READY   AGE
statefulset.apps/c-db2ucluster-ocs1-db2u   1/1     54m
statefulset.apps/c-db2ucluster-ocs1-etcd   1/1     55m

NAME                                         COMPLETIONS   DURATION   AGE
job.batch/c-db2ucluster-ocs1-instdb          1/1           3m58s      60m
job.batch/c-db2ucluster-ocs1-restore-morph   1/1           25m        39m
$
```

以上でデプロイ完了です。