EKSのクラスターオートスケーラーのKarpenterを試してみた

2023.09.18

こんにちは、ゲームソリューション部のsoraです。
今回は、EKSのクラスターオートスケーラーのKarpenterを試してみたことについて書いていきます。

Karpenterとは

Karpenterは、Kubernetesにおけるクラスターオートスケーラーです。
アプリケーションの負荷やPodの増加に応じて、EC2やFargateなどで最適なノードを選定して起動することができます。

Cluster AutoScalerと比較したときのKarpenterのメリット

EKSでは、クラスターオートスケーリングとしてCluster AutoscalerとKarpenterがサポートされています。
KarpneterをCluster Autoscalerと比較したときの良い点は以下です。

  • インスタンスサイズ別や購入オプション別にノードグループを分割する必要がない
     Cluster Autoscalerでは、スケール対象のノードに対して、インスタンスサイズ別や購入オプション別(スポットかオンデマンドか)にノードグループを分割する必要があります。
     Karpenterでは、ノードグループで分けずとも、アプリケーションの負荷に応じて適切なインスタンスタイプを選定することができます。
  • ノードの起動が早い
     Cluster AutoscalerではAutoScalingグループを経由してスケールしますが、KarpenterはAutoScalingグループを経由しないことによりノードの起動が早いです。

クライアント実行環境

それでは実際に構築とテストをしていきます。
クライアントとしてCloud9(インスタンスタイプ:t2.micro)を使用します。
Karpenterをインストールして使用する中でeksctl・kubectl・helmが必要なため、インストールしておきます。

今回の環境におけるそれぞれのバージョンは以下です。

$ eksctl version
0.154.0

$ kubectl version --short
Client Version: v1.27.1-eks-2f008fe
Kustomize Version: v5.0.1

$ helm version
version.BuildInfo{Version:"v3.12.3", GitCommit:"3a31588ad33fe3b89af5a2a54ee1d25bfe6eaa5e", GitTreeState:"clean", GoVersion:"go1.20.7"}

導入

以下公式ページにて導入手順が説明されています。
Getting Started with Karpenter
手順通りに進めていくだけのため、導入手順の説明は割愛します。

手順に従ってKarpenterを導入すると、5つのCloudFormationスタックが作成されます。

ノードはクラスタ構築時に指定した2台が立ち上がっていて、NamespaceのKarpenterの中にコントロール用のPodが2つ作られています。

$ kubectl get node
NAME                                                STATUS   ROLES    AGE     VERSION
ip-192-168-8-240.ap-northeast-1.compute.internal    Ready    <none>   5m6s    v1.27.4-eks-8ccc7ba
ip-192-168-88-218.ap-northeast-1.compute.internal   Ready    <none>   5m10s   v1.27.4-eks-8ccc7ba

$ kubectl get pod -A
NAMESPACE     NAME                         READY   STATUS    RESTARTS   AGE
karpenter     karpenter-6dbf97c49f-7kqjw   1/1     Running   0          111s
karpenter     karpenter-6dbf97c49f-fj25w   1/1     Running   0          111s
…

テスト

Karpenterでノードがスケールする動きを見ていきます。
手順に従って、テスト用のDeploymentを作成して、レプリカ数を5つに増加させます。

$ kubectl scale deployment inflate --replicas 5
$ kubectl get pod -A
NAMESPACE     NAME                         READY   STATUS    RESTARTS   AGE
default       inflate-7849c696cd-9b85q     1/1     Running   0          2m54s
default       inflate-7849c696cd-cd6vs     1/1     Running   0          2m54s
default       inflate-7849c696cd-mp997     1/1     Running   0          2m54s
default       inflate-7849c696cd-nfw45     1/1     Running   0          2m54s
default       inflate-7849c696cd-tcxvm     1/1     Running   0          2m54s
…

その後にノードを確認すると、もともと2台だったノードが1台増えて3台になっていることがわかります。

$ kubectl get node
NAME                                                STATUS   ROLES    AGE     VERSION
ip-192-168-44-24.ap-northeast-1.compute.internal    Ready    <none>   32s     v1.27.4-eks-8ccc7ba
ip-192-168-8-240.ap-northeast-1.compute.internal    Ready    <none>   5m42s   v1.27.4-eks-8ccc7ba
ip-192-168-88-218.ap-northeast-1.compute.internal   Ready    <none>   5m46s   v1.27.4-eks-8ccc7ba

AWSマネージメントコンソール上でも確認してみると、クラスタ構築時に指定した2台のインスタンスタイプとは異なるインスタンスタイプで、負荷に応じてインスタンスタイプを選定して起動していることがわかります。

参考情報

Autoscaling(AWS公式)
Karpenter公式
KarpenterとGraviton2を使った大規模ゲーム向けAgones on EKS を立ち上げるサンプル multi-cluster-allocation-demo-for-agones-on-eks の紹介
構成・説明
ソースコード(GitHub)

最後に

今回は、EKSのクラスターオートスケーラーのKarpenterを試してみたことを記事にしました。
どなたかの参考になると幸いです。