GCPチュートリアル試行「ネットワーク負荷分散」

# お題
表題のチュートリアルを試しにやってみる。

【参照】
https://cloud.google.com/compute/docs/load-balancing/network/example?hl=ja

# 前提
- GCP環境は保持済み。
- ```gcloud```コマンドインストール済み。

# 試行
## 1) GCEインスタンス作成
<pre>
$ gcloud compute instances create www1 \
>     --image-family debian-8 \
>     --image-project debian-cloud \
>     --zone us-central1-b \
>     --tags network-lb-tag \
>     --metadata startup-script="#! /bin/bash
>       sudo apt-get update
>       sudo apt-get install apache2 -y
>       sudo service apache2 restart
>       echo '<!doctype html><html><body><h1>www1</h1></body></html>' | tee /var/www/html/index.html
>       EOF"
ERROR: (gcloud.compute.instances.create) Could not fetch resource:
 - The resource 'projects/debian-cloud/global/images/family/debian-8' was not found
</pre>
いきなりつまづいた。が、「debian-8」が見つからないというメッセージから「debian-9」を試してみることにする。
<pre>
$ gcloud compute instances create www1 \
>     --image-family debian-9 \
>     --image-project debian-cloud \
>     --zone us-central1-b \
>     --tags network-lb-tag \
>     --metadata startup-script="#! /bin/bash
>       sudo apt-get update
>       sudo apt-get install apache2 -y
>       sudo service apache2 restart
>       echo '<!doctype html><html><body><h1>www1</h1></body></html>' | tee /var/www/html/index.html
>       EOF"

Created [https://www.googleapis.com/compute/v1/projects/fs-work-1978/zones/us-central1-b/instances/www1].
NAME  ZONE           MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP     STATUS
www1  us-central1-b  n1-standard-1               10.128.0.2   xxx.xxx.xx.xxx  RUNNING
</pre>
成功した。同じ手順で、あと２インスタンス立ち上げると、クラウドコンソールで下記のようになっている。
![01.png](https://qiita-image-store.s3.amazonaws.com/0/180599/e885572b-e054-e7d6-a3d1-4ada966a8870.png)
<pre>
$ gcloud compute instances list
NAME  ZONE           MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP     STATUS
www1  us-central1-b  n1-standard-1               10.128.0.2   xxx.xxx.xx.xxx  RUNNING
www2  us-central1-b  n1-standard-1               10.128.0.3   xx.xxx.x.xxx    RUNNING
www3  us-central1-b  n1-standard-1               10.128.0.4   xx.xxx.xxx.xxx  RUNNING
</pre>
curlでアクセス。
<pre>
$ curl http://xx.xxx.x.xxx
curl: (7) Failed to connect to xx.xxx.x.xxx port 80: 接続がタイムアウトしました
</pre>
つながらない。pingは通るのだけど。
<pre>
$ ping xxx.xxx.xx.xxx
PING xxx.xxx.xx.xxx (xxx.xxx.xx.xxx) 56(84) bytes of data.
64 bytes from xxx.xxx.xx.xxx: icmp_seq=1 ttl=55 time=167 ms
64 bytes from xxx.xxx.xx.xxx: icmp_seq=2 ttl=55 time=169 ms
64 bytes from xxx.xxx.xx.xxx: icmp_seq=3 ttl=55 time=139 ms
</pre>

## 2) ファイアウォールルール作成
チュートリアル記載の通り、外部トラフィックからGCEインスタンスの特定ポートにつながるようにする。
<pre>
$ gcloud compute firewall-rules create www-firewall-network-lb --target-tags network-lb-tag --allow tcp:80
Creating firewall...⠛Created [https://www.googleapis.com/compute/v1/projects/【プロジェクトID】/global/firewalls/www-firewall-network-lb].
Creating firewall...done.                                                                                                       
NAME                     NETWORK  DIRECTION  PRIORITY  ALLOW   DENY  DISABLED
www-firewall-network-lb  default  INGRESS    1000      tcp:80        False
</pre>
![04.png](https://qiita-image-store.s3.amazonaws.com/0/180599/11b50d2a-8b7c-4330-0dc9-904910d88a9b.png)

そして、curl再び。
<pre>
$ curl http://xxx.xxx.xx.xxx
\<!doctype html\>\<html\>\<body\>\<h1\>www1\</h1\>\</body\>\</html\>
$ 
$ curl http://xx.xxx.x.xxx
\<!doctype html\>\<html\>\<body\>\<h1\>www2\</h1\>\</body\>\</html\>
$ 
$ curl http://xx.xxx.xxx.xxx
\<!doctype html\>\<html\>\<body\>\<h1\>www3\</h1\>\</body\>\</html\>
</pre>
つながった。のだけど、疑問いろいろ。
作ったファイアウォールルールの適用範囲は？　特にインスタンスのIPなど指定するでもなかったのだけど、GCPプロジェクト全体？
ドキュメント確認。
https://cloud.google.com/vpc/docs/firewalls?hl=ja
読んでみると、VPCネットワークも絡むことがわかる。
https://cloud.google.com/vpc/docs/vpc?hl=ja
　
VPCは仮想化ネットワーク。１プロジェクトに複数のVPCネットワークを設定可能。
VPCについては以前、[別のチュートリアル試行](https://qiita.com/sky0621/items/15634150c0099ef8e609)でやってみた。
【特性】
・VPCは、ファイアウォールも含め”グローバル”なりソース。
・GCEインスタンス間のトラフィックはファイアウォールルールで制御する。
　
なるほど。ちなみにファイアウォール作成に使ったgcloudコマンドについては下記参照。
https://cloud.google.com/sdk/gcloud/reference/compute/firewall-rules/create?hl=ja

## 3) 負荷分散に使用する静的外部 IP アドレスを作成
<pre>
$ gcloud compute addresses create network-lb-ip-1 --region us-central1
Created [https://www.googleapis.com/compute/v1/projects/【プロジェクトID】/regions/us-central1/addresses/network-lb-ip-1].
</pre>
![03.png](https://qiita-image-store.s3.amazonaws.com/0/180599/1f635774-8db7-22a7-774d-5c3babe2ca00.png)

静的外部IPアドレスはリージョンリソースらしい。
【参考】https://cloud.google.com/sdk/gcloud/reference/compute/addresses/create?hl=ja
　
ふと、「ネットワーク階層」という欄の「プレミアム」というのが気になった。gcloudでは、そんな指定していないので。
https://cloud.google.com/network-tiers/?hl=ja
「ネットワーク階層」には「プレミアム」と「スタンダード」がある。
「プレミアム」は「Google のグローバル ネットワークを使用して、非常に高いネットワーク パフォーマンスをユーザーに提供します。」で”デフォルト”の階層とのこと。
「スタンダード」は「他のクラウド プロバイダと同等のパフォーマンスを提供しながら、ネットワークのコストを抑えます。」とある。

## 4) HTTPヘルスチェック追加
<pre>
$ gcloud compute http-health-checks create basic-check
Created [https://www.googleapis.com/compute/v1/projects/【プロジェクトID】/global/httpHealthChecks/basic-check].
NAME         HOST  PORT  REQUEST_PATH
basic-check        80    /
</pre>
![02.png](https://qiita-image-store.s3.amazonaws.com/0/180599/b9e7ac0f-01f9-994f-87fa-17eafee19317.png)

ヘルスチェックオブジェクトはグローバルリソースらしい。

## 5) ターゲットプール作成とGCEインスタンスの追加
<pre>
$ gcloud compute target-pools create www-pool --region us-central1 --http-health-check basic-check
Created [https://www.googleapis.com/compute/v1/projects/【プロジェクトID】/regions/us-central1/targetPools/www-pool].
NAME      REGION       SESSION_AFFINITY  BACKUP  HEALTH_CHECKS
www-pool  us-central1  NONE                      basic-check
</pre>
ターゲットプールはリージョンリソース。作成時にヘルスチェックの指定が必須とのこと。
　
そして、冒頭で作成したGCEインスタンス群をターゲットプールに追加。
<pre>
$ gcloud compute target-pools add-instances www-pool --instances www1,www2,www3 --instances-zone us-central1-b
Updated [https://www.googleapis.com/compute/v1/projects/【プロジェクトID】/regions/us-central1/targetPools/www-pool].
</pre>

## 6) 転送ルールの作成
<pre>
$ gcloud compute forwarding-rules create www-rule --region us-central1 --ports 80 --address network-lb-ip-1 --target-pool www-pool 
Created [https://www.googleapis.com/compute/v1/projects/【プロジェクトID】/regions/us-central1/forwardingRules/www-rule].
</pre>

## 7) 転送ルールの外部IPを検索
<pre>
$ gcloud compute forwarding-rules describe www-rule --region us-central1
IPAddress: xx.xxx.xxx.xxx
IPProtocol: TCP
creationTimestamp: '2018-09-18T07:52:11.124-07:00'
description: ''
id: '6314926843158638580'
kind: compute#forwardingRule
loadBalancingScheme: EXTERNAL
name: www-rule
networkTier: PREMIUM
portRange: 80-80
region: https://www.googleapis.com/compute/v1/projects/【プロジェクトID】/regions/us-central1
selfLink: https://www.googleapis.com/compute/v1/projects/【プロジェクトID】/regions/us-central1/forwardingRules/www-rule
target: https://www.googleapis.com/compute/v1/projects/【プロジェクトID】/regions/us-central1/targetPools/www-pool
</pre>

## 8) curlで確認
<pre>
$ curl http://xx.xxx.xxx.xxx
&lt;!doctype html&gt;&lt;html&gt;&lt;body&gt;&lt;h1&gt;www3&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
$ 
$ curl http://xx.xxx.xxx.xxx
&lt;!doctype html&gt;&lt;html&gt;&lt;body&gt;&lt;h1&gt;www3&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
$ 
$ curl http://xx.xxx.xxx.xxx
&lt;!doctype html&gt;&lt;html&gt;&lt;body&gt;&lt;h1&gt;www3&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
$ 
$ curl http://xx.xxx.xxx.xxx
&lt;!doctype html&gt;&lt;html&gt;&lt;body&gt;&lt;h1&gt;www1&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
$ 
$ curl http://xx.xxx.xxx.xxx
&lt;!doctype html&gt;&lt;html&gt;&lt;body&gt;&lt;h1&gt;www1&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
$ 
$ curl http://xx.xxx.xxx.xxx
&lt;!doctype html&gt;&lt;html&gt;&lt;body&gt;&lt;h1&gt;www1&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
$ 
$ curl http://xx.xxx.xxx.xxx
&lt;!doctype html&gt;&lt;html&gt;&lt;body&gt;&lt;h1&gt;www1&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
$ 
$ curl http://xx.xxx.xxx.xxx
&lt;!doctype html&gt;&lt;html&gt;&lt;body&gt;&lt;h1&gt;www2&lt;/h1&gt;&lt;/body&gt;&lt;/html&gt;
</pre>
一定の割合でwww1〜www3がランダムでアクセスされる。