EKS で Containerd を有効化してみた (eksctl)

# はじめに

Kubernetes では、バージョン 1.24 で dockershim コンポーネントが完全に削除されました。dockershim は、Kubernetes 上で Docker API を呼びだすためのインターフェースを提供するブリッジの役割を担うソフトウェアです。EKS でも同様に、バージョン 1.24 以降、 dockershim が完全に削除されます。[こちらのドキュメント](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/dockershim-deprecation.html)に dockershim が削除されることが明記されています。dockersim の代わりに、CRI インターフェースを提供する Containerd が使われるようになります。

バージョン 1.21, 1.22, 1.23 では、引き続き dockershim が使えます。また、containerd を利用するためのオプションも用意されています。今回の記事では、この containerd を有効化した EKS を構築してみる記事となります。



# eksctl のインストール

EKS の構築には、eksctl を使っていきます。手元の環境にインストールします。

```
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin
eksctl version
```



バージョンを確認します。

```
> eksctl version
0.116.0
```



# EKS on EC2 クラスターを作成

eksctl で利用する AMI のバージョンを確認します。EKS のバージョンに合わせた AMI の指定をしていきます。

```
EKS_VERSION=1.23

aws ssm get-parameter \
    --name /aws/service/eks/optimized-ami/${EKS_VERSION}/amazon-linux-2/recommended/image_id \
    --query "Parameter.Value" --output text
```



作業用ディレクトリを作成します。　

```
mkdir ~/temp/eksctl/
cd ~/temp/eksctl/
```



eksctl の動作を指定するための YAML ファイルを、ヒアドキュメントで作成します。

- AMI 指定
- overrideBootstrapCommand で containerd を指定
- クラスター名を正しく指定

```
cat <<'EOF' > ~/temp/eksctl/eksctl-configure.yaml
apiVersion: eksctl.io/v1alpha5
iam:
  withOIDC: true
kind: ClusterConfig
kubernetesNetworkConfig:
  ipFamily: IPv4
managedNodeGroups:
- amiFamily: AmazonLinux2
  ami: ami-08ba895a802ee90a8
  desiredCapacity: 2
  name: ng-containerd
  ssh:
    allow: true
    publicKeyPath: /home/ec2-user/.ssh/id_rsa.pub
  overrideBootstrapCommand: |
    #!/bin/bash
    /etc/eks/bootstrap.sh eks-ec2-eksctl-cluster03 --container-runtime containerd
metadata:
  name: eks-ec2-eksctl-cluster03
  region: ap-northeast-1
  version: "1.23"
privateCluster:
  enabled: false
  skipEndpointCreation: false
vpc:
  autoAllocateIPv6: false
  cidr: 10.0.0.0/16
  clusterEndpoints:
    privateAccess: false
    publicAccess: true
  id: vpc-0b8b2123a16d03528
  manageSharedNodeSecurityGroupRules: true
  nat:
    gateway: Disable
  subnets:
    private:
      ap-northeast-1a:
        az: ap-northeast-1a
        cidr: 10.0.100.0/24
        id: subnet-0c414bf2d11f17bba
      ap-northeast-1c:
        az: ap-northeast-1c
        cidr: 10.0.101.0/24
        id: subnet-09023225144fa1c62
      ap-northeast-1d:
        az: ap-northeast-1d
        cidr: 10.0.102.0/24
        id: subnet-0cf48d891b1bea31c
    public:
      ap-northeast-1a:
        az: ap-northeast-1a
        cidr: 10.0.0.0/24
        id: subnet-0d9a1ae8571fa7c30
      ap-northeast-1c:
        az: ap-northeast-1c
        cidr: 10.0.1.0/24
        id: subnet-0355f72e6534092bf
      ap-northeast-1d:
        az: ap-northeast-1d
        cidr: 10.0.2.0/24
        id: subnet-0c4b7c352a610baf4
EOF
```



一番重要な個所は `overrideBootstrapCommand` です。bootstrap.sh に `--container-runtime containerd` と指定することで、1.23 以前の EKS で Containerd を有効化できます。

```
  overrideBootstrapCommand: |
    #!/bin/bash
    /etc/eks/bootstrap.sh eks-ec2-eksctl-cluster03 --container-runtime containerd
```



overrideBootstrapCommand で指定した文字は、EC2 にある Launch Template に反映されます。Launch Template の詳細画面に移動して

![image-20221031175208962.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/99cc88f8-55a2-b460-3a11-7333990f77ef.png)



Advanced details を開き

![image-20221031175232559.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/cb6e2f7b-f69f-55f2-5e8b-a3c10f5d5266.png)



User data に反映されています。

![image-20221105002257791.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/33a0e605-0194-cef8-7ccd-0efb0820d664.png)



それでは実際にデプロイをする前に、作成したファイル正しいか `--dry-run` で確認します。エラーが出なければ OK です。

```
eksctl create cluster \
-f eksctl-configure.yaml \
--dry-run
```



EKS のデプロイを行います。

```
eksctl create cluster \
-f eksctl-configure.yaml
```



実行例 : いろいろ表示が流れていきます。

```
2021-07-30 13:16:40 [ℹ]  eksctl version 0.58.0
2021-07-30 13:16:40 [ℹ]  using region ap-northeast-1
2021-07-30 13:16:41 [✔]  using existing VPC (vpc-0b8b2123a16d03528) and subnets (private:map[ap-northeast-1a:{subnet-0c414bf2d11f17bba ap-northeast-1a 10.0.100.0/24} ap-northeast-1c:{subnet-09023225144fa1c62 ap-northeast-1c 10.0.101.0/24} ap-northeast-1d:{subnet-0cf48d891b1bea31c ap-northeast-1d 10.0.102.0/24}] public:map[ap-northeast-1a:{subnet-0d9a1ae8571fa7c30 ap-northeast-1a 10.0.0.0/24} ap-northeast-1c:{subnet-0355f72e6534092bf ap-northeast-1c 10.0.1.0/24} ap-northeast-1d:{subnet-0c4b7c352a610baf4 ap-northeast-1d 10.0.2.0/24}])
2021-07-30 13:16:41 [!]  custom VPC/subnets will be used; if resulting cluster doesn't function as expected, make sure to review the configuration of VPC/subnets
```



この裏では、CloudFormation の Stack が自動的に作成されていく

![image-20210730131757972.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/44abd6cd-7fa8-eb20-dbb8-1980d0fd936a.png)



一定時間後、デプロイが終了して EKS クラスターが出来上がりました。

![image-20221030165401217.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e6f58798-0ab8-6a9c-74a8-74f6a6e4acc7.png)



# kubeconfig の生成

作成した EKS クラスターに接続するために、kubeconfig を生成します。

```
aws eks update-kubeconfig \
  --region ap-northeast-1 \
  --name eks-ec2-eksctl-cluster03
```



必要に応じて、コンテキストを切り替えます。

```
kubectl ctx
```



kubectl で、Node の情報を取得可能です。CONTAINER-RUNTIME が `containerd://1.6.6` となっています。

```
> kubectl get nodes -o wide
NAME                                            STATUS   ROLES    AGE    VERSION               INTERNAL-IP   EXTERNAL-IP      OS-IMAGE         KERNEL-VERSION                 CONTAINER-RUNTIME
ip-10-0-1-253.ap-northeast-1.compute.internal   Ready    <none>   5d7h   v1.23.9-eks-ba74326   10.0.1.253    xx.xx.xx.xx      Amazon Linux 2   5.4.209-116.367.amzn2.x86_64   containerd://1.6.6
ip-10-0-2-78.ap-northeast-1.compute.internal    Ready    <none>   5d7h   v1.23.9-eks-ba74326   10.0.2.78     xx.xx.xx.xx      Amazon Linux 2   5.4.209-116.367.amzn2.x86_64   containerd://1.6.6
```



# aws-auth の編集

EKS Cluster を作成した直後では、AWS のマネージメントに情報が表示されないことがあります。マネージメントコンソールで表示させるために、aws-auth を編集します。

まず、現在の設定状況を確認します。

```
kubectl get configmap -n kube-system aws-auth -o yaml
```



実行例

```
> kubectl get configmap -n kube-system aws-auth -o yaml
apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::xxxxxxxxxxxx:role/eksctl-eks-ec2-eksctl-cluster01-n-NodeInstanceRole-RUT1FYEVOH
      username: system:node:{{EC2PrivateDNSName}}
kind: ConfigMap
metadata:
  creationTimestamp: "2021-07-30T04:37:17Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "1664"
  uid: b0268943-b74c-4e78-ac84-ae8cfb162d5f
```



編集をします。

```
kubectl edit -n kube-system configmap/aws-auth
```



このように編集します。

```
apiVersion: v1
data:
  mapRoles: |
    - groups:
        - system:bootstrappers
        - system:nodes
      rolearn: arn:aws:iam::xxxxxxxxxxxx:role/eksctl-eks-ec2-eksctl-cluster01-n-NodeInstanceRole-RUT1FYEVOH
      username: system:node:{{EC2PrivateDNSName}}
    - rolearn: arn:aws:iam::xxxxxxxxxxxx:role/Admin
      username: AdminRole
      groups:
        - system:masters
kind: ConfigMap
metadata:
  creationTimestamp: "2021-07-30T04:37:17Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "1664"
  uid: b0268943-b74c-4e78-ac84-ae8cfb162d5f
```



以下の部分を追加しました。各環境に合わせた Role を指定します。

```
    - rolearn: arn:aws:iam::xxxxxxxxxxxx:role/Admin
      username: AdminRole
      groups:
        - system:masters
```



# EC2 に SSH にして Containerd を確認

まず、該当の Node では Docker サービスは稼働していません。

```
[root@ip-10-0-1-253 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: https://docs.docker.com
```



そのため、もちろん docker コマンドは利用できません

```
[root@ip-10-0-1-253 ~]# docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```



代わりに containerd が稼働しています。

```
[root@ip-10-0-1-253 ~]# systemctl status containerd
● containerd.service - containerd container runtime
   Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/containerd.service.d
           └─10-compat-symlink.conf
   Active: active (running) since Sun 2022-10-30 07:41:04 UTC; 5 days ago
     Docs: https://containerd.io
 Main PID: 2945 (containerd)
    Tasks: 79
   Memory: 1.6G
   CGroup: /system.slice/containerd.service
           ├─ 2945 /usr/bin/containerd
           ├─ 3568 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 47e3da0f2dd40343a9610fc3b95fd26ce41977ffcdadba62bfb96ebe515351d2 -address /run/containerd/containerd.sock
           ├─ 3572 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 0a3bc54254113bfa92758f5cf1657905f2063c9aa1ba4d0f44b7eb03261a7255 -address /run/containerd/containerd.sock
           ├─ 4445 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 401f7f5d0535a46cd548b74f818b15b384a6e31160717682dd45aa600f85b617 -address /run/containerd/containerd.sock
           ├─ 4454 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 5e810b10f01de47970c07a558582375eeba39f0747799b0089ed5f5d38238350 -address /run/containerd/containerd.sock
           └─20576 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id 86544a79c523815c60dd1cc9a4b37ff91e4f789297e44be0e4936d8f9c1eaac5 -address /run/containerd/containerd.sock

Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.204157356Z" level=info msg="shim disconnected" id=e3c316939c0f59f59d4043cacd8f9cd7dd24e1cc...8fc2d70465
Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.204203283Z" level=warning msg="cleaning up after shim disconnected" id=e3c316939c0f59f59d4...ace=k8s.io
Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.204216453Z" level=info msg="cleaning up dead shim"
Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.212056808Z" level=warning msg="cleanup warnings time=\"2022-11-04T01:30:34Z\" level=info m...runc.v2\n"
Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.883594540Z" level=info msg="CreateContainer within sandbox \"86544a79c523815c60dd1cc9a4b37...tempt:3,}"
Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.885576236Z" level=info msg="RemoveContainer for \"8cf7267312093e58c8820806629831f5e963f556...5756c56\""
Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.894339560Z" level=info msg="RemoveContainer for \"8cf7267312093e58c8820806629831f5e963f556...cessfully"
Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.904091408Z" level=info msg="CreateContainer within sandbox \"86544a79c523815c60dd1cc9a4b37...e9f5a67\""
Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.904566641Z" level=info msg="StartContainer for \"1808916d0e5983729db903d7dd430ec2f917e6c2d...e9f5a67\""
Nov 04 01:30:34 ip-10-0-1-253.ap-northeast-1.compute.internal containerd[2945]: time="2022-11-04T01:30:34.978766226Z" level=info msg="StartContainer for \"1808916d0e5983729db903d7dd430ec2f917e6c2d...cessfully"
Hint: Some lines were ellipsized, use -l to show in full.
```



Systemd の定義ファイルはこんな感じです

```
[root@ip-10-0-1-253 ~]# cat /usr/lib/systemd/system/containerd.service
# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerd

Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target
```



nerdctl をインストールします。containerd では、docker コマンドの代わりに、nerdctl コマンドを実行できます。

```
wget https://github.com/containerd/nerdctl/releases/download/v1.0.0/nerdctl-1.0.0-linux-amd64.tar.gz
```



path に格納

```
sudo tar Cxzvvf /usr/local/bin nerdctl-1.0.0-linux-amd64.tar.gz
```



namespaces の一覧を確認すると、`k8s.io` のネームスペースが見えます。

```
[root@ip-10-0-1-253 ~]# nerdctl namespace ls
NAME      CONTAINERS    IMAGES    VOLUMES    LABELS
k8s.io    9             14        0
```



`k8s.io` のネームスペースで稼働しているコンテナ一覧を確認します。いくつかのイメージが稼働している様子がわかります。

```
[root@ip-10-0-1-253 ~]# nerdctl --namespace k8s.io ps -a
CONTAINER ID    IMAGE                                                                                          COMMAND                   CREATED         STATUS     PORTS    NAMES
0a3bc5425411    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/eks/pause:3.5                                "/pause"                  5 days ago      Up                  k8s://kube-system/aws-node-wgxvj
1808916d0e59    xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/toolbox:0.0.1                                "/bin/bash -c sleep …"    15 hours ago    Up                  k8s://default/toolbox-deployment-5749fb995b-cl5z5/toolbox
273f7439f699    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/eks/coredns:v1.8.7-eksbuild.2                "/coredns -conf /etc…"    5 days ago      Up                  k8s://kube-system/coredns-69cfddc4b4-qvck5/coredns
401f7f5d0535    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/eks/pause:3.5                                "/pause"                  5 days ago      Up                  k8s://kube-system/coredns-69cfddc4b4-pqgsl
47e3da0f2dd4    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/eks/pause:3.5                                "/pause"                  5 days ago      Up                  k8s://kube-system/kube-proxy-qmwhr
5e810b10f01d    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/eks/pause:3.5                                "/pause"                  5 days ago      Up                  k8s://kube-system/coredns-69cfddc4b4-qvck5
86544a79c523    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/eks/pause:3.5                                "/pause"                  4 days ago      Up                  k8s://default/toolbox-deployment-5749fb995b-cl5z5
9eb655b381f1    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/eks/coredns:v1.8.7-eksbuild.2                "/coredns -conf /etc…"    5 days ago      Up                  k8s://kube-system/coredns-69cfddc4b4-pqgsl/coredns
aae1575e9b34    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni-init:v1.10.4-eksbuild.1       "/init/init.sh"           5 days ago      Created             k8s://kube-system/aws-node-wgxvj/aws-vpc-cni-init
e3c316939c0f    xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/toolbox:0.0.1                                "/bin/bash -c sleep …"    45 hours ago    Created             k8s://default/toolbox-deployment-5749fb995b-cl5z5/toolbox
e7ad6aff7cb5    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/eks/kube-proxy:v1.23.7-minimal-eksbuild.1    "kube-proxy --v=2 --…"    5 days ago      Up                  k8s://kube-system/kube-proxy-qmwhr/kube-proxy
fe0cddb39cbd    zzzzzzzzzzz.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni:v1.10.4-eksbuild.1            "/app/entrypoint.sh"      5 days ago      Up                  k8s://kube-system/aws-node-wgxvj/aws-node
```



# 検証を通じてわかったこと

- eksctl では、 `overrideBootstrapCommand ` で containerd の有効化を指定可能。
- containerd を有効化すると、docker サービスは稼働していない。
- containerd では、docker コマンドの代わりに、nerdctl コマンドを利用可能。
- nerdctl では、Kubernetes のコンテナが `k8s.io` ネームスペースで稼働している。



# 参考URL

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started-eksctl.html

https://dev.classmethod.jp/articles/getting-started-amazon-eks-with-eksctl/

https://aws.amazon.com/jp/blogs/news/amazon-eks-1-21-released/

https://eksctl.io/usage/dry-run/