AKS で asp.net core アプリケーション : 自動スケール - クラスターのスケール

[前回](https://qiita.com/kenakamu/items/29acb5c79c6700eed814)の記事でポッドの水平スケールを見ていきました。今回はノード側でリソースが不足した場合のノードの自動スケールを見ていきます。

# クラスターオートスケーラー

現在のクラスタでホストしきれない数のポッド要求があった場合、AKS ではクラスタノードを自動的に追加することができます。また逆に不要になった場合は自動で縮小します。

![](https://docs.microsoft.com/ja-jp/azure/aks/media/concepts-scale/cluster-autoscaler.png)
[参考: クラスターオートスケーラー](https://docs.microsoft.com/ja-jp/azure/aks/concepts-scale#cluster-autoscaler)

# ノードプールの追加

今回は既存のクラスタに Web アプリ用のオートスケールするノードプールを追加することにしました。

1\. Standard_A1 サイズのノードを追加。

- 最小台数 1、最大台数 5 
- オートスケールを有効にする
- Taints として kind=app:NoSchedule を指定
- 既定のラベルを指定する機能はまだない模様

```shell
az aks nodepool add -g netcoresample --cluster-name myaks -n nodepool3 -c 1 --node-vm-size Standard_A1 --enable-cluster-autoscaler --min-count 1 --max-count 5 --node-taints kind=app:NoSchedule
```

2\. ノードプール 1 の台数を縮小。

```shell
az aks nodepool scale -g netcoresample --cluster-name myaks --name nodepool1 -c 1
```

3\. ノードプール 1 のノードからラベルとテイントを削除。

```shell
kubectl label node aks-nodepool1-23705949-vmss000000 kind-
kubectl taints node aks-nodepool1-23705949-vmss000000 kind-
```

4\. ノードプール 3 のノードの Labels と Taints を確認。

```shell
>kubectl describe node aks-nodepool3-23705949-vmss000000
Name:               aks-nodepool3-23705949-vmss000000
Roles:              agent
Labels:             agentpool=nodepool3
                    beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/instance-type=Standard_A1
                    beta.kubernetes.io/os=linux
                    failure-domain.beta.kubernetes.io/region=japaneast
                    failure-domain.beta.kubernetes.io/zone=0
                    kubernetes.azure.com/cluster=MC_netcoresample_myaks_japaneast
                    kubernetes.azure.com/role=agent
                    kubernetes.io/hostname=aks-nodepool3-23705949-vmss000000
                    kubernetes.io/role=agent
                    node-role.kubernetes.io/agent=
                    storageprofile=managed
                    storagetier=Standard_LRS
Annotations:        node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Sun, 24 Nov 2019 23:29:40 +0900
Taints:             kind=app:NoSchedule
```

5\. webapp のポッドが配置待ちになっていることを確認。

```shell
>kubectl get pods
NAME                                READY   STATUS              RESTARTS   AGE
core3webapp-b599bd5d-b4ngm          0/1     MatchNodeSelector   0          17d
core3webapp-b599bd5d-g7rqq          0/1     Pending             0          30m
core3webapp-b599bd5d-gwvsc          0/1     MatchNodeSelector   0          17d
core3webapp-b599bd5d-m4ddz          0/1     Pending             0          30m
core3webapp-b599bd5d-qwwth          0/1     Pending             0          30m
core3webapp-b599bd5d-rmm84          0/1     MatchNodeSelector   0          17d
core3webapp-b599bd5d-szgx6          0/1     MatchNodeSelector   0          17d
core3webapp-b599bd5d-wtblp          0/1     Pending             0          30m
mssql-deployment-749f664d67-mv8r4   1/1     Running             1          16d
```

6\. 現在のノードを確認。

```shell
>kubectl get nodes
NAME                                STATUS   ROLES   AGE   VERSION
aks-nodepool1-23705949-vmss000000   Ready    agent   23d   v1.13.11
aks-nodepool2-23705949-vmss000000   Ready    agent   23d   v1.13.11
aks-nodepool3-23705949-vmss000000   Ready    agent   21m   v1.13.11
```

# アプリケーションの更新

現在 webapp は selector がマッチするノードがいないため配置できません。こちらを変更します。
また既定のラベルを指定できなかったので、agentpool=nodepool3 を利用します。

1\. myapp.yaml の core3webapp デプロイだけ以下のように変更。

- nodeSelector で agentpool: nodepool3 を指定
- メモリの最低値を 256 MB に変更

```shell
apiVersion: apps/v1
kind: Deployment
metadata:
  name: core3webapp
  labels:
    app: core3webapp
spec:
  replicas: 4
  selector:
    matchLabels:
        app: core3webapp
  template:
    metadata:
      name: core3webapp
      labels:
        app: core3webapp
    spec:
      containers:
      - name: core3webapp
        image: kenakamuacr.azurecr.io/core3webapp:20191029043926
        resources: 
          requests:
            cpu: "250m"
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "1Gi"
        imagePullPolicy: Always
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      tolerations:
      - key: "kind"
        operator: "Equal"
        value: "app"
        effect: "NoSchedule"
      nodeSelector:
         agentpool: nodepool3
```

2\. デプロイを実行。

```shell
>kubectl apply -f myapp.yaml
storageclass.storage.k8s.io/azure-disk unchanged
persistentvolumeclaim/mssql-data unchanged
secret/mssql unchanged
deployment.apps/mssql-deployment unchanged
service/mssql-deployment unchanged
deployment.apps/core3webapp configured
service/core3webapp unchanged
ingress.extensions/core3webapp unchanged
```

# クラスターオートスケールの確認

最後に、ポッドの要求を現在のノード数では満たせないため、クラスターで自動スケールが発生する様子を確認します。

1\. ポッドの状況を確認。

```shell
>kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP          NODE                                NOMINATED NODE   READINESS GATES
core3webapp-55c4568d6f-btkmx        0/1     Pending   0          46s   <none>      <none>                              <none>           <none>
core3webapp-55c4568d6f-rxl4q        1/1     Running   0          78s   10.0.0.40   aks-nodepool3-23705949-vmss000000   <none>           <none>
core3webapp-55c4568d6f-thg5w        0/1     Pending   0          78s   <none>      <none>                              <none>           <none>
core3webapp-7f6cb8845-j8f4k         0/1     Pending   0          11m   <none>      <none>                              <none>           <none>
core3webapp-7f6cb8845-rjwxp         0/1     Pending   0          11m   <none>      <none>                              <none>           <none>
mssql-deployment-749f664d67-rmtst   1/1     Running   0          12m   10.0.0.79   aks-nodepool2-23705949-vmss000000   <none>           <none>
```

2\. Azure ポータルよりノードプール 3 のインスタンス状況を確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/6f13a2d3-1be1-d53e-3adf-9b90fa65db51.png)


3\. k8s でのノードの状態を確認。クラスター自動スケールで台数が自動的に増加。

```shell
>kubectl get nodes
NAME                                STATUS   ROLES   AGE   VERSION
aks-nodepool1-23705949-vmss000000   Ready    agent   23d   v1.13.11
aks-nodepool2-23705949-vmss000000   Ready    agent   23d   v1.13.11
aks-nodepool3-23705949-vmss000000   Ready    agent   50m   v1.13.11
aks-nodepool3-23705949-vmss000001   Ready    agent   76s   v1.13.11
aks-nodepool3-23705949-vmss000002   Ready    agent   49s   v1.13.11
```

4\. ポッドも併せて起動してくることを確認。

```shell
>kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
core3webapp-55c4568d6f-5r9r4        0/1     Pending   0          96s
core3webapp-55c4568d6f-btkmx        1/1     Running   0          5m40s
core3webapp-55c4568d6f-rxl4q        1/1     Running   0          6m12s
core3webapp-55c4568d6f-thg5w        1/1     Running   1          6m12s
mssql-deployment-749f664d67-rmtst   1/1     Running   0          17m
```

5\. 最終的に要求したポッドが起動することを確認。

```shell
>kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
core3webapp-55c4568d6f-5r9r4        1/1     Running   0          6m7s
core3webapp-55c4568d6f-btkmx        1/1     Running   0          10m
core3webapp-55c4568d6f-rxl4q        1/1     Running   0          10m
core3webapp-55c4568d6f-thg5w        1/1     Running   1          10m
mssql-deployment-749f664d67-rmtst   1/1     Running   0          21m
```

6\. レプリカセット数を減らした場合にノード数が自動的に縮小するか確認。

```shell
>kubectl get nodes
NAME                                STATUS     ROLES   AGE   VERSION
aks-nodepool1-23705949-vmss000000   Ready      agent   23d   v1.13.11
aks-nodepool2-23705949-vmss000000   Ready      agent   23d   v1.13.11
aks-nodepool3-23705949-vmss000000   Ready      agent   69m   v1.13.11
aks-nodepool3-23705949-vmss000001   NotReady   agent   20m   v1.13.11
aks-nodepool3-23705949-vmss000003   NotReady   agent   15m   v1.13.11

>kubectl get nodes
NAME                                STATUS   ROLES   AGE   VERSION
aks-nodepool1-23705949-vmss000000   Ready    agent   23d   v1.13.11
aks-nodepool2-23705949-vmss000000   Ready    agent   23d   v1.13.11
aks-nodepool3-23705949-vmss000000   Ready    agent   69m   v1.13.11
```

# 自動縮小しない場合

いくつかの条件下では、[こちらの記事にあるとおり](https://docs.microsoft.com/ja-jp/azure/aks/cluster-autoscaler#about-the-cluster-autoscaler)ノードが自動で縮小しません。

- ポッドが直接作成されており、デプロイやレプリカ セットなどのコントローラー オブジェクトによってサポートされていない。
- Pod Disruption Budget (PDB) の制限が非常に厳しく、ポッドの数が特定のしきい値を下回ることが許可されていない。
- ポッドが、別のノードでスケジュールされた場合に適用できないノード セレクターまたはアンチ アフィニティーを使用している。

# まとめ

クラスターの自動スケールを使う場合、テイントやラベルをどうするか、また VM のサイズとスケール上限をどうするかなど考えることがいくつかありますが、管理者がわざわざ手動で設定しなくてもいい点はやはり便利です。次回はもう一つの自動スケールである Azure Container Instance (ACI) へのバーストを見ていきます。

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

# 参照

[参考: クラスターオートスケーラー](https://docs.microsoft.com/ja-jp/azure/aks/concepts-scale#cluster-autoscaler)