GKE試行（その3：「クラスタ作成」）

# お題
[前回](https://qiita.com/sky0621/items/4d27f979199a9ea1efa4)は作成した[適当に作ったアプリ](https://github.com/sky0621/go-webapi-for-gke-study)をGitHubから[Cloud Source Repositories](https://cloud.google.com/source-repositories/)に連携し、[Cloud Build](https://cloud.google.com/cloud-build/)を使ってDockerイメージをビルドして[Container Registry](https://cloud.google.com/container-registry/)にプッシュするところまでやった。
今回は、いよいよGKE上で動かすところまで。いけるかな・・・？

# 環境
[前回](https://qiita.com/sky0621/items/2faf4f7e6b2c9b269945#環境)と同じ。

# 前提
- 自前でGCPプロジェクトは契約済み
- gcloudをローカルで使える状態になっている

# 実践
## １）GKEクラスタ作成　→　*失敗*
手順として、GKEで一番大きな「箱」である「クラスタ」を作る。
クラスタは概念・・・なのか？
以下に「Kubernetes Engine クラスタとは、Kubernetes を実行する Compute Engine インスタンスのグループです。」とあった。
https://cloud.google.com/kubernetes-engine/docs/clusters/?hl=ja
なるほど。
「クラスタ　＝　GCEインスタンスグループ」

ということは、クラスタを作ると、中にいくつかの「GCEインスタンス」を作ることになるんだろうな。
インスタンスグループについては以下に説明がある。
https://cloud.google.com/compute/docs/instance-groups/creating-groups-of-managed-instances?hl=ja
「マネージドインスタンスグループは自動スケーリング、負荷分散、ローリング更新などをサポート」

”自動スケーリング”するみたい。以下にも説明がある。
https://cloud.google.com/compute/docs/autoscaler/?hl=ja

**　１クラスタには複数のGCEインスタンスが含まれ、自動スケーリングする**

はい、とりあえずここまでの理解で、いったんクラスタ作ってしまおう。
クラウドコンソールとgcloudコマンドによる２通りの方法それぞれ試してみる。
https://cloud.google.com/kubernetes-engine/docs/clusters/operations?hl=ja

### １−１）クラウドコンソールでGKEクラスタ作成
![01.png](https://qiita-image-store.s3.amazonaws.com/0/180599/79ffae5a-1403-f64f-bc77-e8fd785faa1e.png)
![02.png](https://qiita-image-store.s3.amazonaws.com/0/180599/88a8087b-ff29-0ce6-7eb4-9230cd93eb3d.png)

あれっ？　また、権限かな？
gcloudコマンドの方も試してみよう。
最低限のオプションでクラスタ作成を試みる。チュートリアルでは、クラスタ名とゾーンを渡しているので真似る。
いつも忘れてしまうゾーン。↓に一覧が載っている。
https://cloud.google.com/compute/docs/regions-zones/?hl=ja

以下のように、自分がローカルでgcloudコマンド使って初期設定した時にリージョンをどう設定したかは確認できる。
<pre>
koge@koge-W65-67SF:~$ gcloud config list
[compute]
region = asia-northeast1
[core]
account = 【アカウントに使っているメアド】@gmail.com
disable_usage_reporting = False
project = 【プロジェクトID】

Your active configuration is: [default]
</pre>
「asia-northeast1」は a 〜 c のどれかを付けた名前でゾーンが存在する。

さあ、gcloudコマンドでのクラスタ生成を試してみよう。
<pre>
koge@koge-W65-67SF:~$ gcloud container clusters create go-webapi-for-gke-study-clusters --zone asia-northeast1-a
WARNING: Starting in 1.12, new clusters will have basic authentication disabled by default. Basic authentication can be enabled (or disabled) manually using the `--[no-]enable-basic-auth` flag.
WARNING: Starting in 1.12, new clusters will not have a client certificate issued. You can manually enable (or disable) the issuance of the client certificate using the `--[no-]issue-client-certificate` flag.
WARNING: Currently VPC-native is not the default mode during cluster creation. In the future, this will become the default mode and can be disabled using `--no-enable-ip-alias` flag. Use `--[no-]enable-ip-alias` flag to suppress this warning.
This will enable the autorepair feature for nodes. Please see
https://cloud.google.com/kubernetes-engine/docs/node-auto-repair for more
information on node autorepairs.

WARNING: Starting in Kubernetes v1.10, new clusters will no longer get compute-rw and storage-ro scopes added to what is specified in --scopes (though the latter will remain included in the default --scopes). To use these scopes, add them explicitly to --scopes. To use the new behavior, set container/new_scopes_behavior property (gcloud config set container/new_scopes_behavior true).
ERROR: (gcloud.container.clusters.create) ResponseError: code=403, message=Google Compute Engine: Required 'compute.networks.get' permission for 'projects/【プロジェクトID】/global/networks/default'.
</pre>
うん、「compute.networks.get」権限がないのでダメとのこと。
[前回](https://qiita.com/sky0621/items/4d27f979199a9ea1efa4#１まずはもともとリポジトリに用意してあるdockerfileを使ってビルドそしてgcrにプッシュ)は、「サービスアカウント「○○」にビルド権限がない」というエラーだったので、指定されたサービスアカウントにIAMで権限を付与して解決した。
今回は、どのサービスアカウントがって指定されない。困った。

#### トラブルシューティング
ぐぐると、IAMポリシーを確認しろとあった。
<pre>
koge@koge-W65-67SF:~$ gcloud projects get-iam-policy 【プロジェクトID】
bindings:
- members:
  - serviceAccount:806987825204@cloudbuild.gserviceaccount.com
  role: roles/cloudbuild.builds.builder
- members:
  - serviceAccount:projectowner@【プロジェクトID】.iam.gserviceaccount.com
  - user:【アカウントに使っているメアド】@gmail.com
  role: roles/owner
</pre>
前回に続き再び登場の「806987825204」。
前回与えたロール「cloudbuild.builds.builder」のみだから、ここに「compute.networks.get」（そもそもこれはロール？）を追加すればいいんだろうか。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/180599/a5f957fc-6391-99f3-a162-1d8e8aa1d425.png)
いったん「Compute管理者」を付けてみた。

リトライ
<pre>
koge@koge-W65-67SF:~$ gcloud container clusters create go-webapi-for-gke-study-clusters --zone asia-northeast1-a
　　〜〜〜
ERROR: (gcloud.container.clusters.create) ResponseError: code=403, message=Google Compute Engine: Required 'compute.networks.get' permission for 'projects/【プロジェクトID】/global/networks/default'.
</pre>
ダメだった。試しにプロジェクトのオーナーロールを付与してみてもダメだった。
そういう問題ではないらしい・・・。

そして、ぐぐっては試しのトライ＆エラーを繰り返した後、あきらめて別プロジェクトを作ることにした。。。
業務でやってたら、あきらめるという選択肢はないけど、プライベートであまりにも本筋でないところでハマるとやる気なくなるので。

## ２）別プロジェクトにて再度GKEクラスタ作成
### ２−１）クラウドコンソールでGKEクラスタ作成
![r01.png](https://qiita-image-store.s3.amazonaws.com/0/180599/25bbda56-a0b7-4a5a-b3d3-fd10cde78292.png)
![r02.png](https://qiita-image-store.s3.amazonaws.com/0/180599/5ed7c794-8ee4-9ab9-ce91-9a1b6df0c180.png)
![r03.png](https://qiita-image-store.s3.amazonaws.com/0/180599/d5d7dd5f-b33c-9896-5d1e-8f3c088c10bb.png)

**　来たっ！**

あ〜、完全に前のGCPプロジェクトでいろいろいじり過ぎていたせいだ・・・。
よくよく考えるとネットワーク周りをいろいろ消したりもした気が・・・。
完全に無駄な数時間を・・・。

気を取り直して。
各項目を設定していく前にGKEのクラスタについて、おさらい。
「クラスタ　＝　GCEインスタンスグループ」
なので、クラスタの中には複数のGCEインスタンスが含まれる。
このGCEインスタンスのことをGKEでは「ノード」と呼ぶ。
クラスタ作成のメニューとは、そこに含むGCEインスタンスのスペックをどうするか、
GCEインスタンス（＝ノード）をいくつ起動するかを決めるものということか。

ちなみに、クラスタのアーキテクチャについては以下参照。
https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-architecture?hl=ja

では、クラスタ作成メニュー。項目別に。

#### 【クラスタ名】
![r04.png](https://qiita-image-store.s3.amazonaws.com/0/180599/d0ed3aa5-ca98-4c70-bbc3-bc06ba2b6394.png)
特に言及することは無し。

#### 【ロケーションタイプ　〜　ノードプール　〜　可用性】
#### [ゾーン]
ここはロケーションタイプで「ゾーン」を選択するか「リージョン」を選択するかで変わるので一括して扱う。
![r05.png](https://qiita-image-store.s3.amazonaws.com/0/180599/52e52562-ee67-c50a-9291-1d6ff48194af.png)
デフォルトでは「ゾーン」。つまり、１ゾーンを指定し、その中で複数のノード（＝GCEインスタンス）を立ち上げる。
なので、ゾーン障害が起きたらアウト。
![r06.png](https://qiita-image-store.s3.amazonaws.com/0/180599/9b68efb3-b086-acaf-e60b-45900ee1268f.png)
「ノードプール」で指定するノード数も単純にいくつノード（＝GCEインスタンス）を立ち上げておくかの指定となる。
ノードプールについては以下に説明がある。
https://cloud.google.com/kubernetes-engine/docs/concepts/node-pools?hl=ja

さて、「ノードプールを追加」というのが気になる。
ノードプールでは複数の同じ構成のノードを用意するものらしい。
深みに嵌りそうなのでまだ考えない方がいい気がするけど、実際にアプリを乗せる場合、１つのWebアプリだけなら１つのノードプールで事足りるだろうけど、
マイクロサービスでシステム作ってたりすると複数のサービスをそれぞれコンテナイメージにしているから、
そうなると、１つのノードプールでは事足りず、サービス毎にノードプールを用意するという感じになるのか・・・？
![r07.png](https://qiita-image-store.s3.amazonaws.com/0/180599/0855b3be-d40c-2ac0-4131-ccd3665df642.png)
単一のゾーンではゾーン障害に弱いので複数のゾーンを利用するように設定するもの。（ただ、当然、同じリージョン内に限る）
https://cloud.google.com/kubernetes-engine/docs/concepts/multi-zone-and-regional-clusters?hl=ja&_ga=2.6685618.-1642231062.1533503848

あと、ノードプール数、マルチゾーンにするかどうか、このあたりが立ち上がるGCEインスタンス数に直結するので、当然、かかるお金も変わってくる。

#### [リージョン]
![r05b.png](https://qiita-image-store.s3.amazonaws.com/0/180599/a2b5bb2f-6cfe-64c5-a8cb-d6b6552ca65c.png)
![r06b.png](https://qiita-image-store.s3.amazonaws.com/0/180599/1214f3fb-9cb3-84a1-8e0a-303cdf622700.png)
![r07b.png](https://qiita-image-store.s3.amazonaws.com/0/180599/26e1ef47-253f-be3d-f4e9-9214309306e2.png)
「ゾーン」と異なり、最初から同一リージョンの複数ゾーンにノードを用意する前提なので、そのような設定の仕方になる。
可用性の部分はデフォルトではチェック無しになっていて、その場合は全ゾーンを対象とする。

#### マルチゾーンクラスタとリージョンクラスタの違い
どちらも同一リージョン内に限る点は同じだし、複数のゾーンにノードを配置できる点も同じ。
違いは、「クラスタマスター」の作成数。
クラスタマスターは、クラスタ内の全ノードと通信し、ノード内のアプリ（Dockerコンテナ）のスケジューリング、ライフサイクル管理、スケーリング、アップグレードを管理するコントローラー役。
https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-architecture?hl=ja#master
そのクラスタマスターを１ゾーンにだけ配置するのが「マルチゾーンクラスタ」で、ゾーンすべてに配置するのが「リージョンクラスタ」。
https://cloud.google.com/kubernetes-engine/docs/concepts/multi-zone-and-regional-clusters?hl=ja

#### 作成
他にもいろいろ調べた上で設定すべき項目があったけど、そこは後で調べるとしてデフォルトのまま作成実行。
![r08.png](https://qiita-image-store.s3.amazonaws.com/0/180599/a97ed8a2-3576-01fa-4fae-af0854842c8d.png)
できたので、接続してみる。
![r09.png](https://qiita-image-store.s3.amazonaws.com/0/180599/c7ac615a-4732-32f5-a346-aabfaf2ccb35.png)
![r10.png](https://qiita-image-store.s3.amazonaws.com/0/180599/51be8153-b21f-7f59-343c-7c7710f01b13.png)

#### 後始末
今日は残念ながら、GKE上にアプリを乗せて動かすというところまではいけないので、インスタンスが立ち上がりっぱなしにならないよう、GKEクラスタごと消しておく。
![r11.png](https://qiita-image-store.s3.amazonaws.com/0/180599/9e91a8bf-d1d0-38dd-4baf-490e35b4d770.png)
![r12.png](https://qiita-image-store.s3.amazonaws.com/0/180599/f3d75a5d-124c-f4ba-197c-aa2b6ccb0dba.png)


### ２−２）gcloudコマンドでGKEクラスタ作成
時間の都合で省略。

# まとめ
そもそもクラスタ作れないという問題にハマり、目的を果たせぬまま時間オーバー。
クラスタは作れるところまでいけたので、次回こそはアプリ乗せよう。。。