IBM Cloud(VPC)のアドレス設計・subnet設計はどうするべきか？

# 1. はじめに

クラウドではどのようにアドレス設計・subnet設計をするべきなのでしょうか？オンプレミスでの設計思想をそのままクラウドに持ち込んでも問題ないのでしょうか？

オンプレミスでのNWではVLANで分割した範囲がサブネットで分割した範囲（つまりVLANとサブネットは1:1に対応している）ケースが多く、その設計の思想をそのままクラウド上のVPCに持っていこうとすると、業務サブネット、運用サブネット、バックアップ用サブネット、、、など細かくサブネットを切ってしまいがちです。

もちろんそのように構成することが絶対に駄目だと言うわけではありませんし、そのように設計することもできます。今までがそのように構成されているのであれば、同様の方針に従って設計することは大きな間違いが発生しにくいのかもしれません。ただし、現場のプロジェクトでは、本当にオンプレミス時の設計思想をクラウドにそのまま持ち込んで良いのか？何か落とし穴がないのか？という懸念も少なからずあるのではないかと思います。

本来、オンプレミスでもクラウドでもセキュリティーをなるべく向上し、なるべく運用を容易にした上で、最大限の性能を引き出したいということは同じです。しかし、オンプレミスやクラウドではできることが違います。目指すゴールは同じでも、**クラウド（特にIBM Cloud)固有の制限事項**や**オンプレミスのNW設計に変わる改善案**があればアプローチが変わるはずです。にも関わらず、「現行踏襲」という一見無難のように見える方針の元で設計を進めると、思わぬ落とし穴にはまりかねません。

本稿では、IBM Cloud(VPC)ではどのようにアドレス設計・subnet設計をするべきなのかについて、意見を述べさせていただきたいと思います。**あくまで私の私見ですので、悪しからず。**

# 2. subnet設計と同時にaddress prefix設計をする

**address prefixというのは、オンプレミスには存在しないクラウド固有の概念です**。IBM CloudのVPCでは、address prefixを**AZごとに**まず定義し、そのaddress prefixの中からsubnetを割り当てます。(VPC単位でリージョンレベルで定義するのではなく、AZレベルでの定義であることにご注意ください）。

例えば、IBM Cloudにおいては

- 10.0.0.0/24

というaddress prefixをAZに対して最初に定義し、その後にこの10.0.0.0/24から、

- 10.0.0.0/26
- 10.0.0.64/26
- 10.0.0.128/26
- 10.0.0.192/26

というsubnetを切り出して使います。

このように4分割したsubnetを色々な用途に利用していく上で注意しないといけないのは、Direct LinkやTransit GatewayによるVPC外部との接続において、**対向環境にBGPで経路広告されるのはsubnet単位ではなくaddress prefix単位**だというIBM Cloudの仕様です。もし、10.0.0.0/24というaddress prefixを作成しているが、そのうち`10.0.0.0/26`だけはBGPで広告されないようにDirect LinkやTransit Gatewayのprefix filteringで制御しようとしても、それはできないのです。つまり、**VPC外部とのやり取りにおいて意味のある塊は、subnetではなくむしろaddress prefixです。** 

将来的に複数のVPCをTransit Gatewayで接続する際には、互いのVPCのネットワークの重複があってはいけませんが、よく考えると本当に重複があってはいけないのは、外部と接続が必要なネットワークだけです。それ以外の内部のネットワークは本来、BGPで広告しなければ良いのですから、他のVPCと接続しないaddress prefixは、prefix filtering機能を使っておけば対向VPCにBGP広告されないため、IPアドレスの重複が発生しないように構成することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/2fa41d39-9220-ec24-8f0c-e8117b97b652.png)


そもそもクラウド用に確保したネットワークなのでしょうし、Security GroupやNetwork ACLで通信制御できることから、過度にAddress prefixの設計に頭を悩ます必要はないのかもしれませんが、address prefixを単純に細分化して利用していくのが果たして問題ないのかを事前に評価しておく必要があります。

なお、上記の内容を鑑みると、**１つのaddress prefixに含むsubnetは原則1つ**で構成するのが一見理想的に見えます。subnetを分ける目的は**subnet毎の管理をしたいから**です。この観点で言うとaddress prefix単位でしかBGP filteringの制御がしづらいのであればaddress prefix単位で分割した方が良いというのが自然な考えです。しかし、address prefix単位で分割しようにも、IBM CloudのVPCには[以下の制限](https://cloud.ibm.com/docs/vpc?topic=vpc-quotas#vpc-quotas)があります。1 AZあたり利用できるaddress prefixは8程度までです。これを鑑みると、外部接続をするためのaddress prefixと、外部接続が不要なaddress prefixの２種類ぐらいでスタートするぐらいから検討を始めても良いのかもしれません。

| Resources | Quota | 
|:-|:-|
|  Subnets | 100 per VPC  |
|  address prefixes  |  25 per VPC | 


# 3. サーバーに割り当てるvNICは可能な限り少なくする（できたら1つ）。

これは、以下の図のようにオンプレミスのNW設計のように1つのサーバーに、業務サブネット、運用サブネット、バックアップ用サブネット、、、などのvNICを作成してsubnet単位で細かく制御していく方法を採用しなくても良いのではないかという主張です。
以下でその理由を１つずつ見ていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/c54c7867-cbd2-df81-8bc2-e21acfee2451.png)



## 3-1. セキュリティーの観点

従来のオンプレミスでのNWでは、サーバー毎にFirewallを設けるという考えがあまりありませんでした。OSにSoftware Firewallを導入して制御することももちろんありますが、個々のOS設定に頼らざるを得ないためあくまで補助的に利用されるだけに留まり、原則はVLAN毎にサーバーを配置し、VLAN間通信（≒Subnet間通信）はNWレベルでFirewall機器などを使って制御していました。これは、クラウドにおけるVPCではNetwork ACLしか存在しないイメージに相当します。

しかし、クラウド環境では**ゼロ・トラスト**の考えから、全てのサーバー、ロードバランサー、VPEの通信を制御する**マイクロセグメンテーションをまずは最初に考えることが一般的**であり、VPCではSecurity Groupを使ってvNICごとにFirewallを構成することができます。また、Load BalancerやVPNやVPEに対してもSecurity Groupを構成することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ac20de49-3761-301d-0a70-8dee3a004159.png)


もちろん、業務サブネット、運用サブネット、バックアップ用サブネット、、、のように細かく分割することでSecurity GroupだけでなくNetwork ACLによる制御も併用して実施できるという利点はあります。ただし、Security Groupは絶対に実装する必要があるのですから、Network ACLまで併用すると設計が非常に複雑になる可能性があります。また、Security Groupでは、ルールの送信元としてSource IPだけでなく、他のSecurity Groupをルールの送信元として指定することが可能であり、例えば

- VPC外部からのアクセスは、送信元IPアドレスで許可する
- APサーバーは、Web-Security Groupが適用されているサーバーから Port 9080 でのアクセスを許可する
- DBサーバーは、AP-Security Groupが適用されているサーバーから Port 3306 でのアクセスを許可する
- 全てのサーバーは、Bastion-Security Groupが適用されているサーバーから Port 22 でのアクセスを許可する

といった構成にする方が、サーバーに割り当てられているサブネットを意識する必要性を下げることが可能となり、より柔軟性が増します。Subnet間通信を制御する方法より、もっと使い勝手の良い通信制御であるSecurity Groupがクラウドでできるのであれば、Network ACLは最低限の利用にだけ留めてより管理を省力化した方が良いのではないというのが私の意見です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/8869b7f8-d472-c1b3-a9e8-1a763e7e0aaf.png)



## 3-2. パフォーマンスの観点

オンプレミスの物理サーバーではNICを分けることにより、そのNW帯域を独立して保証できるという利点がありました。もしくは、VMware環境などでは、VM(仮想サーバー)レベルで複数のvNICがあっても、VLANレベルで帯域制御可能だし、全てのvNICが物理NICの性能をベストエフォートで利用できました。

しかし、IBM Cloudでは違います。vNICが増えると、1つのvNICあたりに利用できるNW帯域の上限は小さくなります。 さらには、VSIに割り当てられたbandwidthは全てネットワーク通信にのみ利用できるわけではなく、この帯域からストレージ通信にも割り当てられています。その比率は変更できますが、デフォルトでは25%がstorage bandwidthとして割り当てられており、ネットワークで利用できるのは75%です。

> https://cloud.ibm.com/docs/vpc?topic=vpc-bandwidth-allocation-profiles#network-perf-notes-for-profiles
> Profiles can have a total maximum bandwidth of up to 80 Gbps. **That bandwidth is split between Network and Storage traffic. The network bandwidth allocation is distributed evenly across network interfaces, and each network interface has a cap of 25 Gbps.** You might need to attach multiple network interfaces to your virtual server instance to optimize network performance.

例えば、16vCPUのサーバーには、32Gbpsのbandwidthが割り当てられます。ネットワークに割り当てられるのは、

` 32 Gbps x 0.75 = 24 Gbps`

です。

- vNICが1つの時: vNICあたりの性能上限は 24 Gbps
- vNICが2つの時: vNICあたりの性能上限は 12 Gbps
- vNICが3つの時: vNICあたりの性能上限は 8 Gbps
- vNICが4つの時: vNICあたりの性能上限は 6 Gbps

という風に、vNICあたりの性能上限が頭打ちしていき、せっかくのネットワーク帯域が有効利用できない可能性があります。おそらく、1つのvNICでたくさんコネクションを張った方が、NW帯域の利用効率は高いでしょう。



## 3-3. ルーティングの観点

複数のvNICが付いていると、OSのルーティング設定にも考慮が必要になる場合があります。

例えば、インターネットからのアクセスがあるため、Webサーバーの１つ目のvNICが属するネットワークがdefault gatewayになります。用途に応じてvNICを追加していくということは、そのvNICごとにstatic routeをVSIで構成していく必要があります。オンプレミスのようなユーザーが完全に仕様を決められる環境と異なり、クラウドのような内部のネットワーク情報が利用者に完全に公開されていない環境において、常に最新の経路情報を個々のサーバーのルーティング設定に追加し保守していく必要があるのは、大変なのではないでしょうか。その点、vNICが１つであれば、default gatewayしか必要がない構成なので、管理が非常に容易になります。


## 3-4. vNICを増やすべき例外

とは言っても、いくつか例外は存在します。例えば以下のケースが考えらえるでしょう。

- クラスターソフトウェアによっては、サービス用のsubnetの他に、ハートビート用のsubnetを併用することが要件となることがあります。
- VNF(F5やPaloAltoなど）などは、製品仕様として複数のsubnet/vNICを必要とする場合があります。
- 32vCPU環境（６４ Gbps bandwidth）以上の環境では、デフォルトでネットワークに割り当てられる帯域は、以下のようになります。vNICあたりの性能上限は 25Gbps なので、巨大プロファイルにおいてはvNICを分割することで割り当てられた帯域を最大限に利用できる可能性があります。
    - `64 Gbps x 0.75 = 48 Gbps `
    - `80 Gbps x 0.75 = 60 Gbps `



# 4. 小さなサイズのsubnetは作らない

IBM Cloudでは、`/29` でsubnetを構成することが可能です。`/29`だと本来8つIP アドレスが存在しますが、そのうち5つはIBM Cloudによって予約されており、実際にユーザーが利用できるのは3つのみです。例えば、`10.10.0.0/29`だと以下のようになります。

- 10.10.0.0 (Network address)
- 10.10.0.1 (Gateway address)
- 10.10.0.2 (reserved by IBM)
- 10.10.0.3 (reserved by IBM for future use)
- 10.10.0.4
- 10.10.0.5
- 10.10.0.6
- 10.10.0.7 (Broadcast address)

よって、あまり小さいsubnetを作成すると無駄が大きくなります。

参考: https://cloud.ibm.com/docs/vpc?topic=vpc-about-networking-for-vpc&locale=en#subnets-in-the-vpc



# 5 同一機能を持つサーバー群ごとにSubnetを用意する

## 5-1. サブネットを分けることの利点

専用subnetを作成することの利点は、以下にあります。

- IP address rangeから用途を判別しやすい
- 他のリソースによってsubnet内のIPアドレスが消費されることはない
- subnetごとにNetwork ACLを設定できる
    - 基本的にはSecurity Groupを主軸としてネットワークを設計するべき。しかし、どうしてもSecurity Groupでは保護できないケース（例えばNetwork ACLは、Security Groupと違って拒否ルールを設定できる）があればNetwork ACLを追加で考える。
    - 一方で、[Subnet内通信は、Subnetに対するInbound通信でもOutbound通信でもないのでNetwork ACLの制御の対象外](https://qiita.com/testnin2/items/01a8060a16b894bcab62)。よって、Network ACLで制御をしたい対象はsubnetを分ける必要がある。
- subnetごとにCustom Routeを構成できる（他のCustom Routeの影響を受けない）

すでに記載した通り、１つのWebサーバーが、業務サブネット、運用サブネット、バックアップ用サブネット、、、など複数のサブネットに同時に足を出す必要はないと私は思っています。

一方で、Security Groupによるマイクロセグメンテーションができるなら、別にIPアドレスは何であってもいいのでは良いのかもしれませんが、上記に列挙したようは**同一機能を持つサーバー群ごとに専用のSubnetを用意する**利点は否定できません。特に、Load Balancer/VPN/VPEなどは独立したsubnetを用意することは、IBM Cloud docsで推奨されています。

ただし、全部で数台程度しかないサーバーのであれば、その少数のサーバーのためだけに細かくSubnetを分けるのは管理が大変かもしれません。Security Groupを使えば1つのSubnetの中でWeb/AP/DB/Bastionを同居させても問題は少ないと判断できるケースもあるかもしれませんので、その辺りはサーバー台数の規模にも応じてSubnetを分ける・分けないを決めると良いと思います。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/f857af15-9b17-c4b3-e50f-835ce0954742.png)


## 5-2. Load Balancer

IBM Cloud docsでは、通常のNLBでは、NLB専用のsubnetを作成することを推奨しています。

> https://cloud.ibm.com/docs/vpc?topic=vpc-nlb-limitations&interface=ui
> To ensure service availability, use a dedicated subnet with your NLBs. Clients and members should reside in an alternate subnet.

> https://cloud.ibm.com/docs/vpc?topic=vpc-network-load-balancers#types-network-load-balancers
> For private load balancers, you must have a dedicated subnet with no custom routes configured for the subnet.

NLB route modeでは、L3 Load BalancerとしてActiveなサーバーにパケットを転送するだけなので、ターゲットとなるVNFとNLB(route mode)は同一subnetに存在する必要があります。
> For an NLB with routing mode enabled: The NLB and the VNF back-end targets must be in the same subnet.

ALBは、負荷増大時に動的にインスタンスが追加されることでスケールアウトする構成になっています（なのでALBにはIPアドレスではなくホスト名でアクセスする）。ALBが正しくスケールアウトできるため、ALBも専用subnet上に構成される方が望ましいでしょう。



## 5-3. VPN Gateway/VPN Server

IBM Cloud docsでは以下のように専用のsubnetを作成することを推奨しています。

> https://cloud.ibm.com/docs/vpc?topic=vpc-faqs-vpn-server#faq-vpn-server-choose-subnet
> **Why must I choose subnets during VPN server provisioning?**
> The server resides in the VPN subnet that you choose. A VPN server needs two available private IP addresses in each subnet to provide high availability and automatic maintenance. It is best if you use the dedicated subnet for the VPN server of size 8, where the length of the subnet prefix is shorter or equal to 29. With dedicated subnets, you can customize the security group and ACL for greater VPN server flexibility

> https://cloud.ibm.com/docs/vpc?topic=vpc-troubleshoot-routing-issues&locale=en
> Create a dedicated subnet for the VPN gateway.
Create a dedicated custom routing table.
Associate the dedicated subnet with the dedicated custom routing table.

> https://cloud.ibm.com/docs/vpc?topic=vpc-faqs-vpn#faq-vpn-5
> **Why do I need to choose a subnet during VPN gateway provisioning?**
> The VPN gateway must be deployed in the VPC to provide connectivity. A route-based VPN can be configured to provide connectivity to all zones. A VPN gateway needs four available private IP addresses in the subnet to provide high availability and automatic maintenance. It is best if you use a dedicated subnet for the VPN gateway of size 16, where the length of the subnet prefix is shorter or equal to 28.

## 5-4. VPE

IBM Cloud docsでは以下のように専用のsubnetを作成することを推奨しています。

> https://cloud.ibm.com/docs/vpc?topic=vpc-end-to-end-private-connectivity-vpe&interface=cli
> You should put VPEs in a separate, dedicated subnet that is not associated with your workloads.

## 5-4. 踏み台環境(Bastion Server)

踏み台環境は、外部からの中継環境として存在し、明らかに外部からアクセスすることを意図した環境です。Custom Routeなどを構成する必要がないため、独立したsubnetにしておくことが良いように思います。

# 6. できたら利用を避けるアドレス帯を意識する

## 6-1. 10.0.0.0/14, 10.200.0.0/14, 10.198.0.0/15,10.254.0.0/16はできたら利用を避ける。

このIP address rangesを利用すると、Classic Infrastructureとの接続時にIPアドレス重複が発生します。もしClassic Infrastructureと接続する可能性があるならば、利用を避けるべきです。

> https://cloud.ibm.com/docs/transit-gateway?topic=transit-gateway-helpful-tips&locale=en#classic-infra-connection-considerations
> When you connect a VPC and the classic infrastructure to a transit gateway, all prefixes in the VPC become visible to the classic infrastructure VRF, which uses IP addresses in the 10.0.0.0/8 space. To ensure successful connectivity with the classic infrastructure, do not use prefixes in your VPCs that overlap with the 10.0.0.0/14, 10.200.0.0/14, 10.198.0.0/15, and 10.254.0.0/16 blocks. Also, don't use addresses from your classic infrastructure subnets. 


## 6-2. 172.16.0.0/16, 172.18.0.0/16, 172.19.0.0/16, 172.20.0.0/16はできるだけ利用を避ける。

Red Hat OpenShift on IBM Cloud(ROKS)やIBM Cloud Kubernetes Service(IKS)ではこのIP rangesを利用します。該当のVPCにROKSやIKSをプロビジョニングすることはないのかもしれませんが、もし使わないで済むのであれば、それに越したことがないでしょう。

> https://cloud.ibm.com/docs/openshift?topic=openshift-vpc-subnets
> The 172.16.0.0/16, 172.18.0.0/16, 172.19.0.0/16, and 172.20.0.0/16 ranges are prohibited.

> https://cloud.ibm.com/docs/containers?topic=containers-vpc-subnets
> 172.16.0.0/16, 172.18.0.0/16, 172.19.0.0/16, and 172.20.0.0/16 ranges are prohibited.