こんにちは。技術本部の技術戦略推進部に所属している髙橋 洋樹です。私が所属する部署は全社の開発技術力の強化をミッションとしています。私はその中でもパブリッククラウドに関する全社共通基盤の企画・運用、アーキテクトの育成、ガイドラインの策定などを推進しており、過去に以下のブログを執筆しています。よろしければ併せてご覧ください。
今回はKubernetesのノードライフサイクルマネージャーであるKarpenter(カーペンター)について解説します。KarpenterはAWSが開発したオープンソースソフトウェアです。AWSの公式ブログにおいて、2024年8月16日にβ版から正式にバージョン1.0.0としてリリースされたことが公表されました。Karpenterはクラスタ運用を効率化する様々な機能を持っているのですが、サービスの存在をそもそも知らない方や、Cluster AutoScalerの単なる代替と認識されている方が多い印象ですので、これを機にKarpenterの価値を改めて知ってほしいと思います。
参考:Karpenter 1.0 がローンチされました
Karpenterに関して紹介する前にCluster AutoScaler(CAS)について復習しておきましょう。Kubernetesでコンテナを実行する場合、コンテナはPodという単位でノード(サーバ)にデプロイされます。負荷に応じてPodを増減させたい場合、Horizontal Pod AutoScalerを使うことになりますが、ノード側もPodの増加に合わせてスケールしないと空き容量が足りず、Podを増やすことができません。これを解決するのがCASです。CASはPodがPending(割当て待ち)状態になったのを検知すると、ノードを増やしPodをスケジュール(デプロイ)します。AWSではAmazon EC2 Auto Scaling Group(ASG)が呼び出されDesired Capacity(希望容量)が増えます。
そんなCASですが運用観点で課題があります。CASではPodの要求に応じて適切なノードを起動するためにNodeGroupの属性(vCPU、メモリ、AZ、購入オプションetc)を揃えることが推奨事項となっています。
この時、例えば複数の開発チームがクラスタを共有しているなど、クラスタ内のPodの要求が多岐に渡る場合、クラスタ管理者は事前に各Podの要求を把握して複数のNodeGroupを用意した上で、それぞれを管理する必要があります。管理すべきNodeGroupが多岐に渡った場合の、運用工数の増加とコスト最適化を両立する設定の難易度が高いのです。
こうした状況において、Karpenterは効力を発揮してくれます。KarpenterはPodがPending状態になると「直接」EC2フリートAPIを呼び出してインスタンスを起動します。
起動するEC2インスタンスは、Karpenterの設定(NodePool)とPodの要件を満たすものの中から、最も安価なものが選ばれます。ちなみに、NodePoolとは、CASにおけるNodeGroupと同様の位置づけのもので、いずれもノードの集合体を指します。
NodePoolでは、インスタンスタイプ、サイズなどの組み合わせに基づいて、インスタンス要件を柔軟に設定できます。CASではNodeGroupごとに特定のインスタンスタイプしか指定できないため、1つのPodを上げるのに過剰なリソースを持つノードが選ばれる可能性がありました。
Karpenterを用いたアプローチにより、NodePoolではNodeGroupのように各Podの要求に応じてクラスタを分割する必要がなくなるため、よりコスト効率の高いクラスタ運用が可能になります。またノードの起動にASGを経由しないぶんPodの起動が高速化するという副次的な効果もあります。
KarpenterはCASの単なる代替ではなく、運用の効率化につながる様々な機能を有しています。ここでは4つ紹介します。
Podの配置状態を見直してコストを最適化するもので、2つの機能から成ります。
後半のノードを置換する機能はCASにはないKarpenter特有の機能なので図を使って補足します。図でははじめ2台のm5.xlargeでPodが1つのみ動いている状況でしたが、Consolidationが実行されると、1台のm5.largeで2つのPodが集約される挙動をします。CAを利用する場合はm5.largeではなくm5.xlargeにPodが集約される挙動となるのでKarpenterのほうがよりコストを最適化できています。
望ましい仕様から外れたノードを中断する機能です。例えば、AWSが推奨しているノードのAMIが変更となった場合、それを検知してAMIを更新することが可能です。人手を介さずにノードのAMIを常に推奨版とできるのは運用コストの削減に寄与します。
ノードを指定時間後に中断する機能です。ノードの使用領域を定期的に開放したいような場合に有効です。
ノードに影響を与える可能性のある中断イベントを検知し、Podを退避してノードを終了する機能です。中断イベントというのはSpotインスタンスの中断などですね。自前でSpotインスタンスの中断対策を実装しなくてよいのは嬉しいところです。
なお、KarpenterでSpotインスタンスを扱う場合の注意事項があります。それはSpotインスタンスの中断通知を受け取ってから中断する2分以内にPodの退避が完了するようにクラスタを構成する必要があるということです。CASではEC2 Instance rebalance recommendationを利用できるため、Spotインスタンスの中断通知よりも前に(2分より長く)Podを退避することが可能です。CASと同じ感覚で使用するとハマりやすいので注意してください。
なお、Karpenterの導入方法は(CASから移行する場合も含めて)公式サイトで紹介されているのでそちらをご覧ください。Helm Chartで簡単にインストール可能となっています。
今回はKarpenterの概要と機能についてご紹介しました。KarpenterはCASと比較して特に以下のような環境においては運用効率化の効果を発揮します。該当する場合はぜひ検討してみてください。
当社では、AWS包括的技術支援サービスを提供しています。AWSの利用についてお困りのことがございましたらこちらからお気軽にお問い合わせください。