🐕

eksのcontainer runtimeをcontainerdに入れ替える手順とその効果

2022/09/12に公開

はじめに

アダコテックのkackyです。弊社では機械学習エンジニアが効率よく仕事を進めるためにkubernetesを利用したクラウド開発基盤をAWS上に構築しました。eksのkubernetesバージョンも1.23がGAとなり、すでにcontainer runtimeとしてdockerは非推奨であり、1.24での削除も間近に迫っています。このため先行してcontainerdへの移行を試みたので具体的な手順と実施した結果どうなったかを発表します。

弊社以外でも様々な企業がこの課題に取り組んでいらっしゃいますのでこちらもご参考まで。

https://tech.drecom.co.jp/eks-deprecates-docker/

eks terraform module

残念ながら現状eksではデフォルトでdockerがcontainer runtimeとして使われるため、明示的にcontainerdをcontainer runtimeとして指定する設定を組込む必要があります。公式ドキュメントでcontainerdをcontainer runtimeに指定する方法は以下に記載されています。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/eks-optimized-ami.html#containerd-bootstrap

このうち、eksctlを使うと追加でcontainer runtimeを切り替えられるようですが、eksctlではクラスタで実施した設定をリビジョン管理しておくことができないため、本番での利用に向いているとは言えません。業務利用においては、CloudFormationやTerraformといったIaC(Infrastructure as Code)を使った構築を行うかと思います。

弊社のeks環境はTerraformを使ってデプロイ、管理を行っています。また、awsが提供しているterraform moduleを利用してeks環境の構築を行っています。

https://github.com/terraform-aws-modules/terraform-aws-eks

こちらを利用することで、eksだけでなく、ネットワーク設定や権限、マネージド型ノードグループ(MNG)などを効率的に設定できるようになるため積極的に利用しています。こちらを使った設定方法を紹介していきます。公式ドキュメントは下記のように書かれており、containerdをcontainer runtimeに指定する起動テンプレートを作成することになります。

異なるツールを使用してマネージド型のノードグループを作成する場合、そのノードグループのデプロイには起動テンプレートを使用する必要があります。起動テンプレート内で Amazon EKS 最適化 AMI ID を指定した上で、その起動テンプレートによりノードグループをデプロイし、次のユーザーデータを設定します。このユーザーデータは、引数を bootstrap.sh ファイルに渡します。ブートストラップファイルの詳細については、GitHub の bootstrap.sh を参照してください。

起動テンプレートの対応方法

起動テンプレートを自前で作成する場合

起動テンプレートを自前で作成し、マネージド型ノードグループに設定する方法です。この場合、cloudinit_configを作成してCONTAINER_RUNTIMEを有効化したuser_dataを作成して、起動テンプレートに入れるとよさそうです。(terraform moduleの内部でもそのように実現しています。)

# 最小構成テンプレート
data "cloudinit_config" "linux_eks_managed_node_group" {
  base64_encode = true
  gzip          = false
  boundary      = "//"

  # Prepend to existing user data suppled by AWS EKS
  part {
    content_type = "text/x-shellscript"
    content      = <<-EOT
    #!/bin/bash
    set -ex
    cat <<-EOF > /etc/profile.d/bootstrap.sh
    export CONTAINER_RUNTIME="containerd"
    EOF
    # Source extra environment variables in bootstrap script
    sed -i '/^set -o errexit/a\\nsource /etc/profile.d/bootstrap.sh' /etc/eks/bootstrap.sh
    EOT
  }
}

resource "aws_launch_template" "template" {
  user_data              = data.cloudinit_config.linux_eks_managed_node_group.rendered # user_dataを作成
}

起動テンプレートをterraform moduleで作成する場合

terraform moduleで起動テンプレートを作成する場合は、次のようにmanaged_node_groupを設定するとcontainerdで起動するようになります


module "eks" {
  source = "terraform-aws-modules/eks/aws"
  eks_managed_node_groups = {
    example = {
      enable_bootstrap_user_data = true
      bootstrap_extra_args       = "--container-runtime containerd"

      pre_bootstrap_user_data = <<-EOT
      export CONTAINER_RUNTIME="containerd"
      EOT    
    }
  }
}

Datadogの対応方法

kubernetesのメトリクス集約やログはdatadog agentをhelm経由で入れています。標準ではdatadog agentはdocker API経由でメトリクスを収集するように設定されているため、こちらをcontainerdを使った設定に切り替える必要があります。

datadog:
  # datadog.criSocketPath -- Path to the container runtime socket (if different from Docker)
  criSocketPath:  /var/run/containerd/containerd.sock

containerdに変えた結果

containerdにcontainer runtimeを切り替えた結果、現状起きている現象です。

メモリ消費がわりと減った

containerdのデプロイ前後でNodeのメモリ消費が2割くらい(1GB→0.8GB)減りました。これはPodの種類に関わらず全体的に2割くらいメモリ消費量が改善されました。

memusage

DatadogのKubernetesリソースに一部載らなくなった

DatadogではKubernetesのリソースが閲覧できるダッシュボードがありますが、containerdに変えたクラスタでは一部を除き一覧に載らない現象が起きています。

  • Overview 表示される
  • Pods 表示される
  • Clusters 表示されない
  • Nodes 表示されない
  • Workloads 表示されない
  • Network 表示されない
  • Storage 表示されない
  • AccessControl 表示されない

今のところは特に利用はしていないので特に対応は取っていませんが今後のアップデートに期待したいと思います。

Nodeごとのメトリクスを見るためのKubernetes Nodes Overviewは特に問題なく稼働しています。

おわりに

今回はkubernetesのcontainer runtimeをcontainerdに入れ替える手順とその効果をざっとお話しました。今後の活動としては次のようなところを考えています。

  • eStargzイメージとlazy pullingを使った高速コンテナ起動

せっかくcontainerdに入れ替えたのでこれを生かした新しい機能を試してみたいものです。大きな目玉としてはlazy pullingという手法による高速コンテナ起動でしょうか。特にAI系のタスクは重量級のコンテナイメージを扱うことが少なくないため、起動時間は長くかかります。イメージのpullとコンテナの起動を並列で行うことができれば全体の実行効率を改善することが期待できそうです。

  • base OSをBottlerocketに変える

現状eksでデフォルトで利用しているインスタンスのbase OSはAmazon Linux 2ですが、BottlerocketというAWSが開発したコンテナ運用に特化したOSに乗り換えることでインスタンスの効率アップが期待できます。ただAmazon Linux 2に比べて実績が少ないこと、現状起動テンプレートなどを更新する必要があること、ノードに不具合が発生した場合のトラブルシューティングなどに課題がありそうなので、これから調査を進めていきます。

こちらにeksとBottlerocketの実例があります。
https://blog.inductor.me/entry/2021/11/02/195150

最後に、アダコテックはエンジニアを含め、製造業の革新に取り組んでくださる仲間を募集しています。気になるポジションがありましたら気軽にエントリーください。

https://herp.careers/v1/adacotech

Discussion