AKS を使いこなす : チュートリアルの深堀り - アプリケーションのスケーリング

今回は[チュートリアル:Azure Kubernetes Service (AKS) でのアプリケーションのスケーリング](https://docs.microsoft.com/ja-jp/azure/aks/tutorial-kubernetes-scale?view=azure-cli-latest)の深堀をしていきます。

このチュートリアルでは手動および自動でのスケールを行っています。それぞれの手順で何が起きているか見ていきます。

# ポッドの手動でのスケール

まずはポッド数を明示的に指定した手動でのスケールです。

## チュートリアルの手順

1\. 現在のポッドを確認。

```shell
> kubectl get pods                                                                  NAME                               READY   STATUS    RESTARTS   AGE
azure-vote-back-847fc9bcb9-p7m9x   1/1     Running   0          6h45m
azure-vote-front-c857778b-ttlx2    1/1     Running   0          6h45m
```

2\. フロントのポッドを 5 にスケールするよう指定。

```shell
kubectl scale --replicas=5 deployment/azure-vote-front
```

3\. 再度ポッドを確認。フロントのポッドが 5 台になっていることを確認。

```shell
> kubectl get pods                                                                  NAME                               READY   STATUS    RESTARTS   AGE
azure-vote-back-847fc9bcb9-p7m9x   1/1     Running   0          6h47m
azure-vote-front-c857778b-6px8s    1/1     Running   0          45s
azure-vote-front-c857778b-97mz2    1/1     Running   0          45s
azure-vote-front-c857778b-dkvx5    1/1     Running   0          45s
azure-vote-front-c857778b-swr8q    1/1     Running   0          45s
azure-vote-front-c857778b-ttlx2    1/1     Running   0          6h47m
```
## k8s 側からみたポッドの手動スケール

```kubectl scale``` はデプロイメントに対して実行されるため以下のコンポーネントが影響を受けます。

- デプロイメント
- レプリカセット
- ポッド
- サービス
- ノード

1\. まずはデプロイメントを取得

- l オプション (または select) によりラベルを指定して azure-vote-front だけ取得
- READY が 5 であることを確認。

```shell
> kubectl get deployments -l app=azure-vote-front                                    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
azure-vote-front   5/5     5            5           6h58m
```
2\. 同様にレプリカセットを確認。

```shell
> kubectl get replicasets -l app=azure-vote-front                                    NAME                        DESIRED   CURRENT   READY   AGE
azure-vote-front-c857778b   5         5         5       6h59m
```

3\. 起動しているポッドの詳細を確認。

- 同じレプリカセットから配置されたポッドのため同じプレフィクスを持つ
- 2 つのノードに分散して配置されていることを確認

```shell
> kubectl get pods -l app=azure-vote-front -o wide                                   NAME                              READY   STATUS    RESTARTS   AGE   IP           NODE                       NOMINATED NODE   READINESS GATES
azure-vote-front-c857778b-6px8s   1/1     Running   0          13m   10.244.1.5   aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-97mz2   1/1     Running   0          13m   10.244.1.4   aks-nodepool1-34717040-0   <none>           <none>
azure-vote-front-c857778b-dkvx5   1/1     Running   0          13m   10.244.0.8   aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-c857778b-swr8q   1/1     Running   0          13m   10.244.0.9   aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-c857778b-ttlx2   1/1     Running   0          7h    10.244.1.3   aks-nodepool1-34717040-0   <none>           <none>
```

4\. ロードバランサーとして機能しているサービスを確認。

- Endpoints に 5 つのポッドアドレスが設定されていることを確認

```shell
> kubectl describe service azure-vote-front                                         Name:                     azure-vote-front
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"azure-vote-front","namespace":"default"},"spec":{"ports":[{"port"...
Selector:                 app=azure-vote-front
Type:                     LoadBalancer
IP:                       10.0.10.225
LoadBalancer Ingress:     20.43.78.36
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  32491/TCP
Endpoints:                10.244.0.8:80,10.244.0.9:80,10.244.1.3:80 + 2 more...
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
```

5\. 最後ノードの状態も確認。kube-proxy 以外にも配置されたポッドが表示されていることを確認。

```shell
kubectl describe node aks-nodepool1-34717040-0 
```
- Non-terminated Pods 部分のみ表示

```shell
Non-terminated Pods:         (5 in total)
  Namespace                  Name                                CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                  ----                                ------------  ----------  ---------------  -------------  ---
  default                    azure-vote-back-847fc9bcb9-p7m9x    0 (0%)        0 (0%)      0 (0%)           0 (0%)         7h2m
  default                    azure-vote-front-c857778b-6px8s     250m (12%)    500m (25%)  0 (0%)           0 (0%)         15m
  default                    azure-vote-front-c857778b-97mz2     250m (12%)    500m (25%)  0 (0%)           0 (0%)         15m
  default                    azure-vote-front-c857778b-ttlx2     250m (12%)    500m (25%)  0 (0%)           0 (0%)         7h2m
  kube-system                kube-proxy-wvpdp                    100m (5%)     0 (0%)      0 (0%)           0 (0%)         9h
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource                       Requests    Limits
  --------                       --------    ------
  cpu                            850m (44%)  1500m (77%)
  memory                         0 (0%)      0 (0%)
  ephemeral-storage              0 (0%)      0 (0%)
  attachable-volumes-azure-disk  0           0
```

# ポッドの自動スケール

次に自動でのスケールを見ていきます。k8s は CPU の使用率などの閾値を用いて、自動でのスケールアウトをサポートします。

## チュートリアルの手順

1\. CPU の閾値を 50% として、ポッドの最小個数を 3、最大個数を　10 に設定。

```shell
kubectl autoscale deployment azure-vote-front --cpu-percent=50 --min=3 --max=10
```
2\. スケールの状態は Horizontal Pod Autoscalers で取得可能。ポッド数が 5 から 3 に変化することを確認。

- hpa は horizontalpodautoscalers の省略形
- watch を指定して経過を観察

```shell
> kubectl get hpa --watch 
NAME               REFERENCE                     TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
azure-vote-front   Deployment/azure-vote-front   0%/50%    3         10        5          2m16s
azure-vote-front   Deployment/azure-vote-front   0%/50%    3         10        5          5m15s
azure-vote-front   Deployment/azure-vote-front   0%/50%    3         10        3          5m30s
```

##  k8s 側からみたポッドの自動スケール

オートスケールをデプロイメントに作成するとオートスケーラーが作成されます。

- REFERENCE: オートスケーラーが関連するリソース

```shell
> kubectl get hpa                                                                   NAME               REFERENCE                     TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
azure-vote-front   Deployment/azure-vote-front   0%/50%    3         10        3          13m
```

# ノードの手動スケール

多くのポッドを展開した際、ノードが不足する事があり、その場合はノードを追加する必要があります。

## チュートリアルの手順

ノードは仮想マシンであり、AKS の観点からは k8s の操作でなく Azure 側の作業となるため、az コマンドを使います。

1\. ```az aks scale``` コマンドでスケールを実行。

```shell
az aks scale --resource-group akstutorial --name myfirstaks-- node-count 3
```
2\. ノードを取得して結果を確認。

```shell
> kubectl get nodes                                                                 NAME                       STATUS   ROLES   AGE    VERSION
aks-nodepool1-34717040-0   Ready    agent   10h    v1.13.10
aks-nodepool1-34717040-1   Ready    agent   10h    v1.13.10
aks-nodepool1-34717040-2   Ready    agent   3m7s   v1.13.10
```

## 負荷試験

チュートリアルにはありませんが、アプリに負荷をかけてどのようにポッドが配置されるか見てみます。

1\. ポッドの状況をウォッチ。

```shell
kubectl get pods -o wide --watch
```

2\. 新しいシェルから負荷をかけるためのポッドを実行。

- load-generator という名前でデプロイメントを作成
- イメージは busybox
- 起動時に /bin/sh を起動

```shell
kubectl run -i --tty load-generator --image=busybox /bin/sh
```

3\. ポッドが起動するとシェルにログインするので、以下のコードを実行。

```shell
while true; do wget -q -O- http://20.43.78.36/; done
```
4\. 元のシェルに戻ってポッドの配置状況を確認。

- azure-vote-front-c857778b-q995d の Status が Pending から Running へ変わっていく事を確認

```shell
NAME                               READY   STATUS    RESTARTS   AGE     IP           NODE                       NOMINATED NODE   READINESS GATES
azure-vote-front-c857778b-q995d    0/1     Pending   0          0s      <none>       <none>                     <none>           <none>
azure-vote-front-c857778b-q995d    0/1     Pending   0          0s      <none>       aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-c857778b-q995d    0/1     ContainerCreating   0          0s      <none>       aks-nodepool1-34717040-1   <none>           <none>
azure-vote-front-c857778b-q995d    1/1     Running             0          6s      10.244.0.10   aks-nodepool1-34717040-1   <none>           <none>
```
さらに負荷をかけると最大 10 ポッドまでスケールします。

5\. すべての処理を停止してから、以下のコマンドで負荷をかけていたポッドを削除。

```shell
kubectl delete deployments load-generator
```

# ノードの自動スケール

チュートリアルではカバーされていませんが、現在プレビューとしてノードの自動スケールもサポートされています。詳細はまた別の記事で紹介しますが詳細は参照のリンクを見てください。

# まとめ

アプリケーションのスケールはいくつかのパターンがありますが、自動スケールに使える設定としてどのようなものがあるかを調べるのは面白そうです。次回はアプリケーションの更新を見ていきます。

[次の記事へ](https://qiita.com/kenakamu/items/f6b2de045b76cc05b809)
[目次に戻る](https://qiita.com/kenakamu/items/e155740aa60c85a3d867)

# 参照

[Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
[プレビュー - Azure Kubernetes Service (AKS) でのアプリケーションの需要を満たすようにクラスターを自動的にスケーリングする](https://docs.microsoft.com/ja-jp/azure/aks/cluster-autoscaler)