EKSのコンテナランタイムをcontainerdに変更する


使っているEKSのコンテナランタイムがdockerなのだが、将来的にdockerが[非サポートとなる](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/kubernetes-versions.html#available-versions)ので、containerdに変更した時のメモ。


## お試し
利用する環境変数を事前に設定する。
```
export EKS_VERSION=1.22
export CLUSTER_NAME=xxxxx
export REGION=us-east-1
export AMI_ID=$(aws ssm get-parameter \
    --name /aws/service/eks/optimized-ami/${EKS_VERSION}/amazon-linux-2/recommended/image_id \
    --query "Parameter.Value" --output text --region $REGION)
export NODEGROUP_NAME=containerd-nodegp
```

AMIのIDは[こちら](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/eks-optimized-ami.html)で公開されているものを利用してもよい。

次に設定ファイルを作成する。
```yaml
cat <<EOF > ./containerd_config.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: $CLUSTER_NAME
  region: $REGION
managedNodeGroups:
  - name: $NODEGROUP_NAME
    ami: $AMI_ID
    overrideBootstrapCommand: |
      #!/bin/bash
      /etc/eks/bootstrap.sh $CLUSTER_NAME --container-runtime containerd
EOF
```

NodeGroupを作成する。
```
eksctl create nodegroup -f containerd_config.yaml
```
オフィシャルの手順だと`--version`を要求していたが、手元の環境では`-f`と競合したため、バージョン指定は削除している。

コマンドが完了すると、ノードが増えていることが分かる（AGEが短いノード＝新規ノード）。
```
$ kubectl get node
NAME                                     STATUS   ROLES    AGE     VERSION
fargate-ip-192-168-100-86.ec2.internal   Ready    <none>   23h     v1.22.6-eks-14c7a48
ip-192-168-116-142.ec2.internal          Ready    <none>   11h     v1.22.9-eks-810597c
ip-192-168-50-17.ec2.internal            Ready    <none>   3m24s   v1.22.9-eks-810597c
ip-192-168-8-142.ec2.internal            Ready    <none>   3m31s   v1.22.9-eks-810597c
```

kubectl pluginのnode-shellを利用して、containerdが使えるようになっていることを確認する。
```
$ kubectl node-shell ip-192-168-8-142.ec2.internal -- ctr container list
spawning "nsenter-538mva" on "ip-192-168-8-142.ec2.internal"
CONTAINER    IMAGE    RUNTIME
pod "nsenter-538mva" deleted
```

※追記：
確認は`kubectl get node -o wide`の`CONTAINER-RUNTIME`を見る方が楽。
```
NAME                             STATUS   ROLES    AGE     VERSION               INTERNAL-IP      EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION                 CONTAINER-RUNTIME
ip-192-168-103-69.ec2.internal   Ready    <none>   4d20h   v1.23.9-eks-ba74326   192.168.103.69   <none>        Amazon Linux 2   5.4.209-116.367.amzn2.x86_64   containerd://1.6.6
ip-192-168-105-68.ec2.internal   Ready    <none>   4d20h   v1.23.9-eks-ba74326   192.168.105.68   <none>        Amazon Linux 2   5.4.209-116.367.amzn2.x86_64   containerd://1.6.6
ip-192-168-89-215.ec2.internal   Ready    <none>   4d20h   v1.23.9-eks-ba74326   192.168.89.215   <none>        Amazon Linux 2   5.4.209-116.367.amzn2.x86_64   containerd://1.6.6
```


ここでは動作確認のみ実施したかったため、作成したNodeGroupは一旦削除する。
```
eksctl delete nodegroup --cluster $CLUSTER_NAME --name $NODEGROUP_NAME --region $REGION
```

## 実際に利用する

普段使っているNodeGroupの設定値に組み込む。

```yaml
cat <<EOF > ./mynodegroup.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: ${CLUSTER_NAME}
  region: ${REGION}
managedNodeGroups:
- name: $NODEGROUP_NAME
  ami: $AMI_ID
  overrideBootstrapCommand: |
    #!/bin/bash
    /etc/eks/bootstrap.sh $CLUSTER_NAME --container-runtime containerd
  desiredCapacity: 3
  minSize: 0
  maxSize: 4
  volumeSize: 60
  spot: true
  instanceTypes:
  - m4.xlarge
  - m5.xlarge
  - m5a.xlarge
  - m5ad.xlarge
  - m5d.xlarge
  - t2.xlarge
  - t3.xlarge
  - t3a.xlarge
  iam:
    withAddonPolicies:
      autoScaler: true
      cloudWatch: true
      albIngress: true
  privateNetworking: true
  taints:
    - key: spotInstance
      value: "true"
      effect: PreferNoSchedule
  labels:
    team: myteam
  tags:
    alpha.eksctl.io/nodegroup-name: $NODEGROUP_NAME
    alpha.eksctl.io/nodegroup-type: managed
    k8s.io/cluster-autoscaler/node-template/label/team: myteam
    k8s.io/cluster-autoscaler/node-template/taint/spotInstance: "true:PreferNoSchedule"
EOF
```

NodeGroupを作成する。
```
eksctl create nodegroup -f mynodegroup.yaml
```
こちらでも特に問題なく作成でき、containerdで利用できることが確認できた。
```
$ kubectl node-shell ip-192-168-77-185.ec2.internal -- ctr c list
spawning "nsenter-50gb6a" on "ip-192-168-77-185.ec2.internal"
CONTAINER    IMAGE    RUNTIME
pod "nsenter-50gb6a" deleted
```