GKEのデプロイ時に中の人がやってることを絵にしてみた


GKEを触り始めて日が浅いですが、ちょっとだけ、GKE とか Kubernetes の仕組みに興味を持ちました。
でも、**文字だけだと、イメージしづらい！**
、、、というわけで、以下の公式チュートリアルに沿って、実際にどんな動きをしているか、というのを自分なりに絵にしてみました。
[チュートリアル：コンテナ化されたウェブアプリのデプロイ](https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app?hl=ja)

**ここ違うよ！とかあったらぜひご指摘いただけたら嬉しいです！**

#前提
**Container Registry にコンテナがUPされていること**
　→実際にGKEにデプロイされるタイミングでどんなことが起こっているか、をわかりやすくしたかっただけなので。実際にローカルのコンテナから動かしてみたい、という方はチュートリアルをご参照くださいませ。

**コマンドに関してある程度の知識があればなおOK**
　→ぶっちゃけ、あんまり知らなくてもいいのですけど、説明があっさりしているところもあるかと思いますので、簡単に何やってるかわかると読みやすいかも。。。（詳細は上記[チュートリアル](https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app?hl=ja)を参考にしていただけるといいかもです。



#1. クラスタの作成
```console
$ gcloud container clusters create hello-cluster --num-nodes=3
```
`gcloud`　：　GKEが実行するコマンドで、クラスタの操作を行います。
　　　　　　　（ここではクラスタ作成）
`--num-nodes`：作成するノードの数を設定するオプション。

ノードは、GCEインスタンス として作成されます。
クラスタが作成されると、ノードの他にクラスタマスターも作成されます。
クラスタマスターについては、公式に以下の通りに記載されています。

>
クラスタは少なくとも 1 つのクラスタ マスターと、ノードと呼ばれる複数のワーカーマシンで構成されます。
**クラスタ マスター**
クラスタ マスターは、Kubernetes API サーバー、スケジューラ、コアリソース コントローラといった Kubernetes コントロール プレーンのプロセスを実行します。マスターのライフサイクル管理は GKE が行い、**クラスタの作成または削除のタイミングを管理**します。クラスタ マスター上で実行される **Kubernetes バージョンのアップグレード**も、管理の対象に含まれます。アップグレードは GKE が自動的に行いますが、自動スケジュールに先立って手動でアップグレードすることもできます。
>

＜コマンドでやってること＞
①　GKE　：　クラスタ（クラスタマスター）の作成
②　GKE　：　クラスタ内に指定された数のノードを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/56e29451-5622-9094-cb9f-3f63073f3405.png)


ちなみに、以下のコマンドを実行すると、ノード分のGCEインスタンスが作成されていることが確認できます。

```console
$ gcloud compute instances list
NAME                                          ZONE               MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP     STATUS
gke-hello-cluster-default-pool-xxxxxxxx-96xs  us-central1-b      n1-standard-1               10.128.0.4   35.225.xxx.xxx  RUNNING
gke-hello-cluster-default-pool-xxxxxxxx-pctm  us-central1-b      n1-standard-1               10.128.0.3   35.223.xxx.xxx  RUNNING
gke-hello-cluster-default-pool-xxxxxxxx-r8dr  us-central1-b      n1-standard-1               10.128.0.2   35.193.xxx.xxx    RUNNING
```

#2.アプリケーションのデプロイ
##2-1.Deploymentの作成
>
下記の kubectl run コマンドを実行すると、Kubernetes がクラスタに hello-web という名前の Deployment を作成します。Deployment は、レプリカと呼ばれるアプリケーションの複数のコピーを管理し、クラスタ内の個々のノード上で実行するようにスケジューリングします。今回の場合、Deployment ではアプリケーションの 1 つのポッドのみが実行されます。
>

```
$ kubectl create deployment hello-web --image=gcr.io/${PROJECT_ID}/hello-app:v1
```

＜コマンドでやってること＞
①　クラスタマスター：　`--image`にて指定された dockerイメージ を使って POD を作成
②　クラスタマスター：　①で作成した POD を利用して Deployment を作成
③　Deployment　：　POD を各ノードにばらまく

PODの管理はDeploymentの仕事になるんですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/66ef3d16-4720-3297-6312-aeeaf4ed60ed.png)



##2-2.インターネットへの公開
デフォルトの状態だと、GKEで動作するコンテナは外部からアクセスできません。
理由はExternalIP（外部IP）が公開されていないから。
というわけで、以下のコマンドを実行します。

```console
kubectl expose deployment hello-web --type=LoadBalancer --port 80 --target-port 8080
```
>
上記の kubectl expose コマンドは、アプリケーションのポッドにネットワーキングと IP サポートを提供する Service リソースを作成します。GKE は、アプリケーションの外部 IP とロードバランサ（課金対象）を作成します。
`--port` フラグには、フラグはロードバランサで構成されたポート番号を指定します。`--target-port` フラグには、hello-app コンテナがリッスンするポート番号を指定します。>

＜コマンドでやってること＞
①　クラスタマスター：Service の作成
②　GKE　：　ExternalIP を取得し、Service に設定
③　GKE　：　Service に LoadBalancer作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/bf7662dc-e2e8-6fa0-7a2b-a01fb2bd5483.png)


作成したserviceの内容を確認したいときは以下のコマンドで。

```console
$ kubectl get service
NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
hello-web    10.3.251.122    203.0.xx.xx     80:30877/TCP     3d
```


アクセスした場合はこんなイメージになるのかな？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/92ca116b-ccdf-bf2d-ff34-ddfed77e6260.png)

①「http://302.0.xx.xx」 にアクセスする。
　→外部からのportは 80

②Serviceがリクエストの振り分けを行う。
　→クラスタ内部のアクセスportは 8080
  　（podにてアクセスポートが８０８０に指定されている）



#まとめ
というわけで、中でどんなことが行われているのか、を理解したくて、ドキュメント読みつつ絵にしてみたわけですが。

- **実はクラスタマスターが結構仕事している**（GKEだけだとあまり意識しないけど）

- **クラスタの作成とかクラスタに関するところは`gcloud`コマンドを使うけど、クラスタ内部の操作はクラスタマスターが実行するので`kubectl`を使う**

- 内部では Deployment と Service が仕事してる
- PODの管理はDeploymentの仕事
- ネットワーク周りはServiceの仕事

ってことが今回の「へぇ〜」でした。

ちなみに、実際のデプロイだと、Deployment、Service共にyamlを作成してそこから作成することが多そうです。

色々調べていくと奥が深そうですが、仕組みを知るとなんでこの時にこのコマンド？とか、挙動がおかしい時に「ここが怪しいかも」とあたりをつけたりできそうなので、いろんな動きを調べてみたいなーと思いました。

なので、「正確には〜」とか「ここ違う」のご指摘大歓迎です！！


#参考
https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-architecture?hl=ja