[Oracle Cloud] IaaS(Compute & Block)に、GIを強引にインストールしてみる

#はじめに
IaaSにGrid Infrastructure ( 19c ) をインストールしてみました。早くネイティブにクラウド対応するようになってほしい。。

**※本記事に記載している内容は、サポートされる構成ではありません。本番用途として利用しないでください！IaaSの制約やGIの動作を理解するためのハックとして参照ください**

IaaSにGIをインストールすためには、以下のIaaS固有の制約を回避する必要があります。

1. **マルチキャスト通信がサポートされない** ( マルチキャストが通信相手に届かない )
    - [Frequently Asked Questions
](https://www.oracle.com/jp/cloud/networking/virtual-cloud-network-faq.html)
    - [Oracle Grid Infrastructureが使用するネットワークのマルチキャスト要件](https://docs.oracle.com/cd/F19136_01/cwlin/multicast-requirements-for-networks-used-by-oracle-grid-infrastructure.html#GUID-09DA3502-5880-4E72-88C0-CBE8E4893DF7)

2. **HAIP**が使用するネットワーク ( 169.254.0.0/16のAPIPAのアドレス帯 ) がクラウドの内部ネットワークアドレスと被る

3. OS/クラスタウェアレベルでVIPをF/Oしても、**セカンダリIPなどのクラウドリソースと連携しないと、他サーバから通信できない**

①の制約については、OSレイヤでVXLANを利用してCompute間でオーバレイネットワークを作って回避しました。


②の制約については、GIインストール時に一時的にOSのルーティングテーブルを変更して、インストール後にHAIPを無効にすることで回避しました。

③の制約については、VIPの起動・停止と連動して ( oci cliを利用した ) APIコールを実行するスクリプトをGIに登録することで回避しました。

# クラウド・リソースの構成
## サブネット
- 2つのサブネット 
1. Public用 (10.10.2.0/24)
2. インターコネクト用 (10.10.100.0/24) 
    - VXLANでインターコネクトネットワーク上に192.168.10.0/24ネットワークを作成

## Compute

- VM.Starndar.E2.2を2台。
    - OSイメージはOEL7.7 (UEKカーネル使用)
    - 3つのセカンダリIP
        1.  NODE1vip用 
        2.  NODE2vip用
        3.  scan用

## Block Volume
- Block Volume ×3
    1. NODE1の/u01ファイルシステム用 (50GB)
    2. NODE2の/u01ファイルシステム用 (50GB)
    3. 共有ディスク (50GB)

## 全体像
絵でかくとこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456818/5d8860e5-5281-4ac9-c172-cd785eee5fc5.png)

# ざっくり手順
細かく書くと膨大な量になるので、オンプレ環境でGIをインストールしたことがあることを前提として、ポイントだけ記載します。

## VCNの構成
NODE1とNODE2間の通信をすべて許可するようにセキュリティ・リストまたはNSGを構成します

## Computeインスタンスの作成
特に注意点はありません。作成後、インターコネクト用のVNICを追加します。

## OS設定
[Grid Infrastructureインストレーションおよびアップグレード・ガイドfor Linux](https://docs.oracle.com/cd/F19136_01/cwlin/index.html)などを参照して、インストール条件を満たすように構成します。

- 簡便化のため、SELinux、firewalldは無効化しました。
- インストーラを起動するため、[Windowsクライアントを使って、クラウド上のLinuxサーバでGUIアプリを実行したい（3）](https://qiita.com/yamada-hakase/items/e1946b8a598f4cc0bcfa)を参考にして必要なrpmやsshd_configの設定値変更をします。
- VXLANの設定をします。ブート時にセカンダリVNICのIP設定をしてVXLAN設定するよう、(systemdに登録するのはめんどくさかったので)/etc/rc.d/rc.localに追記しました。※OEL7.7では/etc/rc.d/rc.localに明示的に実行権限を与えてあげないとブート時に実行されませんでした。

　参考にした資料： [VXLAN入門！CentOS 7を使ってVXLANを設定する方法](https://tech-mmmm.blogspot.com/2017/10/vxlancentos-7vxlan.html)

```
◆ NODE1側
# vi /etc/rc.d/rc.local
… (最終行に追記)
NODE1_IP=10.10.100.16 # NODE1のインターコネクトIP
NODE2_IP=10.10.100.17 # NODE2のインターコネクトIP
VXLAN_PORT=4789
INTERFACE_NAME=vxlan0
VXLAN_IP1=192.168.10.1/24 # VXLANのNODE1側IP
VXLAN_IP2=192.168.10.2/24 # VXLANのNODE2側IP
DEVICE_NAME=ens5

if /usr/libexec/secondary_vnic_all_configure.sh -c; then
    if ip link add ${INTERFACE_NAME} type vxlan id 100 remote ${NODE2_IP} dstport ${VXLAN_PORT} dev ${DEVICE_NAME}; then
        ip link set up ${INTERFACE_NAME}
        ip address add ${VXLAN_IP1} dev ${INTERFACE_NAME}
    fi
fi

◆NODE2側
IPの変数をNODE2用に変更したものを追記します
…

///1号機と同じ変数を設定

if /usr/libexec/secondary_vnic_all_configure.sh -c; then
    if ip link add ${INTERFACE_NAME} type vxlan id 100 remote ${NODE1_IP} dstport ${VXLAN_PORT} dev ${DEVICE_NAME}; then
        ip link set up ${INTERFACE_NAME}
        ip address add ${VXLAN_IP2} dev ${INTERFACE_NAME}
    fi
fi
```

/etc/hostsにVXLANのIPを追記します。(両ノード)

```
# vi /etc/hosts
192.168.10.1 ora01-priv.db.xxxxx.oraclevcn.com ora01-priv
192.168.10.2 ora02-priv.db.xxxxx.oraclevcn.com ora02-priv
```

VXLAN設定後、しばらくたつと通信できなくなる事象が発生しました。互いにpingを打つと回復するようでしたので、( ダサいのですが ) 回避のためcronで毎分ごとに対向のVXLANのIPあてにpingするという処理をいれました。

```
# crontab -e
◆ NODE1側
* * * * * ping -c 5 ora02-priv > /dev/null 2>&1
◆ NODE2側
* * * * * ping -c 5 ora01-priv> /dev/null 2>&1
```

設定後、リブートしてVXLANが設定されていることを確認します。

```
# ip -f inet -o addr
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
2: ens3    inet 10.10.2.34/24 brd 10.10.2.255 scope global dynamic ens3\       valid_lft 86339sec preferred_lft 86339sec
3: ens5    inet 10.10.100.16/24 scope global ens5\       valid_lft forever preferred_lft forever
★4: vxlan0    inet 192.168.10.1/24 scope global vxlan0\       valid_lft forever preferred_lft forever
```

## Block Volumeの設定
GIのSWインストールディレクトリとして、/u01ファイルシステム用のブロックボリュームを各ノードごとに作成してアタッチします。( ブートボリュームのサイズを大きくしても問題ないと思います。)
**※アタッチの方法は、準仮想化を選択します。iSCSIを選択すると、ブロックボリュームへのアクセスに169.254.0.0/16ネットワークを利用するため、HAIPとアドレス帯がかぶってしまうためです※**

[OCI Computeでブロックボリュームをマウントする（LVM不使用編）](https://qiita.com/yamada-hakase/items/2e051720950470728230)を参考にアタッチ後、ファイルシステムを作成して自動マウント設定をします。

共有ディスク用に、ブロックボリュームを作成します。**アタッチメントタイプに準仮想化、アクセスタイプに読取り/書込み - 共有可能**を指定してノード1とノード2両方にアタッチします。1号機と2号機で同じデバイス名を指定します。

共有ディスクにはパーティションは作成しませんでした。ただし、ASMディスクとして利用するため。gridユーザがボリュームにアクセスできる必要があります。これもダサいですが、/etc/rc.d/rc.localでパーミッション変更するようにしました。

```
* /dev/sd*のデバイスは、リブート時にデバイス名が変わってしまう可能性があるため/dev/oracleoci/oraclevd*デバイス(実体はシンボリックリンク)を指定する

# vi /etc/rc.d/rc.local
… (最終行に追記)
chown grid.asmadmin /dev/oracleoci/oraclevdc
```


## セカンダリipを付与
VIPとして利用するIPを、セカンダリIPとして付与します。セカンダリIPの設定は、
[VIPなどで使用するOCI ComputeのセカンダリIPを考える](https://qiita.com/yamada-hakase/items/12d4de70d239ae304b65)を参考にします。
**ここで設定するIPはクラスタウェアが制御するIPのため、クラスタ・リソースとして割り当てるだけでOSレイヤでの設定は行いません。**

以下のIPをセカンダリIPとして割り当てます
1. NODE1インスタンスのプライマリVNICに、NODE1用VIP
2. NODE1インスタンスのプライマリVNICに、SCAN用VIP
3. NODE2インスタンスのプライマリVNICに、NODE2用VIP

/etc/hostsに、設定したVIPを登録して名前解決できるようにします。(両ノード)
**セカンダリIP割り当て時にホスト名指定することでDNSによる名前解決ができますが、後続の手順でVIPの停止時にセカンダリIPをUNASSIGNするスクリプトを登録します。UNASSIGNするとDNSによる名前解決もできなくなってしまうため、hostsに登録します**

```
# vi /etc/hosts
…最終行に追記
10.10.2.51 ora01-vip.db.xxxxx.oraclevcn.com ora01-vip
10.10.2.52 ora02-vip.db.xxxxx.oraclevcn.com ora02-vip
10.10.2.53 ora-scan.db.xxxxx.oraclevcn.com ora-scan
```

## HAIP対策
クラウドの内部ネットワークと通信するため、169.254.0.0/16のルーティングが設定されています。

```
# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.10.2.1       0.0.0.0         UG        0 0          0 ens3
10.10.2.0       0.0.0.0         255.255.255.0   U         0 0          0 ens3
10.10.100.0     0.0.0.0         255.255.255.0   U         0 0          0 ens5
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 ens3 ★
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 ens3 ★
192.168.10.0    0.0.0.0         255.255.255.0   U         0 0          0 vxlan0
```

このルーティングがHAIPと干渉するため、一時的に削除します。(両ノード)

```
# ip route add 169.254.169.254/32 dev ens3
↑DNSサーバやNTPサーバの宛先になってたりする169.254.169.254/32のスタティックルートを設定します。
# ip route delete 169.254.0.0/16 dev ens3
# ip route delete 169.254.0.0/16 dev ens3

# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.10.2.1       0.0.0.0         UG        0 0          0 ens3
10.10.2.0       0.0.0.0         255.255.255.0   U         0 0          0 ens3
10.10.100.0     0.0.0.0         255.255.255.0   U         0 0          0 ens5
169.254.169.254 0.0.0.0         255.255.255.255 UH        0 0          0 ens3
192.168.10.0    0.0.0.0         255.255.255.0   U         0 0          0 vxlan0
↑169.254.0.0/16のルーティングがなくなっていることを確認します
```

## GIのインストール
- gridユーザでインストールファイルを展開し、[展開ディレクトリ]/cv/rpm/cvuqdisk-1.0.10-1.rpmをインストール (両ノード)
- ノード間でgridユーザの透過設定を行います。(パスワードなしでお互いにログインできる状態にする)
- ローカル端末でXサーバを起動して、X Forwardingなどを利用してGIのインストーラを起動します

1. Configure Oracle Grid Infrastructure for a New Clusterを選択
2. Configure an Oracle Standalone Clusterを選択
3. Create Local SCANを選択し、セカンダリIP設定時にhostsに追記したscan用のホスト名を入力
4. Node2のホスト名とVIPホスト名を追加。SSH ConnectivityはTestのみ行う
5. ens5をDo not Useに変更し、vxlan0をASM * Privateに変更します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456818/d856a246-1311-06c8-b52a-ed226bd52f16.png)

6. Use Oracle Flex ASM for storageを選択します
7. Configure Grid Infrastructure Management RepositoryはNoのままとしました
8. RedandancyはExternalを指定。Change Discovery Pathで、/dev/oracleoci/oraclevd*を指定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456818/8389bb39-9735-66df-9495-a226dc4f9abf.png)

9. sysユーザパスワードを設定します
10. Do not use Intelligent Platform Management Interface (IPMI)を選択します
11. EMCCの登録はせず、次に進みます
12. グループ設定はデフォルトのままとします
13. GIのベースディレクトリは、なじみのある/u01/app/gridに変更しました。
14. oraInventoryはデフォルト位置のままにします
15. root.shは手動実行とします
16. 以下の警告が出力されましたがすべて無視します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456818/e4978bbb-8f34-38b0-6f8b-41d57c7d0ed2.png)
・swapサイズが小さい、SCANが1つしかない、RPMパッケージの検査ができなかった、zeroconfが設定されていない

17. インストールを開始します
18. orainstRoot.sh とroot.shを1号機から実行します

```
成功すると、こんな感じに出力されます
# /u01/app/19.0.0.0/grid/root.sh
Performing root user operation.

…略
  /u01/app/grid/crsdata/rac01/crsconfig/rootcrs_rac01_2020-03-26_10-10-21PM.log
2020/03/26 22:10:33 CLSRSC-594: Executing installation step 1 of 19: 'SetupTFA'.
2020/03/26 22:10:33 CLSRSC-594: Executing installation step 2 of 19: 'ValidateEnv'.
2020/03/26 22:10:33 CLSRSC-363: User ignored prerequisites during installation
2020/03/26 22:10:33 CLSRSC-594: Executing installation step 3 of 19: 'CheckFirstNode'.
2020/03/26 22:10:36 CLSRSC-594: Executing installation step 4 of 19: 'GenSiteGUIDs'.
2020/03/26 22:10:38 CLSRSC-594: Executing installation step 5 of 19: 'SetupOSD'.
2020/03/26 22:10:38 CLSRSC-594: Executing installation step 6 of 19: 'CheckCRSConfig'.
2020/03/26 22:10:38 CLSRSC-594: Executing installation step 7 of 19: 'SetupLocalGPNP'.
2020/03/26 22:11:02 CLSRSC-594: Executing installation step 8 of 19: 'CreateRootCert'.
2020/03/26 22:11:09 CLSRSC-594: Executing installation step 9 of 19: 'ConfigOLR'.
2020/03/26 22:11:10 CLSRSC-4002: Successfully installed Oracle Trace File Analyzer (TFA) Collector.
2020/03/26 22:11:19 CLSRSC-594: Executing installation step 10 of 19: 'ConfigCHMOS'.
2020/03/26 22:11:19 CLSRSC-594: Executing installation step 11 of 19: 'CreateOHASD'.
2020/03/26 22:11:24 CLSRSC-594: Executing installation step 12 of 19: 'ConfigOHASD'.
2020/03/26 22:11:25 CLSRSC-330: Adding Clusterware entries to file 'oracle-ohasd.service'
2020/03/26 22:11:47 CLSRSC-594: Executing installation step 13 of 19: 'InstallAFD'.
2020/03/26 22:11:53 CLSRSC-594: Executing installation step 14 of 19: 'InstallACFS'.
2020/03/26 22:11:58 CLSRSC-594: Executing installation step 15 of 19: 'InstallKA'.
2020/03/26 22:12:04 CLSRSC-594: Executing installation step 16 of 19: 'InitConfig'.

ASM has been created and started successfully.

[DBT-30001] Disk groups created successfully. Check /u01/app/grid/cfgtoollogs/asmca/asmca-200326PM101235.log for details.

2020/03/26 22:13:29 CLSRSC-482: Running command: '/u01/app/19.0.0.0/grid/bin/ocrconfig -upgrade grid oinstall'
CRS-4256: Updating the profile
Successful addition of voting disk c1edc2986a424f9dbf3ed22f0ab5e117.
Successfully replaced voting disk group with +DATA.
CRS-4256: Updating the profile
CRS-4266: Voting file(s) successfully replaced
##  STATE    File Universal Id                File Name Disk group
--  -----    -----------------                --------- ---------
 1. ONLINE   c1edc2986a424f9dbf3ed22f0ab5e117 (/dev/oracleoci/oraclevdc) [DATA]
Located 1 voting disk(s).
2020/03/26 22:14:47 CLSRSC-594: Executing installation step 17 of 19: 'StartCluster'.
2020/03/26 22:15:46 CLSRSC-343: Successfully started Oracle Clusterware stack
2020/03/26 22:15:46 CLSRSC-594: Executing installation step 18 of 19: 'ConfigNode'.
2020/03/26 22:17:07 CLSRSC-594: Executing installation step 19 of 19: 'PostConfig'.
2020/03/26 22:17:34 CLSRSC-325: Configure Oracle Grid Infrastructure for a Cluster ... succeeded
```

19. orainstRoot.sh とroot.shを2号機から実行します

```
成功すると、こんな感じに出力されます
# /u01/app/19.0.0.0/grid/root.sh
Performing root user operation.
…略
Using configuration parameter file: /u01/app/19.0.0.0/grid/crs/install/crsconfig_params
The log of current session can be found at:
  /u01/app/grid/crsdata/rac02/crsconfig/rootcrs_rac02_2020-03-26_10-19-54PM.log
2020/03/26 22:20:00 CLSRSC-594: Executing installation step 1 of 19: 'SetupTFA'.
2020/03/26 22:20:00 CLSRSC-594: Executing installation step 2 of 19: 'ValidateEnv'.
2020/03/26 22:20:01 CLSRSC-363: User ignored prerequisites during installation
2020/03/26 22:20:01 CLSRSC-594: Executing installation step 3 of 19: 'CheckFirstNode'.
2020/03/26 22:20:02 CLSRSC-594: Executing installation step 4 of 19: 'GenSiteGUIDs'.
2020/03/26 22:20:02 CLSRSC-594: Executing installation step 5 of 19: 'SetupOSD'.
2020/03/26 22:20:02 CLSRSC-594: Executing installation step 6 of 19: 'CheckCRSConfig'.
2020/03/26 22:20:03 CLSRSC-594: Executing installation step 7 of 19: 'SetupLocalGPNP'.
2020/03/26 22:20:04 CLSRSC-594: Executing installation step 8 of 19: 'CreateRootCert'.
2020/03/26 22:20:05 CLSRSC-594: Executing installation step 9 of 19: 'ConfigOLR'.
2020/03/26 22:20:17 CLSRSC-594: Executing installation step 10 of 19: 'ConfigCHMOS'.
2020/03/26 22:20:17 CLSRSC-594: Executing installation step 11 of 19: 'CreateOHASD'.
2020/03/26 22:20:19 CLSRSC-594: Executing installation step 12 of 19: 'ConfigOHASD'.
2020/03/26 22:20:19 CLSRSC-330: Adding Clusterware entries to file 'oracle-ohasd.service'
2020/03/26 22:20:37 CLSRSC-4002: Successfully installed Oracle Trace File Analyzer (TFA) Collector.
2020/03/26 22:20:42 CLSRSC-594: Executing installation step 13 of 19: 'InstallAFD'.
2020/03/26 22:20:43 CLSRSC-594: Executing installation step 14 of 19: 'InstallACFS'.
2020/03/26 22:20:45 CLSRSC-594: Executing installation step 15 of 19: 'InstallKA'.
2020/03/26 22:20:46 CLSRSC-594: Executing installation step 16 of 19: 'InitConfig'.
2020/03/26 22:20:54 CLSRSC-594: Executing installation step 17 of 19: 'StartCluster'.
2020/03/26 22:21:37 CLSRSC-343: Successfully started Oracle Clusterware stack
2020/03/26 22:21:37 CLSRSC-594: Executing installation step 18 of 19: 'ConfigNode'.
2020/03/26 22:21:51 CLSRSC-594: Executing installation step 19 of 19: 'PostConfig'.
2020/03/26 22:22:05 CLSRSC-325: Configure Oracle Grid Infrastructure for a Cluster ... succeeded
```

20. インストーラに戻る
21. 成功!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456818/4795cda1-7729-7603-3e21-03b83300c7b7.png)

## HAIP無効化
クラスタの内部ネットワークとバッティングするHAIPを無効化します。
※-unsupported付きのコマンドは、本来SRに指示された場合のみサポートされます

◆ NODE1から、ASM の cluster_interconnects パラメータを設定します

```
# su - grid
$ vi .bashrc
export ORACLE_HOME=/u01/app/19.0.0.0/grid
export PATH=${ORACLE_HOME}/bin:${PATH}:${ORACLE_HOME}/OPatch
export ORACLE_SID=+ASM1 # 2号機は+ASM2
export NLS_LANG=American_America.AL32UTF8

$ . .bashrc
$ sqlplus / as sysasm
SQL> alter system set cluster_interconnects='192.168.10.1' scope=spfile sid='+ASM1';
SQL> alter system set cluster_interconnects='192.168.10.2' scope=spfile sid='+ASM2';

※.bashrcはNODE2でも修正しておきます
```

◆ HAIPの無効化
- NODE1から実行

```
# . /home/grid/.bashrc
# crsctl modify res ora.cluster_interconnect.haip -attr "ENABLED=0" -init -unsupported
# crsctl modify res ora.cluster_interconnect.haip -attr "AUTO_START=never" -init -unsupported
# crsctl stat res ora.asm -p -init |grep haip
# crsctl modify resource ora.asm -attr "START_DEPENDENCIES='hard(ora.cssd,ora.ctssd)pullup(ora.cssd,ora.ctssd)weak(ora.drivers.acfs)'" -init -unsupported
# crsctl modify resource ora.asm -attr "STOP_DEPENDENCIES=hard(intermediate:ora.cssd)" -init -unsupported
# crsctl stat res ora.asm -p -init |grep haip
```

NODE2でもNODE1と同じコマンドを実行します

◆ GIの再起動
-NODE1からCRS停止

```
# crsctl stop crs
```

-NODE2からCRS停止

```
# crsctl stop crs
```

-NODE1からCRS起動

```
# crsctl start crs -wait

# crsctl stat  res ora.cluster_interconnect.haip -t -init
--------------------------------------------------------------------------------
Name           Target  State        Server                   State details       
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
ora.cluster_interconnect.haip
      1        OFFLINE OFFLINE                               STABLE
--------------------------------------------------------------------------------
↑OFFLINE/OFFLINEであること

# ip -f inet -o addr
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
2: ens3    inet 10.10.2.32/24 brd 10.10.2.255 scope global dynamic ens3\       valid_lft 82432sec preferred_lft 82432sec
2: ens3    inet 10.10.2.53/24 brd 10.10.2.255 scope global secondary ens3:1\       valid_lft forever preferred_lft forever
2: ens3    inet 10.10.2.51/24 brd 10.10.2.255 scope global secondary ens3:2\       valid_lft forever preferred_lft forever
2: ens3    inet 10.10.2.52/24 brd 10.10.2.255 scope global secondary ens3:3\       valid_lft forever preferred_lft forever
3: ens5    inet 10.10.100.16/24 scope global ens5\       valid_lft forever preferred_lft forever
4: vxlan0    inet 192.168.10.1/24 scope global vxlan0\       valid_lft forever preferred_lft forever
↑ 169.254.x.xのHAIPが存在しないこと

```

2号機でも同様に起動して、同じように確認

◆ 事前に削除したルーティングをもとに戻す (両ノード)

```
# ip route add 169.254.0.0/16 dev ens3
# ip route delete 169.254.169.254 dev ens3

# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.10.2.1       0.0.0.0         UG        0 0          0 ens3
10.10.2.0       0.0.0.0         255.255.255.0   U         0 0          0 ens3
10.10.100.0     0.0.0.0         255.255.255.0   U         0 0          0 ens5
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 ens3 ★
192.168.10.0    0.0.0.0         255.255.255.0   U         0 0          0 vxlan0

```

## VIP F/O時に、クラスタリソースもアップデートするためのスクリプトを登録する
### oci cliのインストール
1. python3パッケージのインストール (両ノード)

```
# yum install -y python3
```

2. oci cliのインストール
ここでは、rootユーザにインストールしました。

```
# bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"
…
ERROR: oci 2.12.1 has requirement configparser==4.0.2, but you'll have configparser 5.0.0 which is incompatible.
→ 何か変なエラーが出たが無視してる。

```
### 動的グループの設定
インスタンスプリンシパルの設定をするので、以下のようにNODE1とNODE2が含まれるように動的グループを作成します

```
ANY {instance.id = 'ocid1.instance.oc1.xxxxxx', instance.id = 'ocid1.instance.oc1.xxxxxxxxxx'}
```
※instance.idは、コンピュートインスタンスのOCID

### ポリシーの作成
作成した動的グループに、以下の権限を付与します
allow dynamic-group <動的グループ名> to manage private-ip in compartment <コンパートメント名>
allow dynamic-group <動的グループ名> to use virtual-network-family in compartment <コンパートメント名>
allow dynamic-group <動的グループ名> to use instance-family in compartment <コンパートメント名>


### スクリプトを作成します。
何気に一番はまりました。start後に実行されるcheckが戻り値0を返し、stop後に実行されるcheckが戻り値0以外を返すようにしないと、クラスタの起動・停止でfailになってしまうので、ちゃんとcheckするようにしました。

```
NODE1-VIP用のスクリプトを作ります。

# mkdir /u01/app/grid/script/
# vi /u01/app/grid/script/manage-secondary-ip1.sh
---------------------
#!/bin/bash

HOST1=ora01 # NODE1のホスト名
HOST2=ora02 # NODE2のホスト名
LOG_FILE=$(dirname ${0})/$(basename ${0} .sh).log
STATE_FILE=$(dirname ${0})/$(basename ${0} .sh).laststate
VIP_ADDR=10.10.2.51 # VIPのアドレス
VIP_NAME=ora01-vip  # VIPのホスト名
REGION_NAME=ap-tokyo-1 # リージョン
export PATH=$PATH:/root/bin

case $(hostname -s) in
    "${HOST1}")
        # NODE1のVNIC OCID
        VNIC_OCID=ocid1.vnic.oxxxxxxx
        ;;
    "${HOST2}")
        # NODE2のVNIC OCID
        VNIC_OCID=ocid1.vnic.oxxxxxxx
        ;;
esac

echo "[$(date '+%Y/%m/%d %H:%M:%S')]: ${1} called" >> ${LOG_FILE} 2>&1
case ${1} in 
    'start')
        oci --auth instance_principal --region ${REGION_NAME} network vnic assign-private-ip \
          --vnic-id ${VNIC_OCID}\
          --ip-address ${VIP_ADDR}\
          --hostname-label ${VIP_NAME} \
          --unassign-if-already-assigned >> ${LOG_FILE} 2>&1
           
        ret_code=${?}
        ;;
    'stop')
        oci --auth instance_principal --region ${REGION_NAME} network vnic unassign-private-ip \
          --vnic-id ${VNIC_OCID}\
          --ip-address ${VIP_ADDR} >> ${LOG_FILE} 2>&1

        ret_code=${?}
        ;;
    'clean')
        ;;
    'check')
        oci --auth instance_principal --region ${REGION_NAME}  network private-ip list \
          --vnic-id ${VNIC_OCID} \
          --query 'data[]."ip-address"' 2>>${LOG_FILE} |grep -o -E -e [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ |grep -E -e ${VIP_ADDR}$ >> ${LOG_FILE} 2>&1
        ret_code=${?}
        ;;
    *)
        ;;
esac

if [[ ${ret_code} -ne 0 ]]; then
    exit 1
fi

exit 0
---------------------
```

同じようにNODE2-VIPとSCAN用のスクリプトも作ります。
VIP_ADDR=
と
VIP_NAME=
を修正するだけでよいです。

```
# diff manage-secondary-ip1.sh manage-secondary-ip2.sh 
7,8c7,8
< VIP_ADDR=10.10.2.51 # VIPのアドレス
< VIP_NAME=ora01-vip  # VIPのホスト名
---
> VIP_ADDR=10.10.2.52 # VIPのアドレス
> VIP_NAME=ora02-vip  # VIPのホスト名

# diff manage-secondary-ip1.sh manage-secondary-ip3.sh 
7,8c7,8
< VIP_ADDR=10.10.2.51 # VIPのアドレス
< VIP_NAME=ora01-vip  # VIPのホスト名
---
> VIP_ADDR=10.10.2.53 # VIPのアドレス
> VIP_NAME=ora-scan # VIPのホスト名
```

作ったら実行権限を付与後、NODE2にファイルを転送します。

### クラスタリソースに登録
クラスタリソースにスクリプトを登録し、VIPの起動停止と連動するようにします

```
※ora.xxx.vipは環境に合わせて読み替えてください

# crsctl add resource oci_ip_control_vip1 \
 -type cluster_resource \
 -attr "ACL='owner:root:rwx,pgrp:root:r--,other::r--',ACTION_SCRIPT=/u01/app/grid/script/manage-secondary-ip1.sh,SCRIPT_TIMEOUT=120,CHECK_INTERVAL=0,RESTART_ATTEMPTS=0,START_DEPENDENCIES=hard(intermediate:ora.xxx.vip) pullup(intermediate:ora.xxx.vip),STOP_DEPENDENCIES=hard(ora.xxx.vip)"

# crsctl start res oci_ip_control_vip1
CRS-2672: Attempting to start 'oci_ip_control_vip1' on 'xxx'
CRS-2676: Start of 'oci_ip_control_vip1' on 'xxx' succeeded

# crsctl stat res oci_ip_control_vip1 -t
--------------------------------------------------------------------------------
Name           Target  State        Server                   State details       
--------------------------------------------------------------------------------
Cluster Resources
--------------------------------------------------------------------------------
oci_ip_control_vip1
      1        ONLINE  ONLINE       xxx01                    STABLE

```
おなじようにNODE2用VIP、SCAN用のVIPも登録します

### 動作確認
クラスタの外部からVIPとSCANにpingを打ち続け、1台ごとに停止・起動を繰り返し、pingの応答がF/Oすることを確認します。

------
パッチをあてる場合は、Doc# 2582139.1にご注意ください