OCFS2を利用してOCI Block Volumeを共有ストレージ・ボリュームとして利用する

- Oracle Cloud Infrastructure Block Storageを複数のコンピュート・インスタンスにアタッチ
- Oracle Cluster File System（OCFS2）を利用した同時書き込み制御
- Oracle Linux 7.9

# はじめに
Oracle Cloud Infrastructureで利用可能なブロック・ボリュームは、読取り/書込みアクセスに対応する共有可能なボリュームとして、複数のコンピュート・インスタンス（最大8台）に接続して利用することができます。一方で、同時書込み操作の調整する機能備わっていないため、読取り/書込み操作によるデータ破損を防止するには、Oracle Cluster File System（OCFS2）やIBM Spectrum Scale、GlusterFSなどのクラスタウェアを導入することが必要となります。本記事では、OCFS2を利用してブロック・ボリュームを複数のコンピュート・インスタンスから書き込み可能な共有ストレージとして利用する手順を記します。


# Oracle Cloud Infrastructureのリソースの準備
## OCI上のネットワークの構成
### インターネット接続性を持つVCN作成ウィザード
OCIダッシュボードにログインし、OCIダッシュボードメニューから、**ネットワーキング**>**概要**にアクセスし、画面中央の 「インターネット接続性を持つVCN作成」の「VCNウィザードの起動」を選択してください。

下記にウィザード内の入力例を記します。

* 基本情報
    * VCN名 : 任意のVCN名　OCFS_VCN
    * コンパートメント : 任意のコンパートメント名　 /dev
* VCNとサブネットの構成
    * VCN CIDRブロック 172.0.0.0/16
    * パブリック・サブネットCIDRブロック　172.0.0.0/24
    * プライベート・サブネットCIDRブロック　172.0.1.0/24
    * DNS解決： 選択


### セキュリティ・ルールの変更
パブリック・サブネットに配置する2台のLinuxサーバでOCFS2を構成する際に使用するNWポートが利用できるように、パブリック・サブネットにアサインされているセキュリティ・ルールの設定を編集します。OCIダッシュボードメニューから、**ネットワーキング**>**仮想クラウド・ネットワーク**にアクセスし、作成したVCN (本記事内ではMySQLTest) を選択、画面左下のリソースメニューより**セキュリティ・リスト**を選択、セキュリティ・リストの一覧より**Default Security List for *VCN名***を選択、**画面中央のイングレス・ルールの追加**ボタンをクリックし、下記の設定を追記してください。


---
|ステートレス|ソース・タイプ|ソースCIDR|IPプロトコル|ソース・ポート範囲|宛先ポート範囲|
|---|---|---|---|---|---|
|いいえ|CIDR|172.0.0.0/24|TCP|All|7777|

---

## OCFSクラスタ・ノード用途のCompute VMインスタンスの作成

クラスタを構成するLunuxサーバとして、2台のCompute VMインスタンスを構築します。OCIダッシュボードメニューから、**コンピュート**>**コンピュート**>**インスタンス**にアクセスします。**インスタンスの作成**ボタンを押してComputeインスタンスの作成ウィザードを開始します。
1台目のクラスタ・ノード**OCFS_Node1**を作成する際の。ウィザード内入力例を下記に示します。

---
* 名前　: 任意名前　OCFS_Node1
* コンパートメントの選択 : 任意のコンパートメント名　 /dev

* 配置とハードウェアの構成
    * 可用性ドメインの選択　：デフォルト　Fubk:AP-TOKYO-1-AD-1
    * フォルト・ドメインの選択　：デフォルト　 FAULT-DOMAIN-1
    * イメージ：Oracle Linux 7.9
    * シェイプの選択：デフォルト　 VM.Standard.E2.1.Micro
* ネットワーキングの構成
    * 仮想クラウド・ネットワーク: OCFS_VCN
    * サブネット: パブリック・サブネット-OCFS_VCN
    * ネットワーク・セキュリティ・グループを使用してトラフィックを制御: いいえ
    * パブリックIPv4アドレスの割当て: はい
* SSHキーの追加：公開キー・ファイルの選択
* ブート・ボリュームの構成　：デフォルト設定

---


同様に2台目のクラスタ・ノードとして**OCFS_Node2**を作成します。

## ブロック・ボリュームの作成とマウント

クラスタで共有するブロック・ボリュームを作成して、各ノードからマウントします。OCIダッシュボードメニューから、**ストレージ**>**ブロック・ストレージ**>**ブロック・ボリューム**にアクセスします。**ブロック・ボリュームの作成**ボタンを押してブロック・ボリュームの作成ウィザードを開始します。
ブロック・ボリューム**OCFS_Volume**を作成する際の。ウィザード内入力例を下記に示します。

---
* 名前　: 任意名前　OCFS_Volume
* コンパートメントの選択 : 任意のコンパートメント名　 /dev
* 可用性ドメインの選択　：デフォルト　Fubk:AP-TOKYO-1-AD-1
* ボリューム・サイズとパフォーマンス　：カスタム
    * ボリューム・サイズ(GB)　：50
    * ターゲットのボリューム・パフォーマンス(VPU)　：10　バランス
* バックアップ・ポリシー : 任意  選択しない
* クロス・リージョン・レプリケーション：任意  オフ
* 暗号化　：デフォルト設定　Oracle管理キーを使用した暗号化

---

下記ような作成したブロック・ボリュームの詳細画面左下のリソースメニューより**アタッチされたインスタンス**ボタンを選択、**アタッチされたインスタンス**画面に遷移します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/831381/293f2b04-4768-1769-2d33-3d9e1cb0fd37.png)

**インスタンスにアタッチ**ボタンを選択、下記のように入力し作成済のLinuxサーバ**OCFS_Node1**にアタッチします。

---
* アタッチメント・タイプ　:準仮想化
* アクセス・タイプ : 読取り/書込み - 共有可能　（表示される注意書きにチェック）
* 可用性ドメインの選択　：デフォルト　Fubk:AP-TOKYO-1-AD-1
* インスタンス
    * インスタンスの選択 :Devコンパートメントの**OCFS_Node1**を選択
    * デバイス・パス　： /dev/oracleoci/oraclevdb
    
---


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/831381/24047082-7f95-4796-b0c3-e185a83ec6a8.png)

同様の操作を**OCFS_Node2**に対しても行い、**OCFS_Volume**を共有ストレージとしてアタッチします。

---
* アタッチメント・タイプ　:準仮想化
* アクセス・タイプ : 読取り/書込み - 共有可能　（表示される注意書きにチェック）
* 可用性ドメインの選択　：デフォルト　Fubk:AP-TOKYO-1-AD-1
* インスタンス
    * インスタンスの選択 :Devコンパートメントの**OCFS_Node2**を選択
    * デバイス・パス　： /dev/oracleoci/oraclevdb
    
---

# OCFSクラスタの構成
## 事前準備とクラスタ構成ファイルの作成
この項の手順は**OCFS_Node1**および**OCFS_Node2**の両方のComputeサーバにSSH接続して同様に行います。
まず、それぞれのComputeサーバのHOSTNAMEとIPアドレスを調べメモしておきます。

---
|インスタンス名|HOSTNAME|IPアドレス|
|---|---|---|
|OCFS_Node1|ocfs-node1|172.0.0.9|
|OCFS_Node2|ocfs-node2|172.0.0.85|

---

次に、それぞれのComputeサーバで利用するポートを解放します。

```shell-session:
$ sudo firewall-cmd --zone=public --permanent --add-port=7777/tcp
$ sudo firewall-cmd --complete-reload
```

利用するOCFS2のパッケージをインストールします。

```shell-session:
$ sudo yum install ocfs2-tools-devel ocfs2-tools -y
```

クラスタ構成ファイル (cluster.conf) を作成します。直接テキストエディタで作成しても良いですが、本記事ではo2cbコマンドを利用して生成します。

```shell-session:
$ sudo o2cb add-cluster ociocfs2
$ sudo o2cb add-node ociocfs2 ocfs-node1 --ip 172.0.0.9
$ sudo o2cb add-node ociocfs2  ocfs-node2 --ip 172.0.0.85
```

これらのコマンドで生成される構成ファイルは下記のようになります。

```shell-session:
$ sudo cat /etc/ocfs2/cluster.conf
cluster:
	heartbeat_mode = local
	node_count = 2
	name = ociocfs2

node:
	number = 0
	cluster = ociocfs2
	ip_port = 7777
	ip_address = 172.0.0.9
	name = ocfs-node1

node:
	number = 1
	cluster = ociocfs2
	ip_port = 7777
	ip_address = 172.0.0.85
	name = ocfs-node2
```

## OCFSクラスタの構成

この項の手順も**OCFS_Node1**および**OCFS_Node2**の両方のComputeサーバにSSH接続して同様に行います。
前の手順で作成したクラスタ構成ファイルを利用して、下記コマンドでOCFSクラスタを構成します。
（Cluster to start on boot (Enter "none" to clear) [ocfs2]: の箇所でcluster.confに記載したcluster名を入力することがポイント）

```shell-session:
$ sudo /sbin/o2cb.init configure
Configuring the O2CB driver.

This will configure the on-boot properties of the O2CB driver.
The following questions will determine whether the driver is loaded on
boot.  The current values will be shown in brackets ('[]').  Hitting
<ENTER> without typing an answer will keep that current value.  Ctrl-C
will abort.

Load O2CB driver on boot (y/n) [n]: y
Cluster stack backing O2CB [o2cb]: 
Cluster to start on boot (Enter "none" to clear) [ocfs2]: ociocfs2
Specify heartbeat dead threshold (>=7) [31]: 
Specify network idle timeout in ms (>=5000) [30000]: 
Specify network keepalive delay in ms (>=1000) [2000]: 
Specify network reconnect delay in ms (>=2000) [2000]: 
Writing O2CB configuration: OK
checking debugfs...
Loading stack plugin "o2cb": OK
Loading filesystem "ocfs2_dlmfs": OK
Creating directory '/dlm': OK
Mounting ocfs2_dlmfs filesystem at /dlm: OK
Setting cluster stack "o2cb": OK
Registering O2CB cluster "ociocfs2": OK
Setting O2CB cluster timeouts : OK
[opc@ocfs-node2 ~]$ sudo /sbin/o2cb.init status
Driver for "configfs": Loaded
Filesystem "configfs": Mounted
Stack glue driver: Loaded
Stack plugin "o2cb": Loaded
Driver for "ocfs2_dlmfs": Loaded
Filesystem "ocfs2_dlmfs": Mounted
Checking O2CB cluster "ociocfs2": Online
  Heartbeat dead threshold: 31
  Network idle timeout: 30000
  Network keepalive delay: 2000
  Network reconnect delay: 2000
  Heartbeat mode: Local
Checking O2CB heartbeat: Not active
Debug file system at /sys/kernel/debug: mounted
```

**/sbin/o2cb.init status**コマンドを実行し、構成したクラスタのステータスを確認します。

```shell-session:
$ sudo /sbin/o2cb.init status
Driver for "configfs": Loaded
Filesystem "configfs": Mounted
Stack glue driver: Loaded
Stack plugin "o2cb": Loaded
Driver for "ocfs2_dlmfs": Loaded
Filesystem "ocfs2_dlmfs": Mounted
Checking O2CB cluster "ociocfs2": Online
  Heartbeat dead threshold: 31
  Network idle timeout: 30000
  Network keepalive delay: 2000
  Network reconnect delay: 2000
  Heartbeat mode: Local
Checking O2CB heartbeat: Not active
Debug file system at /sys/kernel/debug: mounted
```

この時点ではボリュームが設定されていないので、O2CB heartbeatはNot Activeとなっています。
ボリュームの設定の前に、再起動の際にOCFSボリュームが自動でマウントできるようにo2cbとocfs2をサービス化します。

```shell-session:
$ sudo systemctl enable o2cb
$ sudo systemctl enable ocfs2
```
カーネルパニック発生時に自動的に再起動するように下記の値を設定します。

```shell-session:
$ sudo sysctl kernel.panic=30
$ sudo sysctl kernel.panic_on_oops=1
```

さらに設定値の永続化ために/etc/sysctl.confに下記を追記します。

```
# Define panic and panic_on_oops for cluster operation
kernel.panic=30
kernel.panic_on_oops=1
```

# 共有ストレージ・ボリュームの作成とマウント
## OCFS2ボリュームの作成
どちらか一方のComputeサーバからmkfs.ocfs2コマンドを実行してOCFS2ボリュームを作成します。

```shell-session:
$ sudo mkfs.ocfs2 -L "ocfs2" /dev/oracleoci/oraclevdb
mkfs.ocfs2 1.8.6
Cluster stack: classic o2cb
Label: ocfs2
Features: sparse extended-slotmap backup-super unwritten inline-data strict-journal-super xattr indexed-dirs refcount discontig-bg
Block size: 4096 (12 bits)
Cluster size: 4096 (12 bits)
Volume size: 53687091200 (13107200 clusters) (13107200 blocks)
Cluster groups: 407 (tail covers 11264 clusters, rest cover 32256 clusters)
Extent allocator size: 8388608 (2 groups)
Journal size: 268435456
Node slots: 8
Creating bitmaps: done
Initializing superblock: done
Writing system files: done
Writing superblock: done
Writing backup superblock: 3 block(s)
Formatting Journals: done
Growing extent allocator: done
Formatting slot map: done
Formatting quota files: done
Writing lost+found: done
mkfs.ocfs2 successful
```

## OCFS2ボリュームのマウント
両方のComputeサーバにおいてマウントポイントを作成し、作成したOCFS2ボリュームをマウントします。

```shell-session:
$ sudo mkdir /ocfs2
$ sudo mount /dev/oracleoci/oraclevdb /ocfs2
```

アンマウントのコマンドは下記になります。

```shell-session:
$ sudo mkdir /ocfs2
$ sudo mount /dev/oracleoci/oraclevdb /ocfs2
```

OS起動時に自動でmountさせるために、/etc/fstabに下記を追記します。
（ネットワーク・インターフェースを利用できるように**_netdev**を記述することがポイント）

```
/dev/oracleoci/oraclevdb /ocfs2 ocfs2    _netdev,defaults   0 0 
```

fstab設定後、下記コマンドでマウントすることができます。

```shell-session:
$ mount -a
```

再度、**/sbin/o2cb.init status**コマンドを実行し、構成したクラスタのステータスを確認します。

```shell-session:
$ sudo /sbin/o2cb.init status
Driver for "configfs": Loaded
Filesystem "configfs": Mounted
Stack glue driver: Loaded
Stack plugin "o2cb": Loaded
Driver for "ocfs2_dlmfs": Loaded
Filesystem "ocfs2_dlmfs": Mounted
Checking O2CB cluster "ociocfs2": Online
  Heartbeat dead threshold: 31
  Network idle timeout: 30000
  Network keepalive delay: 2000
  Network reconnect delay: 2000
  Heartbeat mode: Local
Checking O2CB heartbeat: Active
Debug file system at /sys/kernel/debug: mounted
```

O2CB heartbeatがActiveとなっていることを確認できました。

最後に**OCFS_Node1**でファイルを作成しOCFSに保存、**OCFS_Node2**から参照します。

```shell-session:
[opc@ocfs-node1 ~]$ sudo vi /ocfs2/test.txt
```

```shell-session:
[opc@ocfs-node2 ~]$ sudo cat /ocfs2/test.txt
TEST
```
**OCFS_Node2**でファイルを編集し、**OCFS_Node1**から確認します。

```shell-session:
[opc@ocfs-node1 ~]$ sudo cat /ocfs2/test.txt
TEST3
```

どちらのComputeサーバからOCFSボリュームにアクセスしてファイル編集できることが確認できました。

# まとめ
本記事では、Oracle Cluster File System (OCFS2) を利用してOCI ブロック・ボリュームを共有ストレージ・ボリュームとして利用できることを確認しました。
OCIで大規模なフォイル共有が必要なシステムでは、マネージドNFSサービスであるFile Storrage Serviceの利用が第一候補となりますが、小規模なシステムで手軽に共有ストレージ・ボリュームを利用したい場合や、より低価格で共有ストレージを利用したい場合にはOCFSを導入して読み書き可能なストレージ・ボリュームとしてブロック・ボリュームを利用することもできそうです。


# 関連情報
[Using the Multiple-Instance Attach Block Volume Feature to Create a Shared File System on Oracle Cloud Infrastructure](https://blogs.oracle.com/cloud-infrastructure/post/using-the-multiple-instance-attach-block-volume-feature-to-create-a-shared-file-system-on-oracle-cloud-infrastructure)
[A Simple Guide to Oracle Cluster File System (OCFS2) using iSCSI on Oracle Cloud Infrastructure](https://blogs.oracle.com/cloud-infrastructure/post/a-simple-guide-to-oracle-cluster-file-system-ocfs2-using-iscsi-on-oracle-cloud-infrastructure)
[Oracle Linux 7ファイル・システムの管理　第7章 Oracle Cluster File Systemバージョン2の管理](hhttps://docs.oracle.com/cd/E77565_01/fsadmin/ol7-ocfs2.html)