DockerはわかってるけどKubernetesはそうでもない時に最初にやるチュートリアル


# 今日の教科書

今日の教科書は、[コンテナ化されたウェブ アプリケーションのデプロイ](https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app?hl=ja)です。

`Docker` はわかってるけど `kubernetes` はそんなでもない、という時に、まずにやればいいチュートリアルはこれだと思う。コンテナイメージつくるところから、クラスタへのデプロイ、そしてローリングアップデートまでクラスタの世界を短時間で覗き見ることができるのでおすすめ


# サンプルコードを落としてくる

```shell

$ git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
$ cd kubernetes-engine-samples/hello-app
```
```
$ cd kubernetes-engine-samples/hello-app
```

# 環境変数の設定

```shell

$ export PROJECT_ID=$(gcloud config get-value project)
```

# コンテナをビルド

教科書はローカルの`docker`でビルドしているが、ここでは`Cloud Build`を使う

```shell

$ gcloud builds submit -t gcr.io/${PROJECT_ID}/hello-app:v1 .
```

```shell

$ gcloud container images list-tags gcr.io/${PROJECT_ID}/hello-app
DIGEST        TAGS  TIMESTAMP
0904af2110a6  v1    2020-02-08T14:07:54
```
イメージができた

# クラスタつくる

```yaml

$ gcloud container clusters create hello-cluster --num-nodes=2

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.
WARNING: Newly created clusters and node-pools will have node auto-upgrade enabled by default. This can be disabled using the `--no-enable-autoupgrade` flag.
WARNING: Starting in 1.12, default node pools in new clusters will have their legacy Compute Engine instance metadata endpoints disabled by default. To create a cluster with legacy instance metadata endpoints disabled in the default node pool, run `clusters create` with the flag `--metadata disable-legacy-endpoints=true`.
WARNING: Your Pod address range (`--cluster-ipv4-cidr`) can accommodate at most 1008 node(s). 
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.
Creating cluster hello-cluster in us-west1-a... Cluster is being health-checked (master is healthy)...done.                                   
Created [https://container.googleapis.com/v1/projects/core-verbena-262002/zones/us-west1-a/clusters/hello-cluster].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-west1-a/hello-cluster?project=core-verbena-262002
kubeconfig entry generated for hello-cluster.
```
いろいろ`WARNING`でる。中身については、ここのブログ読む → [というわけで。](https://tinux.hatenablog.jp/entry/2018/10/30/191051)

クラスタは以下で確認できる

```
$ gcloud compute instances list
NAME                                          ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
gke-hello-cluster-default-pool-a1e7a3dd-33j2  us-west1-a  n1-standard-1               10.138.0.5   104.199.118.216  RUNNING
gke-hello-cluster-default-pool-a1e7a3dd-bw4w  us-west1-a  n1-standard-1               10.138.0.6   34.82.179.67     RUNNING
```

# イメージをデプロイする

この時のレプリカは`1`

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

ここではクラスタ名を指定していない。クラスタが複数ある場合どのように認識しているのか？おそらく以下のコマンドでクラスタを指定して、デプロイするクラスタの認証情報を構成するんだとおもう
`gcloud container clusters get-credentials hello-cluster`

`pod`を見てみる

```
$ kubectl get deployment hello-web
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
hello-web   1/1     1            1           11m
```

```
$ kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
hello-web-cf78d9db9-knlcp   1/1     Running   0          71s
```

# 外部からアクセスできるようにする

```
$ kubectl expose deployment hello-web --type=LoadBalancer --port 80 --target-port 8080
```

```
$ kubectl get services 
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
hello-web    LoadBalancer   10.51.242.58   35.247.108.207   80:30369/TCP   2m5s
kubernetes   ClusterIP      10.51.240.1    <none>           443/TCP        108m
```

プラウザでアクセスしてみるとこんな感じ。ここでは `Version: 1.0.0` で `Hello, world!`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32540/0f5eff8a-4872-7a0a-2da0-d63ddd1de7fb.png)



# スケールアウトする

レプリカを`3`にする

```
$ kubectl scale deployment hello-web --replicas=3
```

```
$ kubectl get deployment hello-web
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
hello-web   3/3     3            3           11m
```

```
$ kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
hello-web-cf78d9db9-knlcp   1/1     Running   0          10m
hello-web-cf78d9db9-m64m8   1/1     Running   0          9s
hello-web-cf78d9db9-txr2r   1/1     Running   0          9s
```

レプリカを`1`に戻すのもこのコマンドで。このあたりを`deployment`リソースが管理しているらしい。イミュータブルな世界！

`pod`がどの`node`で動いているかを見る。`pod`が`3`つで、`node`が`2`つなので、以下のように`pod`二つは同じノード`gke-hello-cluster-default-pool-a1e7a3dd-33j2`にいることがわかる

```
$ kubectl get pod -o wide
NAME                        READY   STATUS    RESTARTS   AGE     IP           NODE                                           NOMINATED NODE   READINESS GATES
hello-web-cf78d9db9-kg2pb   1/1     Running   0          4m39s   10.48.0.11   gke-hello-cluster-default-pool-a1e7a3dd-bw4w   <none>           <none>
hello-web-cf78d9db9-knlcp   1/1     Running   0          19m     10.48.1.4    gke-hello-cluster-default-pool-a1e7a3dd-33j2   <none>           <none>
hello-web-cf78d9db9-qcd57   1/1     Running   0          4m39s   10.48.1.6    gke-hello-cluster-default-pool-a1e7a3dd-33j2   <none>           <none>
```

# コンテナ`v2`をビルドする

`main.go` を `Hello world!` から `Hello GKE!` に書き換えて、さらに `Version:` を `1.0.0` から `2.0.0` としてビルド

```
gcloud builds submit -t gcr.io/${PROJECT_ID}/hello-app:v2 .
```

```
$ gcloud container images list-tags gcr.io/${PROJECT_ID}/hello-app
DIGEST        TAGS  TIMESTAMP
c7685a830142  v2    2020-02-08T15:08:14
0904af2110a6  v1    2020-02-08T14:07:54
```

# コンテナをアップデートする

`v1`から`v2`へアップデートする。ローリングアップデートなるものがおこるらしい

```
$ kubectl set image deployment/hello-web hello-app=gcr.io/${PROJECT_ID}/hello-app:v2
deployment.extensions/hello-web image updated
```

再び、ブラウザを開くと、確かに変わっている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32540/c17aad0b-a0e6-52bd-df00-0e15c504bb3a.png)

ホスト名は、`Load Balancer` あるので変わるのだろう

# おかたずけ

ハッキングされないように

```
$ kubectl delete service hello-web
```
```
$ gcloud container clusters delete hello-cluster
```