OpenStackの「物理ネットワークインフラ」と「～アーキテクチャー」について考えてみる

# はじめに
[OpenStack公式のInstallation Guide](https://docs.openstack.org/install-guide/)にはよく**「物理ネットワーク(Physical Network)」** **「物理ネットワークインフラ(Physical Network Infrastructure)」**という言葉が出てきます。

https://docs.openstack.org/newton/ja/install-guide-rdo/overview.html#networking

> ネットワークオプション 1: プロバイダーネットワーク
プロバイダーネットワーク構成では、可能な限り最も簡単な方法で OpenStack Networking サービスをデプロイします。主として、レイヤー 2 (ブリッジング/スイッチング) サービスと VLAN によるネットワーク分離が利用できます。本質的には、仮想ネットワークは<font color="Red">物理ネットワーク</font>にレイヤー 2 でブリッジングされ、レイヤー 3 (ルーティング) サービスは<font color="Red">物理ネットワークインフラ</font>のものが利用されます。また、 DHCP サービスにより IP アドレス情報がインスタンスに提供されます。

(日本語は現時点での最新版であるNewton版のものを引用しています。以下同様)

また、データセンターネットワークと言われることもあります。本記事では、この実体について自分なりに理解した内容を記載します。また、それを元にして、これもドキュメント頻出の「プロバイダーネットワークアーキテクチャー」「セルフサービスネットワークアーキテクチャー」「サンプルアーキテクチャー」との関係について考えてみます。
(誤り等ありましたら教えてください)

# 参考にするページ

OpenStackの「物理ネットワークインフラ」として何が想定されているのかについては、こちらのページが参考になります。

Networking アーキテクチャ
https://docs.openstack.org/ja/security-guide/networking/architecture.html

> 物理サーバのネットワーク接続性
![](https://docs.openstack.org/ja/security-guide/_images/1aa-network-domains-diagram.png)
> 標準的な OpenStack Networking セットアップは最大４つの物理データセンターネットワークがあります。
>
> 管理ネットワーク
> …(中略)
> ゲストネットワーク
> …(中略)
> 外部ネットワーク
> …(中略)
> API ネットワーク

「物理データセンターネットワーク」という言葉が使われていますが、同じ意味と捉えて先へ進めます。要は、OpenStack環境を構築するためには、物理的にサーバ間および外部のネットワーク(例:Internet)との間をつないであげる必要があり、その種類は通信の用途に応じて基本的にこの4種類になる、ということを言っています。

本記事では、OpenStackの物理ネットワークインフラ(もしくは物理データセンターネットワーク)がなぜこの図になるか、という点についてゼロベースで考えてみた結果を記載します。

# 方針

考え方としては、OpenStackを設計した人の気持ちになって「IaaSサービスを提供するソフトウェア」の要件を定義し、万能アーキテクチャ設計ツールであるPowerpointでお絵描きをしながら、その要件を満たすためのアーキテクチャについて考えてみる、という方法をとります。

# 要件定義
求める要件はシンプルに以下のように定義します。

* 要件①：ユーザからの要求に応じて仮想マシン(VM)が作成できること
* 要件②：作成した仮想マシンに対してユーザが通信できること

シーケンス図で書くとこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566422/eeb96712-9e88-bdda-525e-e7948a0c7601.png)

また、パブリッククラウド/プライベートクラウド(IaaS)サービスを念頭においているため、「ユーザ」はインターネットや社内ネットワーク越しに利用するものとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/7d739dab-f5cf-ef6d-0168-f418b2d1bfd4.png)


# 要件①：ユーザからの要求に応じた仮想マシン(VM)の作成
まずはどんな機能が必要かについてざっくり考えていきます。

まず要件①のうち、「ユーザからの要求に応じて」の部分については、REST API等何らかのAPIによって要求を受け付けるものとすると、要求受付のための機能が必要です。この機能を「リクエスト受付」機能とします。また仮想マシンを作成するための機能も必要です。この機能を「VM作成」機能とします。また、リクエスト受付機能とVM作成機能は連携する必要がありますので、ネットワーク的に接続されている必要があるでしょう。

ここまでを図にすると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/620f0e7a-70b0-e619-fdeb-8729b1c25bf2.png)

ここで、インターネット/社内ネットワーク等、外部に出ていくための出口となるルータをゲートウェイ(GW)ルータと呼ぶことにします。[^gwrouter]

[^gwrouter]: 実際の環境では、外部へのアクセスルータの他にL3スイッチがある場合が多いかと思いますが、ここでは「GWルータ」にまとめています。また、ファイアウォール等の機器についても省略しています。

次にこれを物理的な環境に配置してみます。ここでは処理負荷を考慮して、リクエスト受付機能とVM作成機能は別の物理マシンに載せます。リクエスト受付機能を配置した物理マシンは「Cloud Controller Node」(略してController)、VM作成機能を配置した物理マシンは「Compute Node」(略してCompute)と呼ぶことにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/b5380a2b-35dc-6c9b-715a-b16595f7e38b.png)

また、機能間の連携を実現するために、GWルータ - Controller間、Controller - Compute間を物理的なネットワークでつなぐ必要があります。前者の物理ネットワークが、ユーザからのOpenStack APIに対する通信に使われる「**APIネットワーク**」(図中ではAPI)、後者がOpenStack内部で使われる管理用の通信に利用される「**管理ネットワーク**」(図中ではManagement)となります。

また、ここでいう「物理ネットワーク」とは、L2ネットワーク(1つのブロードキャストドメイン)を考えています。L3の接続性については物理マシン側でのIPアドレス設定によって担保されます。ControllerのAPIネットワーク側のNICについては、GWルータからルーティング可能なサブネットに属するIPアドレスを設定します。Management側については、任意のプライベートIPアドレスを設定します。

ここまでで要件①：ユーザからのリクエスト受付とVM作成は実現できそうです(少なくともパワポ上は)ので、次は要件②：ユーザとVMの通信について考えていきます。

# 要件②：ユーザとVMの通信
要件②を実現するためには、作成したVMを外部(インターネット,社内ネットワーク等)に接続する必要があります。そのための構成としては大きく以下の2つが考えられます。

(1) ブリッジ接続
(2) NAT接続
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566422/de5bd990-e36f-eee2-da5e-c0c596f8d3ac.png)


それぞれについて考えていきます。

## (1) ブリッジ接続

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/2017214e-1fa5-2eca-b0f7-25f76042bda2.png)


GWルータからVMまでを直接L2で接続する方法です。VirtualBoxやVMware Workstation Playerのブリッジ接続に相当します。GWルータからComputeの物理NICまでは物理ネットワークを用意しておく必要があります。これが「**外部ネットワーク**」[^external](図中ではExternal)になります。

[^external]: 「外部ネットワーク」という言葉は色々な意味を持つ場合があるため注意が必要です。「インターネット・社内ネットワーク等」の部分を指す場合や、仮想ネットワークのうち、外部に接続しているものを指す場合等があります(別の記事にする予定)。本記事では混乱を避けるため、「Externalネットワーク」と表記します。

また、Computeの物理NICからVMのvNICをつなぐために、Compute内に仮想的なブリッジを作成し、Computeの物理NICとVMのvNICを接続します。この機能を「L2接続」機能とします。

この時、VMのIPアドレスは、GWルータからルーティング可能なものである必要があります。今、GWルータはOpenStackの外の世界に属しており、動的に設定を変えられるわけではないため、ルート設定はあらかじめ行っておく必要があります。このため、ユーザはVMに割り当てたいIPアドレスを自由に選べるわけではなく、GWルータにあらかじめ設定されたサブネット内のアドレスを使うことになります。

### プロバイダーネットワーク(Provider Network)

一般的に、よく**「プロバイダーネットワーク」(Provider Network)**と呼ばれているものは、上図におけるGWルータ～VMのL2ネットワークのことである場合が多いと思います(詳細については別の記事にします)。物理ネットワークインフラであるExternalネットワーク(GWルータ～Computeの物理NICの区間)はクラウドの提供者が用意するものですし、Compute内の仮想ネットワーク区間についても予めクラウド提供者が準備しておくことが多いため、そのような名前がついているものと思われます。

また、プロバイダーネットワークにVMを接続することによってサービスを提供するアーキテクチャが**「プロバイダーネットワークアーキテクチャー」(Provider Network Architecture)**になります。

### VMのIPアドレス管理
VMのIPアドレスについては、ユーザが指定する、もしくはシステム側で自動的に払い出す、という選択肢があります。上記の図はユーザ指定の場合になっており、特に自動的に払い出す機能については考えていませんでした(VMに固定IPを設定する機能については、「VM作成」機能に含むとします)。もともと設定した要件では、VM作成時にユーザに対してVMの接続先情報を返すことになっていたので、ここでは自動払い出し機能について考えていきます。

また、IPアドレスを払い出すということは、IPアドレスの使用状態(使用中/空き)の管理をするということです。ユーザ指定の場合はユーザが管理することになりますが、システム払い出しの場合はシステム側で管理する必要があります。

IPアドレスの自動払い出しおよび使用状態の管理を実現するために、最も安直でリーズナブルな方法はDHCPによる払い出しと管理になると思います。そこで、リクエスト受付機能から制御可能なDHCPサーバ機能を導入します。ここでは、「Network Node」という新たな物理マシンを用意して、そこにDHCPサーバ機能を搭載します。また、DHCPサーバ機能を"プロバイダーネットワーク"につなぎこむために、L2接続機能も実装します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/787cf00e-d4f1-9d7f-d521-587cee1cade5.png)

これが、"プロバイダーネットワークアーキテクチャー" (DHCPあり)の場合の基本的なサーバ構成および物理ネットワークインフラになります。

ここで、冒頭で触れたInstallation Guideの文言に立ち返ってみます。

> ネットワークオプション 1: プロバイダーネットワーク
(中略)
本質的には、仮想ネットワークは<font color="Red">物理ネットワーク</font>にレイヤー 2 でブリッジングされ、レイヤー 3 (ルーティング) サービスは<font color="Red">物理ネットワークインフラ</font>のものが利用されます。また、 DHCP サービスにより IP アドレス情報がインスタンスに提供されます。

「仮想ネットワーク」＝Computeの物理NIC～VM間の仮想ネットワーク区間、「物理ネットワーク」＝「Externalネットワーク」と考えると、この説明が理解できるかと思います。また、「レイヤー3（ルーティング）サービス」＝GWルータが提供するルーティング機能、「DHCPサービス」＝Network Nodeに配置したDHCPサーバ機能と考えると辻褄があいます。

## (2) NAT接続
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/424a99c2-fcb7-e6cf-5a5b-85bb11a17d88.png)


GWルータとVMを直接L2で接続するのではなく、間に仮想的なルータ(相当のアドレス変換(NAT)機能)を挟んで接続する方法です。VirtualBoxやVMware Workstation PlayerのNAT接続に相当します。上図では、Network NodeにNAT機能を持たせました。この構成にすることで、GWルータのルート設定に縛られず、VMに任意のIPアドレスを割り当てることができるようになります。もしくは、"プロバイダーネットワークアーキテクチャー"では外部環境のため制御できなかったGWルータを「仮想ルータ」としてOpenStackの制御下においた構成、とも考えることができます。

この構成においては、ExternalネットワークはGWルータ～Network Nodeとなり、Network Node～Compute間は新規の物理ネットワーク「**ゲストネットワーク**」(図中ではGuest)になります。なお、図中ではGuest側にDHCPサーバ機能を配置しておらず、VMのIPアドレスはユーザ設定を想定していますが、External側と同様にDHCPサーバ機能を配置し、自動払い出しとすることも可能です。

この構成において、VMとユーザ(外部)との通信は、次のようにして実現されます。

* VM→ユーザ(外部)の通信：
NAT機能は、任意のIPアドレスが設定されたVMから出たパケットに対し、その送信元IPアドレスを仮想ルータの外側(External側)のネットワークに属するIPアドレスに書き換えます。これにより、レスポンスのパケットが戻ってくることができます。

* ユーザ(外部)→VMの通信：
NAT機能は、VMに割り当てられた任意のIPアドレスに対して、仮想ルータ外側(External側)ネットワークのIPアドレス(Floating IP)を1つ、払い出します。ユーザがFloating IPにアクセスした際、NAT機能が宛先IPアドレスをVMのものに書き換えることで、ユーザは所望のVMに接続することができます。

もともとの要件に設定していた、ユーザへの「VM接続先情報の提供」およびユーザから「VMへの接続」は、後者の機能(Floating IP)を使って実現することができます。

### セルフサービスネットワーク(Self-service Network)
この構成においては、「プロバイダーネットワーク」の範囲はGWルータ～仮想ルータまでとなります。仮想ルータ～VM間のL2ネットワーク[^selfservice]は、クラウドの利用者が自由に構築できるネットワーク、すなわち**「セルフサービスネットワーク」(Self-service Network)**になります。

[^selfservice]: 実際には、ゲストネットワーク上にVXLANやGREでoverlayすることによって仮想的なL2を作ることが一般的と思いますが、ここでは触れず、まとめて「L2ネットワーク」としておきます。

ここで、(2)NAT接続の構成図を見ると、OpenStackネットワークガイドに記載されている図とほぼ同等のものができあがっていることに気づきます。(「SDN Service Node」「Dashboard Node」は省略)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/b6c8911b-3b60-704d-57a4-0005a4120746.png)

このアーキテクチャが、**「セルフサービスネットワークアーキテクチャー」(Self-service Network Architecture)**・・・かというと、**そういうわけではない**ようです。OpenStack Installation Guideには以下のように記載されています。

OpenStack Installation Guide (Newton)
https://docs.openstack.org/newton/ja/install-guide-rdo/environment-networking.html
> セルフサービス (プライベート) ネットワークアーキテクチャーでは、インスタンスをセルフサービスネットワークとプロバイダーネットワークに接続できます。

セルフサービスネットワークだけでなく、プロバイダーネットワークにも接続できるのがセルフサービスネットワークアーキテクチャーとなっています。物理ネットワークインフラもこれに合わせて、(1)(2)を合わせた形に変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/791bbb4e-e0ac-a299-90e1-963b8a9fdbc6.png)

ExternalネットワークをComputeまでのばしました。これが、"セルフサービスネットワークアーキテクチャー"の場合の基本的なサーバ構成および物理ネットワークインフラになります。

# サンプルアーキテクチャーの意味
Installation Guideに記載がある「サンプルアーキテクチャー」は、セルフサービスネットワークアーキテクチャーをベースに簡略化(縮退化)させたものになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/ff2fd108-7cfe-9e51-b687-2a81dab8d2eb.png)

> このサンプルアーキテクチャーは、以下の点が最小限の本番アーキテクチャーと異なります。

> Networking エージェントは、専用のネットワークノードではなく、コントローラーノードで動作します。

> セルフサービスネットワークのオーバーレイ (トンネル) 通信は、専用ネットワークではなく管理ネットワークを通過します。

Network Nodeは省略し、機能はCloud Controller Node上に配置しました。また、ゲストネットワークは作らず、管理ネットワーク上を仮想ネットワークとして通るようにしました。

ただし、これで終わりではありません。

https://docs.openstack.org/newton/ja/install-guide-rdo/environment-networking.html

>すべてのノードで、パッケージインストール、セキュリティー更新、DNS、NTP などの管理目的でインターネットアクセスが必要です。多くの場合、ノードのインターネットアクセスは管理ネットワークインターフェース経由とすべきです。ネットワーク分離の重要性を強調するために、サンプルアーキテクチャーは、管理ネットワークに プライベートアドレス空間 を使用し、物理ネットワークインフラが NAT や他の方法によりインターネットアクセスを提供すると仮定します。

管理ネットワークはインターネットアクセスが必要だが、Externalネットワークとは分離すべきなので、物理ネットワークインフラ側でNATを挟むことにしてもらう、ということになります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586231/cf7b7edc-91ca-cc5a-1b65-90e11f7ef790.png)


# まとめ
IaaSを提供するためのシンプルな要件をベースに、OpenStackの「物理ネットワークインフラ」として何が想定されているか、また「プロバイダーネットワークアーキテクチャー」「セルフサービスネットワークアーキテクチャー」「サンプルアーキテクチャー」との関係について考えてみました。

# 参考
* OpenStack (Newton) Installation Guide (日本語)
https://docs.openstack.org/newton/ja/install-guide-rdo/

* OpenStack (Pike以降) Installation Guide (英語)
https://docs.openstack.org/install-guide/

* OpenStack Networking アーキテクチャ
https://docs.openstack.org/ja/security-guide/networking/architecture.html

* OpenStack ネットワークガイド
https://docs.openstack.org/ocata/ja/networking-guide/intro-os-networking.html

* OpenStack Neutronが作るNWの実体を追ってみよう
https://www.ntt-tx.co.jp/column/tec/180702/

* Provider Networkってなんぞ？
https://qiita.com/K5K/items/98de426eb68961742928

* Spot the difference: Tenant, provider and external Neutron networks
https://superuser.openstack.org/articles/spot-the-difference-tenant-provider-and-external-neutron-networks/