GCPのネットワークで構築するCluster構成、AWSとオンプレミスネットワークの違い

#はじめに
オンプレミス、AWS、GCPそれぞれの環境でクラスタ構成を構築する仕組みについて書きたいと思います。

結論としては、オンプレミスで一般的な仮想IPを使ってARPテーブルを変更することにより接続先を切り替える方式は、クラウドではARPそのものが使用できないため、利用できずAWSではRoute tableを使用して接続先を切り替えます。GCPでは、仮想IPの付け替えをクラスタの機能で実装すればクラスタ構成可能です。

#前提
この記事で想定している前提について記載させていただきます。

##この記事で想定しているClusterの仕組み
色々仕組みがあると思いますが、こちらで取り上げる方式は仮想IPを使い、障害発生時にStandbyノードに仮想IPをfailoverする仕組みについて取り上げたいと思います。以下のようなイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/abe5d864-13ff-b1d4-7445-d8346e9104bd.png)

10.0.0.8が仮想IP(VIP)として設定されており、Activeノードに障害が発生すると、ClusterソフトウェアによりStandbyノードに仮想IPの設定を実施し、自身のMacアドレスでARPテーブルを更新し、リクエストが自ノードに送信されるようにします。

参考:https://www.atmarkit.co.jp/ait/articles/0104/14/news003.html

##オンプレ、AWS、GCPのネットワークの違い
上記のようなARPテーブルを使った接続先の切り替えは、AWSやGCPといったクラウドで使用できません。

###AWSの場合
ARPリクエストが実行されると”Mapping Service”がリクエストを横取りし、宛先情報を”Mapping Service”から返信します

参考:https://codezine.jp/article/detail/9790

>
ゲストOSが送信先のIPアドレスからMACアドレスを得るためにARPリクエストを送信します。するとServerがすかさずリクエストを横取りし、Mapping Serviceに「VPC ID xxxx 内でIPアドレスが x.x.x.x のEC2インスタンスはどこのServerにいるのか？」と聞きに行きます。

このような仕様があるため、ARPテーブルを使ったfailoverが使えません。

###GCPの場合
GCPのVPCは、ソフトウェア定義ネットワーキングを使用しており、MACアドレスを使わない。そのため、GCPでもARPテーブルを使ったfailoverが使えません。

参考:https://cloud.google.com/compute/docs/tutorials/running-windows-server-failover-clustering

>
クラスタがフェイルオーバーした後、リクエストは新しくアクティブになったノードに送られる必要があります。クラスタリング技術は通常、アドレス解決プロトコル（ARP）を使用してルーティングを処理します。このプロトコルは IP アドレスと MAC アドレスを関連付けます。GCP の Virtual Private Cloud（VPC）システムはソフトウェア定義ネットワーキングを使用します。これは MAC アドレスを提供しません。つまり、ARP によってブロードキャストされた変更はルーティングにまったく影響しません。したがって、クラスタでルーティングを機能させるには、内部ロードバランサからソフトウェアレベルの支援を受ける必要があります。

##AWSにおけるクラスタ設計
参考：https://aws.amazon.com/jp/blogs/apn/making-application-failover-seamless-by-failing-over-your-private-virtual-ip-across-availability-zones/

AWSのVPCではAPRテーブルを使ったClusterが組めないため、Route Tableを使ってルーティング先を着替える方式が取れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/06f19190-9a11-57a2-e9c5-dee686cd8266.png)

上記の例では、仮想IPを10.1.5.5で構成し、クライアントから10.1.5.5に対してリクエストを送信します。そうすることでSubnetに紐付けられているRoute tableのルールに従いActiveノードにアタッチされたENI:AAAに対して通信されます。
Activeノード障害時は、Route tableを編集しStandbyノードのENI:BBBをターゲットに変更することでFailoverを実現します。
ポイントは仮想IPがVPCのレンジに入ってないことです。これはサブネットがAZごとに作成する必要があり、AZをまたいだfailoverする場合、SubnetのCIDRと被らないIPを指定する必要があるからです。

##GCPにおけるクラスタ設計
GCPもAWSと同じでARPテーブルを使ったFailoverは構成できません。ただしAWSと異なりGCPのVPCは、サブネットがZoneをまたぐことができます。つまり、Route tableで宛先を切り替えるといった処理が不要で、Multi Zoneで同じCIDRの中で仮想IPの付け替えが可能です。

違いを整理すると以下になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/ab258fc5-3848-1236-ea74-f8bd71622283.png)

###GCPでWindows clusterを作成する
参考：https://www.draw.io/#G1t4v_xPEqubQ_EzESs0RhNKvKAXOvkkzn

上記マニュアルを参考にしてWindows clusterを作成してみます。

まずは何もリソースがない単純なクラスタを作成します。
仮想IPとして、クラスタに10.0.0.8を設定しています。10.0.0.7はWindows Native Clusterの前提となるActive Directoryを構成するためのDomain Controllerとなります。また、障害時のwitness用として今回はFile共有方式を取るため、sharing用のサーバにもなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/68593498-f6f9-c300-147e-c1bceec0fc1d.png)

IPアドレスの予約状況を確認します。

```
$ gcloud compute addresses list
NAME                             ADDRESS/RANGE  TYPE      PURPOSE       NETWORK  REGION       SUBNET       STATUS
google-managed-services-default  10.39.96.0/20  INTERNAL  VPC_PEERING   default                            RESERVED
cluster-access-point             10.0.0.8       INTERNAL  GCE_ENDPOINT           us-central1  wsfcnetsub1  RESERVED
```

wsfc-1でのipconfigを確認してみます。

```
PS C:\Users\matsushi> ipconfig

Windows IP Configuration


Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::9593:91f7:3ba9:e52c%3
   IPv4 Address. . . . . . . . . . . : 10.0.0.4
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   IPv4 Address. . . . . . . . . . . : 10.0.0.8
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   Default Gateway . . . . . . . . . : 10.0.0.1
```

同じNICにIPが2つ設定されています。

GCPのコンソールで見ると1つになります。Subnet内でIPアドレスは予約しているが、インスタンスのNICにはGCPレイヤーではアタッチされていないことが確認できます。

```
$ gcloud compute instances list
NAME                                         ZONE               MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP           EXTERNAL_IP      STATUS
wsfc-1                                       us-central1-a      n1-standard-2               10.0.0.4              34.69.219.210    RUNNING             
```

さらに、クラスタのリソースとしてIISを構築してきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/40e95227-0e6c-d9e9-5090-d1d668d7cfb9.png)


10.0.0.9がIISにアクセスするための仮想IPになります。
LBが必要な理由は、IISのヘルスチェックとクライントから見た接続先のIFになります。
gcloudコマンドの表示でもわかるように、10.0.0.9はWindowsクラスタ上での管理さており、TCPロードバランサーを使って仮想IPを持っているノードにリクエストがフォワードされます。さらに、インスタンス作成時にcan-ip-forwardが指定されているため、ノード内でforwardされ仮想IPで動作しているIISにアクセスできます。

以下がインスタンス作成用のコマンド。

```
gcloud compute instances create wsfc-1 --zone [YOUR_ZONE_1] --machine-type n1-standard-2 --image-project windows-cloud --image-family windows-2016 --scopes https://www.googleapis.com/auth/compute --can-ip-forward --private-network-ip 10.0.0.4 --network wsfcnet --subnet wsfcnetsub1 --metadata enable-wsfc=true
```

ここでIPアドレスの予約を確認します。

```
$ gcloud compute addresses list
NAME                             ADDRESS/RANGE  TYPE      PURPOSE       NETWORK  REGION       SUBNET       STATUS
google-managed-services-default  10.39.96.0/20  INTERNAL  VPC_PEERING   default                            RESERVED
cluster-access-point             10.0.0.8       INTERNAL  GCE_ENDPOINT           us-central1  wsfcnetsub1  RESERVED
load-balancer-ip                 10.0.0.9       INTERNAL  GCE_ENDPOINT           us-central1  wsfcnetsub1  RESERVED
```

この状態でwsfc-1でのipconfigを確認してみます。IIS用の仮想IPがノードに付与されています。

```
PS C:\Users\matsushi> ipconfig

Windows IP Configuration


Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::9593:91f7:3ba9:e52c%3
   IPv4 Address. . . . . . . . . . . : 10.0.0.4
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   IPv4 Address. . . . . . . . . . . : 10.0.0.8
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   IPv4 Address. . . . . . . . . . . : 10.0.0.9
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   Default Gateway . . . . . . . . . : 10.0.0.1
```

この状態で、10.0.0.9にアクセスするとIISのデフォルトページが表示されます。wsfc-1を停止するとwsfc−2にFailoverされます。

##Failoverの仕組み
各コンポーネントの役割

###Compute Engine Agent
GCEインスタンスで実行されるエージェント。GCEインスタンス上のVIPを管理し、LBからのヘルスチェックに応答する。

###ロードバランサー(LB)
VIP宛の通信の受口とヘルスチェック機能を提供する

###Windows failover cluster
クラスタ機能を提供

###Failoverの流れ
Windows failover clusterが障害を検知
VIPをStandbyノードに移動させる
StandbyエージェントがヘルスチェックにOKを返す
LBがリクエストのフォワード先を変更する

##参考
AWS VPC
https://codezine.jp/article/detail/9790

GCP windows cluster
https://www.draw.io/#G1t4v_xPEqubQ_EzESs0RhNKvKAXOvkkzn

オンプレミスシステムのCluster
https://www.atmarkit.co.jp/ait/articles/0104/14/news003.html