IBM Cloud: PCI InterfaceとVLAN Interfaceの違いについて

#1. はじめに
BM for VPCを理解する上で、ネットワークインターフェースの種類とその違いについては分かりにくいトピックの1つではないでしょうか。IBM Cloud docsには以下の解説ページがありますが、ちょっとこれを読んだだけでは分からない人もいるのではないかと思いました。そこで、この記事では私の理解の範囲においてこの違いについて説明してみたいと思います。

https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-network&locale=en
https://cloud.ibm.com/docs/vpc?topic=vpc-managing-nic-for-bare-metal-servers&interface=ui&locale=en

#2. PCI Interface

- PCI InterfaceはOSから認識される物理ポートです。ESXiでは`vmnic0, vmnic1, ...`と認識されるアップリンクポートになります。
- PCI Interfaceは全部で8つまで構成可能です。
- PCI Interfaceは、実際はBM for VPCのSmartNICで構成されています。このSmartNICには100Gbpsポートが2つ搭載されて冗長構成をとっています。ただし、SmartNICの物理ポートをそのままOSが認識しているのではありません。SmartNICの仮想化機能であたかも物理ポートがOSに搭載されているように見せています。
- 現時点で、PCI Interface間での NIOC(Network I/O control) /Shapingを行う機能はありません。
- PCI Interfaceを作成する度にIPアドレスとMACアドレスがVPCから割り振られます。1つ目のPCI Interfaceは、ESXiでは仮想スイッチ上のVMkernel(vmk0)として構成されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/aecef593-2ebc-7927-3be8-5ad8bd3eb751.png)


```txt:PCIInterfaceを8つ構成した場合。OSからはあたかも8つの物理ポートがあるように見える。
[root@esx-001:~] esxcfg-nics -l
Name    PCI          Driver      Link Speed      Duplex MAC Address       MTU    Description
vmnic0  0000:19:00.0 ionic_en    Up   100000Mbps Full   02:00:04:2c:82:0e 1500   Pensando Systems DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card, Ethernet Controller
vmnic1  0000:1a:00.0 ionic_en    Up   100000Mbps Full   02:00:0f:2c:82:0e 1500   Pensando Systems DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card, Ethernet Controller
vmnic2  0000:1b:00.0 ionic_en    Up   100000Mbps Full   02:00:11:2c:82:0e 1500   Pensando Systems DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card, Ethernet Controller
vmnic3  0000:1c:00.0 ionic_en    Up   100000Mbps Full   02:00:06:2c:82:0e 1500   Pensando Systems DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card, Ethernet Controller
vmnic4  0000:1d:00.0 ionic_en    Up   100000Mbps Full   02:00:08:2c:82:0e 1500   Pensando Systems DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card, Ethernet Controller
vmnic5  0000:1e:00.0 ionic_en    Up   100000Mbps Full   02:00:0a:2c:82:0e 1500   Pensando Systems DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card, Ethernet Controller
vmnic6  0000:1f:00.0 ionic_en    Up   100000Mbps Full   02:00:0c:2c:82:0e 1500   Pensando Systems DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card, Ethernet Controller
vmnic7  0000:20:00.0 ionic_en    Up   100000Mbps Full   02:00:0d:2c:82:0e 1500   Pensando Systems DSC-100 40/100G 2-port 8G RAM 16G eMMC G1 Services Card, Ethernet Controller
```


#2. VLAN Interface

##2-1 VLANという概念を導入するモチベーション
そもそもVPCって最初からネットワークが仮想化されているのでVSI for VPCを構築する際にもVLANなんて意識していなかったはずです。なぜVPC上でVLANを考える必要があるのか？と思われる方も多いのではないでしょうか。
VLANの必要性は、ESXiにおけるNW構成を実際に意識してみたら分かるのではないかと思います。ESXi上では仮想スイッチを構成し、そのポートグループにVMを接続しますが、VLANの概念がなければ全てのVMは同じブロードキャストドメイン(VLAN=0)に属することになります。これだと、確かにVM間の通信はルーター経由になるとしても、ARPなどの低層プロトコルの通信は互いに見えてしまいます。これではあまり嬉しくないですよね。
<img width="50%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/291ca4de-4aac-599f-573e-9ca97b911748.png">
いったんVPCのSDNに入ってしまえばVLANは気にする必要はないですが、ESXi内部でネットワークを分離するためにはやはり以下のようにVLANの概念が導入されている方が便利そうです。
<img width="50%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/58efbcfe-6a41-a6ce-daff-910536bd8d61.png">

##2-2 VLAN Interfaceとは

物理サーバーにLinuxが導入され、そこにIPアドレスが1つ割り当てられているケースを考えましょう（左図）。物理サーバーにはNICが割り当てられており、正しくドライバーが読み込まれていれば、そのポートごとにネットワークインターフェース(eth0)を構成します。 利用者はLinux上からはこのeth0に対して設定を行い、IPアドレスなどを割り当てます。この場合、物理サーバー視点ではVLANを意識することはありません。

一方で、サーバー内でVLANに対応したインターフェースを構成することが可能です（中図の`eth0.100`や`eth0.200`)。これが所謂VLAN Interfaceになります。このインターフェースに割り当てられたIPアドレスを使えば、OSが対抗スイッチに送信する時にVLAN番号のタグ付けをして送信してくれるため、VLANレベルでネットワークを分離することができます。Classic InfrastructureでVRAを構成したことがある人は、VLANをassociateした時に[以下のようにVIFを構成](https://cloud.ibm.com/docs/virtual-router-appliance?topic=virtual-router-appliance-routing-your-vlans)したことがあるのではないでしょうか？このIPアドレスを使って通信する時は、該当のVLAN番号(1432や1693)でタグ付けして対抗スイッチに送るので、これもVLAN Interfaceですね！結局VLAN Interfaceとは、「IPアドレスとMACアドレスを持ち、そのIPアドレスがサーバー外部と通信する際には何らかの仕組みでVLAN番号のタグ付けを行う必要がある。」ということだけを意識しておけば良いのかもしれません。。

```
vyatta@vra01# set interfaces bonding dp0bond0 vif 1432 address 10.0.10.14/24
vyatta@vra01# set interfaces bonding dp0bond0 vif 1693 address 10.0.20.1/24

vyatta@vra01:~$ show interfaces
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface       IP Address                        S/L  Speed/Duplex  Description
---------       ----------                        ---  ------------  -----------
dp0bond0        10.132.122.196/29                 u/u  2g/full
（途中略）
dp0bond0.1432   10.0.10.14/24                     u/u  2g/full
dp0bond0.1693   10.0.20.1/24                      u/u  2g/full
（途中略）
```

最後に、この構成をESXiおよび仮想スイッチに拡張したのが右図です。この構成では、このESXiそのものに割り振られた`10.0.0.10/24`というアドレスでさえ、uplink portではなく、仮想スイッチに接続されたVMkernel(`vmk0`)にIPアドレスを割り振っています。そして、VLAN100で構成されたポートグループにおいては、VLANタグの付け外しを仮想スイッチが担当してくれるため、VMにVLAN InterfaceのIPアドレスを割り当てると期待した挙動になることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/39895af1-46fb-c089-380b-d6bade777899.png)



##2-3 VLAN Interface作成時の注意

- VLAN Interfaceを作成する時には、必ずVLAN番号が指定される必要があります。VLAN=0は利用できません。
- VLAN Interfaceはどれか1つのPCI Interfaceに関連づける必要があります。同じVLAN番号のVLAN Interfaceを異なるPCI Interfaceに関連づけることはできません。
- `Allow interface to float`を有効にすることで、GARP/RARPが機能します。vMotionなどで筐体間を移動したいVM環境では必ず有効にしましょう。後から変更することはできません。
- VLAN Interfaceを作成すると、IPアドレスとMACアドレスが割り当てられます。VMのIPアドレス設定をDHCPで構成したい場合は、VLAN Interface作成時に割り当てられたMACアドレスを利用する必要があります。固定IPで構成するのであれば、ESXiが自動生成したMACアドレスを利用しても構いません。

#3. よくあるFAQ

##Q1) 冗長化は必要ですか？
SmartNIC内で冗長構成をしているため、利用者側での対応は不要です。
むしろAggregationを利用者側で構成すると正しく機能しなくなる可能性があります。

[IBM Cloud docs](https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-network&interface=ui&locale=en)より

:::note info
All network interfaces are backed by two redundant physical ports that are on the TORs (top-of-rack) switch. IBM Cloud® manages the aggregation, so you don't need to create multiple PCI interfaces for redundancy.
:::
:::note warn
A bare metal server can have only one Uplink that is set on a standard vSwitch or distributed vSwitch. Otherwise, the network might not work properly
:::

##Q2)PCI Interface/VLAN InterfaceのIPアドレスは利用者側で指定可能ですか？
UIから作成すると指定したサブネットの中からVPCが自動的に割り当ててしまいます。CLI(`ibmcloud is bare-metal-server-network-interface-create`)を使えば、利用者が明示的にIPアドレスを指定可能です。

##Q3) Security Groupは利用可能ですか？
PCI Interface/VLAN Interfaceの双方で独立したルールを適用可能です。ただしSecurity GroupはSmartNICで機能するため、例えば以下のVM1-VM2間のような通信では仮想スイッチ間での通信で完結してしまうためSecurity Groupは機能しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/e1948756-1e75-89ff-9441-bf33f7ba7256.png)

1つの回避策としては、以下を参照してください。
[IBM Cloud: BM for VPCで同一サブネット内の通信でSecurity Groupを強制する方法](https://qiita.com/testnin2/items/2a871b43a07c6d32f358)

##Q4) Floating IPは利用可能ですか？
PCI Interface/VLAN Interfaceの双方で利用可能です。
原則1つのFloating IPは1つのInterfaceにしか紐付けできませんが、Infrastructure NATが無効になっている時は複数のFloating IPを1つのInterfaceに紐付け可能です。

##Q5) `Infrastructure NAT`とは何ですか？
[こちら](https://qiita.com/testnin2/items/ca3629489574d24f55bf)を参照してください。

##Q6) PCI InterfaceのIPアドレスはVMkernel用途なのでしょうか？
限りなくYESに近いですが、絶対にVMに割り当ててはいけないということはありません。ただし、以下の理由のため、VMにPCI Interfaceを利用する需要は限りなく0に近いでしょう。

- PCI InterfaceのIPアドレスは必ずVLAN=0となります。 VLAN Interfaceは必ず0以外のVLAN番号が付与されます。
- PCI Interfaceを構成せずに、VLAN=0のIPアドレスを割り当てる仕組みが現時点では存在しません。そのため、IPアドレスの割り振りの度にサーバーの停止が必要になり、しかもPCI Interfaceの制限上、8つまでしか構成できません。一方で、VLAN Interfaceの追加にはサーバーの停止は不要です。
- PCI InterfaceのIPアドレスは、vMotionなどで別筐体に移動できません。VLAN Interfaceは`Allow interface to float`の構成をすることでGARP/RARPが機能します。


##Q7) subnetとVLANは1:1で構成するべきですか？
はい、それがBest Practiceです。
1つのVLANに複数のsubnetを紐づけることは問題ありません。一方で、1つのsubnetを複数のVLANに紐づけることは（構成上はできるようですが）正しく機能しない可能性があります。
https://cloud.ibm.com/docs/vpc?topic=vpc-bare-metal-servers-network#nic-limits&locale=en

##Q8) VLAN=100のVLAN Interfaceを複数のPCI Interfaceに紐付けて構成できますか？
できません。VLAN Interfaceは必ずどれか1つのPCI Interfaceに紐づく必要がありますが、PCI Interface#1で既にVLAN=100が指定されていれば、PCI Interface#2でVLAN=100を利用することはできません。以下に例を示します。

- VLAN Interfaceを作成すると、どちらのPCI Interfaceに紐付けるかを選択する画面が出る。<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/6af46e31-9737-6d55-befa-2307b2669138.png" width=50%>
- VLAN100を指定すると自動的にPCI Interface#1(eth0)が選択されてしまう（これは既にPCI Interface#1でVLAN=100を構成しているから）。<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/4c057f0c-a4d0-aefd-93f2-eaf700d7e577.png" width=50%>
- PCI Interface#2に、PCI Interface#1で定義されているVLAN100を構成しようとするとエラーになる。<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/60606c62-9a00-1f4b-7fc9-e0851689bfd6.png" width=50%>

docsにも以下のように書かれています。
https://cloud.ibm.com/docs/vpc?topic=vpc-managing-nic-for-bare-metal-servers&interface=ui&locale=en

:::note warn
You can't add the same VLAN ID to the Allowed VLANs lists of two PCI interfaces on a single bare metal server. You can't create a new PCI interface if it contains VLAN IDs that are specified in the Allowed VLANs list of any existing PCI interface.
:::