OCI ComputeにセカンダリVNICを追加する Part 2

# 前回の続き

前回から続いた内容なので、5から始まる連続した段落番号をつけている。

* [OCI ComputeにセカンダリVNICを追加する Part 1](https://qiita.com/yamada-hakase/items/a6d4d846e4cf4afb9453)

# 5. セカンダリVNICを永続的に設定する（1）

提供されているスクリプトを使うと、セカンダリVNICを簡単に構成できることはわかった。ところがOSをリブートすると設定が消えてしまう。そこで永続に設定することを試みる。

### 5-1. 永続的に設定するには

永続的に設定する方法として思いつくのは`/etc/sysconfig/network-scripts/ifcfg-<NICデバイス名>`を設定する方法だろう。しかし7系以降からは、直接ファイルを編集するのではなく、NetworkManagerのコマンドである`nmcli`が推奨されている。

**「OSをインストールしたら最初にNetworkManagerを無効にする」といった昔の習慣が懐かしい。**

マニュアルなどもチェックしつつ、永続的に設定する方法を考えると、以下の3種類くらいだろうか。順番に調べてみることにする。

1. nmcliで設定する（7系以降）
2. 「/etc/sysconfig/network-scripts/ifcfg-NICデバイス名」ファイルを作成する
3.  設定スクリプトsecondary_vnic_all_configure.shをOS起動時にキックする


**ネットワーク関連のマニュアル：**

* [Oracle Linux 6 管理者ガイド「ネットワーク構成」](https://docs.oracle.com/cd/E39368_01/E41138/html/ol_netconf.html)
* [Oracle Linux 7 管理者ガイド「ネットワーク構成」](https://docs.oracle.com/cd/E77565_01/E54669/html/ol7-netconf.html)
* [RHEL6 導入ガイド「ネットワークインターフェース」](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/ch-network_interfaces)
* [RHEL7 ネットワークガイド「IP ネットワークの設定」](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/networking_guide/ch-configure_ip_networking)

### 5-2. nmcliで設定する
注：Oracle Linux 8ではnmcliを利用でき、またNetwork Managerも起動している。

nmcliを起動してみよう。

```shell-session
# nmcli
sudo: nmcli: command not found
```

`command not found`
**オーマイガー！インストールされていない？**

6系まではインストールオプションによってはインストールされてないこともあったけれど、7系では必須になったはず。

調べてみると、サービスはinactiveで、RPMもインストールされていない！

```shell-session
# systemctl status NetworkManager
● NetworkManager.service
   Loaded: masked (/dev/null; bad)
   Active: inactive (dead)　★deadというステータス
Warning: NetworkManager.service changed on disk. Run 'systemctl daemon-reload' to reload units.

# rpm -qa | grep -i NetworkManager
★検索にヒットせず
```

ここでNetwokManagerをインストールしてみることも考える。だけれどデフォルトでインストールされるはずのものが、インストールされていないのはタダごとでは無い。

Oracleをはじめとする商用ソフトに通じているみなさまだったら分かるように、勝手なことをすると「サポートする／サポートしない」問題が発生する可能性がある。

ということでnmcliは断念。次へ。

### 5-3. ifcfgファイルで設定する

`/etc/sysconfig/network-scripts/ifcfg-NICデバイス名`を作成して設定する。NICデバイス名は「プライマリVNIC`ens3`」「セカンダリVNIC`ens5`」だと分かっているので、`ifcfg-ens3`をひな形として作成する。

1. ifcfg-ens3ファイルを確認する

```shell-session
# ls /etc/sysconfig/network-scripts/ifcfg-*
/etc/sysconfig/network-scripts/ifcfg-ens3
/etc/sysconfig/network-scripts/ifcfg-lo
```

```shell:/etc/sysconfig/network-scripts/ifcfg-ens3
# Generated by dracut initrd
NAME="ens3"
DEVICE="ens3"
ONBOOT=yes
NETBOOT=yes
UUID="3a77cda7-9164-48d8-b9a6-32e95aae6cff"
BOOTPROTO=dhcp ★プライマリVNICはdhcp
TYPE=Ethernet
NM_CONTROLLED=no
```

2.ifcfg-ens3ファイルをコピーする。

```shell-session
# cp /etc/sysconfig/network-scripts/ifcfg-ens3 /etc/sysconfig/network-scripts/ifcfg-ens5
```

3.以下のように設定する。★印の行が変更箇所。

```shell:/etc/sysconfig/network-scripts/ifcfg-ens5
# Generated by dracut initrd
NAME="ens5"　★
DEVICE="ens5"　★
ONBOOT=yes
NETBOOT=yes
# UUID="e6310354-eb16-4ed2-ac1a-b095cf703a45"　★コメントアウト
HWADDR=02:00:17:00:0d:43　★
BOOTPROTO=static　★
PREFIX=24　★
IPADDR=10.1.0.5　★
MTU=9000　★
TYPE=Ethernet
NM_CONTROLLED=no
```

4.設定が終わったらOSをリブートする。networkサービスはrestartできないので注意。

```shell-session
# reboot
```

5.設定状況を確認する。ens5にIPアドレスは割り当てられ、またルーティングテーブルにも乗っている。

```shell-session
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
    link/ether 02:00:17:00:08:22 brd ff:ff:ff:ff:ff:ff
    inet 10.1.0.5/24 brd 10.1.0.255 scope global dynamic ens3
       valid_lft 86117sec preferred_lft 86117sec
3: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000
    link/ether 02:00:17:00:0d:43 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.5/24 brd 10.1.1.255 scope global ens5
       valid_lft forever preferred_lft forever
```

```shell-session
# ip route
default via 10.1.0.1 dev ens3
10.1.0.0/24 dev ens3 proto kernel scope link src 10.1.0.5
10.1.1.0/24 dev ens5 proto kernel scope link src 10.1.1.5
169.254.0.0/16 dev ens3 proto static scope link
169.254.0.0/16 dev ens3 scope link metric 1002
169.254.0.0/16 dev ens5 scope link metric 1003
```

### 5-4. 動作確認する

想定通りに動作することを確認する。ネットワーク構成やセキュリティルールは以下のように設定している。

* VCN内はssh可能
* 同一サブネット内はpingできるが、異なるサブネットにはpingできない

![sec-nic02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/7b77fcf4-d5f2-1f93-1499-f93b1e3f26ce.png)

VM1からVM2にpingすると失敗する。

```shell-session
VM1~] $ ping 10.1.1.6
PING 10.1.1.6 (10.1.1.6) 56(84) bytes of data.
★止まったまま
```

上記図には登場しないが、Subnet Aに属する他のインスタンスにはpingが成功する。まとめると以下の通り。

* **プライマリVNICが属するサブネットのVMに対してping成功**
* **セカンダリVNICが属するサブネットにVMに対してping失敗**

### 5-5. 原因を調べる

結論から先に言うと、ルーティングの問題でうまく疎通できない。

`secondary_vnic_all_configure.sh`スクリプトでは疎通できているので、その設定状況を調べてみる。以下のコマンドで設定を削除して、再設定する。

```shell-session
/tmp/secondary_vnic_all_configure.sh -d
/tmp/secondary_vnic_all_configure.sh -c
```

いままで`ip route`コマンドでルーティングテーブルを表示していたが、これで表示されるのはmainテーブルだけだ。そこでルーティングテーブルの一覧を表示する。するとort1というルーティングテーブルがあることがわかる。

```shell-session
# ip rule show
0:      from all lookup local
32765:  from 10.1.1.5 lookup ort1 ★
32766:  from all lookup main
32767:  from all lookup default
```

ort1を確認すると、セカンダリVNIC用にルーティングテーブルが設定されている。つまりポリシーベース・ルーティングが設定されている。

```shell-session
# ip route show table ort1
default via 10.1.1.1 dev ens5
10.1.1.0/24 dev ens5 scope link
```

<font color="blue">**ポリシーベース・ルーティングとは**</font>
ポリシーベース・ルーティングの詳細は調べてもらうとして、複数のルーティングテーブルを使ってルーティングを実現する仕組み。`ip rule show`でルーティングテーブルの一覧を表示しているけれど、実際の設定は`/etc/iproute2/rt_tables`に書かれている。

```shell-session:/etc/iproute2/rt_tables
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
10    ort1
```

<font color="red">Network Managerがdisableなのは、デフォルトではポリシーベース・ルーティングをサポートしていないためか？　と思ったけれど、Known issuesに書いてある、↓が主原因かも。</font>
> [Instance reboot fails if the Network Manager service is installed](https://docs.cloud.oracle.com/iaas/Content/knownissues.htm)
> Details: If the Network Manager service is installed, an instance can fail to reboot.
> Workaround: If the Network Manager service is not required, you can uninstall it. If the Network Manager service is required, modify the network interface configuration file before you reboot the instance. Set the NM_CONTROLLED configuration key to "no":

`ip route`や`route`コマンドでよくある失敗が、main以外のルーティングテーブルの見落としだ。そんなときに便利なのが`routel`コマンドだ（7系Linux OSのみ）。ルーティングテーブルのプライオリティも考慮した形ですべて表示できる。

```shell-session
# routel
         target            gateway          source    proto    scope    dev tbl
        default           10.1.1.1                                     ens5 ort1
      10.1.1.0/ 24                                              link   ens5 ort1
        default           10.1.0.1                                     ens3
      10.1.0.0/ 24                        10.1.0.5   kernel     link   ens3
      10.1.1.0/ 24                        10.1.1.5   kernel     link   ens5
   169.254.0.0/ 16                                   static     link   ens3
   169.254.0.0/ 16                                              link   ens3
       10.1.0.0          broadcast        10.1.0.5   kernel     link   ens3 local
       10.1.0.5              local        10.1.0.5   kernel     host   ens3 local
     10.1.0.255          broadcast        10.1.0.5   kernel     link   ens3 local
       10.1.1.0          broadcast        10.1.1.5   kernel     link   ens5 local
       10.1.1.5              local        10.1.1.5   kernel     host   ens5 local
     10.1.1.255          broadcast        10.1.1.5   kernel     link   ens5 local
      127.0.0.0          broadcast       127.0.0.1   kernel     link     lo local
     127.0.0.0/ 8            local       127.0.0.1   kernel     host     lo local
      127.0.0.1              local       127.0.0.1   kernel     host     lo local
127.255.255.255          broadcast       127.0.0.1   kernel     link     lo local
```

これまでの調査で分かったことは「手動で設定するのは大変そう」ということ。またsecondary_vnic_all_configure.shのソースを解析すると、想定より複雑なことをしていて、ネットワーク・ネームスペースも対応している。

そこで「5-1. 永続的に設定するには」で考えた↓の案がよさそうだ。次回はこの方法を説明する。

**「3. 設定スクリプトsecondary_vnic_all_configure.shをOS起動時にキックする」**

* [OCI ComputeにセカンダリVNICを追加する Part 3](https://qiita.com/yamada-hakase/items/abe8114d327c19c98acd)