Amazon EKS のノード1台に起動できるPod の制限数を増やす

# はじめに
[Amazon EKS](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/what-is-eks.html) クラスタのアドオンである[Amazon VPC CNI (Container Network Interface)](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/pod-networking.html)を有効化するとEKS のノードで起動するPod はVPC 内のIP アドレスを使って通信できるようになります。

この機能を有効化すると、デフォルトではノードのインスタンスタイプによって起動できるPod の数に制限が発生してしまうため、スペックが低めのインスタンスタイプの場合、この制限にすぐに引っかかってしまうかと思います。

参考: [インスタンスタイプによって起動できるPod の数](https://github.com/awslabs/amazon-eks-ami/blob/master/files/eni-max-pods.txt)

本記事では、この制限を緩和する手順について記載しています。
詳細は、下記を参考にするとより理解が深まるかと思います。

[Amazon VPC CNI プラグインでノード 1 台に配置可能な Pod 数を増やすために](https://aws.amazon.com/jp/blogs/news/amazon-vpc-cni-increases-pods-per-node-limits/)
[Amazon EC2 ノードで使用可能な IP アドレスの量を増やす](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/cni-increase-ip-addresses.html) 

# 手順
現在のコンテキストを確認します。
```terminal
$ kubectl config current-context
```

ここでは、Kubernetes のバージョンは、`1.22` です。
```
$ kubectl version
Server Version: v1.22.11-eks-18ef993
```
Amazon VPC CNI plugin が`1.9.0`または`1.10.1以降`であることを確認します。
```
$ kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
amazon-k8s-cni-init:v1.10.1-eksbuild.1
amazon-k8s-cni:v1.10.1-eksbuild.1
```
クラスタ内のノードで起動しているすべてのPod を確認します。
ここでは、マネージド型ノードグループの`1ノード`を使用しています。
```
$ kubectl get pod -A
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE
kube-system   aws-node-lg4cz             1/1     Running   0          7m47s
kube-system   coredns-5b6d4bd6f7-2c4wl   1/1     Running   0          12m
kube-system   coredns-5b6d4bd6f7-gh5p9   1/1     Running   0          12m
kube-system   kube-proxy-bn4n2           1/1     Running   0          8m38s
```

ノードに起動できる`Pod の制限数`と起動している`Pod の現在数`を確認します。
ここでは、ノードのインスタンスタイプは、`t3.small` を使用しており、起動できるPod の制限数は、`11`、起動しているPod の現在数は、`4` です。
```
$ kubectl describe nodes [ノード名]
...
Allocatable:
  attachable-volumes-aws-ebs:  25
  cpu:                         1930m
  ephemeral-storage:           18242267924
  hugepages-1Gi:               0
  hugepages-2Mi:               0
  memory:                      1507200Ki
  pods:                        11 ←起動できるPod の制限数

Non-terminated Pods:          (4 in total) ←起動しているPod の現在数
...
```

まずは、起動できるPod の制限数を超えて、合計 `12`個を起動させてみます。
```
$ kubectl create deployment nginx-deployment --image=nginx --replicas=8
```

起動しているすべてのPod の状態を確認すると、1つのPod の`STATUS` が `Pending` となり、起動ができません。
```
% kubectl get pod -A
NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE
default       nginx-deployment-84cd76b964-wtfr4   0/1     Pending   0          27s
...
```

起動できないPod のEvents のメッセージ を確認すると`0/1 nodes are available: 1 Too many pods.`と出力されています。
```
$ kubectl describe pod nginx-deployment-84cd76b964-wtfr4
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  55s (x12 over 12m)  default-scheduler  0/1 nodes are available: 1 Too many pods.
```

一旦、起動するPod の合計が`11`個になるようにスケールインさせます。
```
$ kubectl scale deployment --replicas=7 nginx-deployment 
```

起動できるPod の制限数を増やすため、下記コマンドで、Amazon VPC CNI に `/28 IPv4 アドレスプレフィックス`を割り当てる設定を追加します。
```
$ kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
```

`aws-node` に上記の設定がされていることを確認します。
(`aws-node`には、ノード上で動作するPod にVPC のIP アドレスを割り当てる機能があります。)
```
$ kubectl describe pod aws-node-lg4cz -n kube-system
...
    Environment:
      ENABLE_PREFIX_DELEGATION:               true
...
```

**ノードを再作成します。**

再作成後、ノードに起動できる`Pod の制限数`が `110`([Kubernetes scalability thresholds](https://github.com/kubernetes/community/blob/master/sig-scalability/configs-and-limits/thresholds.md) および推奨設定に基づいた値) に増えていることを確認します。
```
...
$ kubectl describe nodes [ノード名]
Allocatable:
  attachable-volumes-aws-ebs:  25
  cpu:                         1930m
  ephemeral-storage:           18242267924
  hugepages-1Gi:               0
  hugepages-2Mi:               0
  memory:                      1507200Ki
  pods:                        110 ←起動できるPod の制限数
...
```

もう一度、Pod を合計 `12`個起動させます。
```
$ kubectl scale deployment --replicas=8 nginx-deployment 
```

デフォルトの制限数(`11`)を超える`12`個のPod が起動できるようになっていることを確認します。
```
$ kubectl describe nodes [ノード名]
...
Allocatable:
  attachable-volumes-aws-ebs:  25
  cpu:                         1930m
  ephemeral-storage:           18242267924
  hugepages-1Gi:               0
  hugepages-2Mi:               0
  memory:                      1507200Ki
  pods:                        110 ←起動できるPod の制限数

Non-terminated Pods:          (12 in total) ←起動しているPod の現在数
...
```
ノード1台に起動できるPod の制限数を増やすことができました。
```
$ kubectl get pod -A
NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE
default       nginx-deployment-84cd76b964-4tzhd   1/1     Running   0          3h14m
default       nginx-deployment-84cd76b964-5ctgw   1/1     Running   0          3h14m
default       nginx-deployment-84cd76b964-cwcjq   1/1     Running   0          3h14m
default       nginx-deployment-84cd76b964-jc6r2   1/1     Running   0          3h14m
default       nginx-deployment-84cd76b964-pzgbx   1/1     Running   0          3h14m
default       nginx-deployment-84cd76b964-rq627   1/1     Running   0          3h14m
default       nginx-deployment-84cd76b964-vrlfh   1/1     Running   0          3h3m
default       nginx-deployment-84cd76b964-zgvg6   1/1     Running   0          3h14m
kube-system   aws-node-smrht                      1/1     Running   0          3h22m
kube-system   coredns-5b6d4bd6f7-46xt2            1/1     Running   0          3h14m
kube-system   coredns-5b6d4bd6f7-rp9n4            1/1     Running   0          3h14m
kube-system   kube-proxy-jlf9q                    1/1     Running   0          3h22m
```