Kubernetesの公式チュートリアルをやってみる その6

[Kubernetesの公式チュートリアルをやってみる その5][topic-5] では Service について扱いました。
この記事のチュートリアルではアプリのスケーリングについて扱います。

#### 注意 && disclaimer

翻訳・意訳が主目的ではないのでいろいろ端折ったりすることがあります。
明らかな間違いはしないつもりですが、何かあれば優しくツッコんであげてください。

→記事のまとめは [Kubernetesの公式チュートリアルをやってみる その1][topic-1] にあります。


## 本記事の取り扱う範囲

[Running Multiple Instances of Your App][tutorial-5] の内容を扱います。


## Running Multiple Instances of Your App

Pod で稼働するアプリのスケーリング 関連の内容

### Scaling

- アプリのアクティビティが増えた際にスケーリングさせる必要があることがある。
- kubernetes では Deployment 上のレプリカ数を変更することでスケールさせることができる。
- スケールアウトを指示すると Pod を追加してクラスタ上で稼働させる。[^1]
- レプリカ数を0にすることもできる。この場合該当の Pod はすべて破棄される。
- Service は Pod を継続して監視し、稼働している Pod のみにトラフィックを振り分ける。
- 複数のインスタンスを稼働させることでダウンタイムなしでコンテナ化アプリの更新を行うことができる。[^2]

[^1]: kubenetes自体にオートスケールの機能もあるが本チュートリアルでは取り扱われない。
[^2]: 次のチュートリアルで取り扱う。


### Interactive Tutorial

Estimate Time: 10分

- `kubectl get deployment`
    - `DESIRED` が要求されたレプリカ数
    - `CURRENT` が現在起動している Pod 数
    - `UP-TO-DATE` が `DESIRED` で要求された中で起動している Pod 数
        - `CURRENT` との違いは？ここはよくわかってない
    - `AVAILABLE` が有効と判断されている Pod 数

```bash
# 開始直後でまだ有効なPodがない状態
$ kubectl get deployments
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   1         1         1            0           1s
# 時間が経過してPodが有効になった
$ kubectl get deployments
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   1         1         1            1           1m
```

- `kubectl scale`
    - レプリカ数を変更するコマンド
        - チュートリアル環境ではスケール指定後即座に追加分が `AVAILABLE` になっていた。

```bash
$ kubectl scale deployments/kubernetes-bootcamp --replicas=4
deployment.extensions/kubernetes-bootcamp scaled
$ kubectl get deployments
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   4         4         4            4           5m

# スケール変更直後にリストした場合の状態(初期レプリカ = 1 の状態から)
# -- スケールインは指示直後にAVAILABLEから外れるらしい
$ kubectl scale deployments/kubernetes-bootcamp --replicas=4 && kubectl get deployments.
deployment.extensions/kubernetes-bootcamp scaled
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   4         4         4            1           9m
$ kubectl scale deployments/kubernetes-bootcamp --replicas=1 && kubectl get deployments.
deployment.extensions/kubernetes-bootcamp scaled
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   1         1         1            1           10m
```

- `kubectl get pod -o wide`
    - wide表示にすると個別IPが表示される。

```bash
# それぞれのPodに個別のIPが振られる
$ kubectl get pods -o wide
NAME                                   READY     STATUS    RESTARTS   AGE       IP           NODE
kubernetes-bootcamp-5c69669756-f2sf2   1/1       Running   0          11m       172.18.0.2   minikube
kubernetes-bootcamp-5c69669756-vc9w4   1/1       Running   0          4s        172.18.0.7   minikube
kubernetes-bootcamp-5c69669756-wggtk   1/1       Running   0          4s        172.18.0.5   minikube
kubernetes-bootcamp-5c69669756-xrx9n   1/1       Running   0          4s        172.18.0.6   minikube
```

- `kubectl describe deployments/[deployment name]`
    - Deploymentの詳細ではレプリカ数が確認できる。

```bash
$ kubectl describe deployments/kubernetes-bootcamp | grep Replicas
Replicas:               4 desired | 4 updated | 4 total | 4 available | 0 unavailable
  Available      True    MinimumReplicasAvailable
```

- サービスからのバランシング
    - サービス配下に複数の Pod が存在する場合トラフィックはバランシングされる。

```bash
$ kubectl describe services/kubernetes-bootcamp | grep -e Name -e EndpointsName:                     kubernetes-bootcamp
Namespace:                default
Endpoints:                172.18.0.2:8080,172.18.0.5:8080,172.18.0.6:8080 + 1 more...
$ export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
# アクセス毎に処理するPodが異なる(チュートリアルはPod名を返している)
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5c69669756-f2sf2 | v=1
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5c69669756-xrx9n | v=1
```

- スケールダウン[^3]
    - レプリカ数を減らすと不要な数のPodが破棄される。

```bash
$ kubectl scale deployments/kubernetes-bootcamp --replicas=2
deployment.extensions/kubernetes-bootcamp scaled
$ kubectl get deployments
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   2         2         2            2           18m
# スケールダウン直後
$ kubectl get pods -o wide
NAME                                   READY     STATUS        RESTARTS   AGE       IP           NODE
kubernetes-bootcamp-5c69669756-f2sf2   1/1       Running       0          18m       172.18.0.2   minikube
kubernetes-bootcamp-5c69669756-vc9w4   1/1       Running       0          7m        172.18.0.7   minikube
kubernetes-bootcamp-5c69669756-wggtk   1/1       Terminating   0          7m        172.18.0.5   minikube
kubernetes-bootcamp-5c69669756-xrx9n   1/1       Terminating   0          7m        172.18.0.6   minikube
# しばらくすると完全に破棄される
$ kubectl get pods -o wide
NAME                                   READY     STATUS    RESTARTS   AGE       IP           NODE
kubernetes-bootcamp-5c69669756-f2sf2   1/1       Running   0          20m       172.18.0.2   minikube
kubernetes-bootcamp-5c69669756-vc9w4   1/1       Running   0          8m        172.18.0.7   minikube
```

[^3]: 意味合いからすると本来的には *Scale In* では...？と思うけど、kubernetes 上では *Scale Down* らしい。

----

## 参考リンク

- [Kubernetes公式][kubernetes]
- [Kubernetes公式チュートリアル][tutorials]

[kubernetes]:https://kubernetes.io/
[tutorials]:https://kubernetes.io/docs/tutorials/kubernetes-basics/
[tutorial-5]:https://kubernetes.io/docs/tutorials/kubernetes-basics/scale/scale-intro/

[topic-1]:https://qiita.com/kitamin/items/f50fe470a04e38023f7a
[topic-2]:https://qiita.com/kitamin/items/c4902edba777f4bf4826
[topic-3]:https://qiita.com/kitamin/items/c2fb850bbf0397acd9c2
[topic-4]:https://qiita.com/kitamin/items/a7657db9689111c9e4dc
[topic-5]:https://qiita.com/kitamin/items/7b56d1c40824414ec768