AWS EKS/EC2構成で、Multi-AZでのAutoScalingを実現する(Cluster Autoscaler編)

# はじめに
EKSのAutoScalingには、大きく3種類存在の機能が存在しており、その中のCluster Autoscaler(CA)はMulti-Azに対応していない。

https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md

><font color = "red">Cluster autoscaler does not support Auto Scaling Groups which span multiple Availability Zones</font>; instead you should use an Auto Scaling Group for each Availability Zone and enable the--balance-similar-node-groupsfeature. If you do use a single Auto Scaling Group that spans multiple Availability Zones you will find that AWS unexpectedly terminates nodes without them being drained because of therebalancing feature.

そこで今回は上記で紹介されている、`--balance-similar-node-groups`を使って、Multi-Az構成を組んでみる。

## EKSにおけるAutoScaingの種類
Amazon EKSクラスタには、大きく3つのAutoScalingが存在する。

1. **Cluster Autoscaler(CA)**:Kubernetes Cluster Autoscaler は、リソース不足が原因でポッドが起動できなかった場合、またはクラスター内のノードの利用率が低く、そのポッドをクラスター内の他のノードに再スケジュールできる場合に、**クラスター内のノードの数**を自動的に調整します。
2. **Horizontal Pod Autoscaler(HPA)**:Kubernetes Horizontal Pod Autoscaler は、そのリソースの CPU 使用率に基づいて、デプロイ、レプリケーションコントローラー、またはレプリカセット内の**ポッドの数**を自動的にスケーリングします。
3. **Vertical Pod Autoscaler(VPA)**:Kubernetes Vertical Pod Autoscaler は、ポッドの CPU とメモリの予約を自動的に調整し、アプリケーションを「適切なサイズ」にします。これにより、**クラスターリソース**を効率的に使用し、CPU とメモリを他のポッドに解放できます。

つまり、<font color="Red">**EC2など、IaaSレベルでのノードが不足している場合にはCAが管理し、その上で動作するポッドを
どのノード上で動作させるかをHPAが管理し、更に各Podの数をVPAが管理しているというわけ。**</font>

今回の記事は、**ClusterAutoscalerwo使ったMultiAz構成**なので、HPAやVPAは説明していない。

# CAを使ったMulti-AZ構成　構築手順
## 事前準備
まずは、下記を参考にEKSクラスターおよび、ノードグループを作成しておく。
**EKSクラスターの作成**
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/create-cluster.htm
**ノードグループの作成**
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/create-managed-node-group.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449825/9766421c-28b0-8f8a-f3b5-c6274e884c8e.png)

## CAのデプロイ
AWSの公式ページを参考に進めていく
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/cluster-autoscaler.html

### CAをクラスターにデプロイ
下記コマンドを使って、CAをクラスターにデプロイする。

```
[ec2-user@ip-10-100-20-210 ~]$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
serviceaccount/cluster-autoscaler created
clusterrole.rbac.authorization.k8s.io/cluster-autoscaler created
role.rbac.authorization.k8s.io/cluster-autoscaler created
clusterrolebinding.rbac.authorization.k8s.io/cluster-autoscaler created
rolebinding.rbac.authorization.k8s.io/cluster-autoscaler created
deployment.apps/cluster-autoscaler created
```
### デプロイに対して ```cluster-autoscaler.kubernetes.io/safe-to-evict``` 注釈を追加

```
[ec2-user@ip-10-100-20-210 ~]$ kubectl -n kube-system annotate deployment.apps/cluster-autoscaler cluster-autoscaler.kubernetes.io/safe-to-evict="false"
deployment.apps/cluster-autoscaler annotated
```

### CAデプロイを編集
ここで、`--balance-similar-node-groups```と```--skip-nodes-with-system-pods=false`を追加する。
また`<YOUR CLUSTER NAME>` をクラスターの名前に置き換える。

```
[ec2-user@ip-10-100-20-210 ~]$ kubectl -n kube-system edit deployment.apps/cluster-autoscaler
～中略～
      containers:
      - command:
        - ./cluster-autoscaler
        - --v=4
        - --stderrthreshold=info
        - --cloud-provider=aws
        - --skip-nodes-with-local-storage=false
        - --expander=least-waste
        - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/eks-miharatky-test-01
        - --balance-similar-node-groups
        - --skip-nodes-with-system-pods=false
～省略～
```

### ClusterAutoscalerの最新マイナーバージョンを調査する。
ClusterAutoScalerの[リリースページ](https://github.com/kubernetes/autoscaler/releases)にアクセスし、Kubernetesクラスターのメジャーバージョンとマイナーバージョンを調べる。例えば、2020/5/5現在、最新バージョンは1.16.5になっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449825/01006b38-f414-c3ef-b65a-4f33f583fd7f.png)

### Cluster Autoscaler イメージタグにバージョンを設定
Cluster Autoscaler イメージタグを、前のステップで書き留めたバージョンに設定する。

```
[ec2-user@ip-10-100-20-210 ~]$ kubectl -n kube-system set image deployment.apps/cluster-autoscaler cluster-autoscaler=asia.gcr.io/k8s-artifacts-prod/autoscaling/cluster-autoscaler:v1.16.5
deployment.apps/cluster-autoscaler image updated
```

### 動作確認
Cluster Autoscaler ログを表示して、実際に動いていることを確認する。

```
[ec2-user@ip-10-100-20-210 ~]$ kubectl -n kube-system logs -f deployment.apps/cluster-autoscaler
```

これで設定は完了。
マニュアル通りだが、意外とすんなりいった。

### 最後に
今回はCAにて、`--balance-similar-node-groups`を設定する手順を説明した。
余裕があれば、HPAやVPAについても実際に試してみようと思う。