grasys blog

Kubernetes のイベント駆動オートスケールをローカル環境で動かしてみた。

こんにちは。shirota です。
「Kubernetes の…」って入力したとたん「タイトル長くならないかな…」って不安になりました。
ちなみに「k8s」って略して書いたりもしますが、あれは数略語(ヌメロニム)って言うらしいです。

さてさて、コンテナ・オーケストレーションのための OSS、Kubernetes ですが、
運用していると様々な理由で Pod の数を制御したくなる場面があると思います。

例えば、
(1)開発環境において、夜間は使っていないので Pod の数を減らしてコストを削減したい
(2)本番環境において、負荷状況に応じて Pod の数を自動で調整して需要に応えたい
などなど。

これらの課題を解決するために、
(1)の場合、時間帯を条件として制御できそうです。
(2)の場合、CPU 使用率やアクセス数を指標に制御できそうです。

このように、サービスの特徴や背景によって条件は様々なため、柔軟に設定できることが望まれます。
今回はイベント駆動型のオートスケーラー KEDA を使用して、柔軟に、且つ簡単にオートスケールの設定ができるのか見ていきたいと思います!

今回の目標

KEDA の公式ページを見ると様々なスケーラーがあります。
今回はこの中から Cron を使用して、時間指定でのオートスケールの動作確認を目標に進めていきます。
これができれば、上で触れた(1)の条件を満たせそうです。

今回は minikube を使用してローカル環境に作成した Kubernetes クラスターを使います。
また、KEDA のインストールには Helm を使用します。

  • minikube(v1.36.0)
  • helm(v3.18.4)

動かしてみる

Cluster 作成

minikube の設定はデフォルト(CPUs=2、Memory=2048MB)のまま、クラスターを作成します。

$ minikube start

Nginx をデプロイ

スケール対象として使用するアプリケーションは何でも良いのですが、今回は Kubernetes の公式ページに記載されている Nginx のデプロイメントを使用します。

まずは公式のサンプルをローカルに保存します。

curl https://raw.githubusercontent.com/kubernetes/website/main/content/ja/examples/controllers/nginx-deployment.yaml > deployment.yaml

cat コマンド等で内容に問題がないことが確認できたら、デプロイします。
default の Namespace を使用します。

kubectl apply -f deployment.yaml -n default

Nginx がデプロイできたことを確認します。

$ kubectl get pods -n default
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           3m11s

KEDA をデプロイ

KEDA 用の Namespace を作成します。

kubectl create ns keda

Helm を使用してインストールします。

helm repo add kedacore https://kedacore.github.io/charts  
helm repo update
helm install keda kedacore/keda --namespace keda

KEDA がデプロイできたことを確認します。

$ kubectl get deploy -n keda
NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
keda-admission-webhooks           1/1     1            1           13h
keda-operator                     1/1     1            1           13h
keda-operator-metrics-apiserver   1/1     1            1           13h

スケールの設定

Cron を使用して時間をトリガーにしたスケールの設定をしていきます。
KEDA が使用するトリガーとスケールの動作を定義する ScaledObject は対象となるリソースと同じ Namespace に作成する必要がありますので、今回は default の Namespace に作成します。

スケール対象となるデプロイメントを確認します。

$ kubectl get pods -n default
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           3m11s

Cron のスケールオブジェクトを作成します。
公式ドキュメントを参考に以下の条件を満たすように YAML ファイルを書いていきます。

  • Timezone は Asia / Tokyo
  • 15:00〜15:10 の間、3 台の Pod を起動する
  • それ以外の時間帯は Pod を 0 台にする
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: cron-scaledobject
  namespace: default
spec:
  scaleTargetRef:
    name: nginx-deployment
  minReplicaCount: 0
  cooldownPeriod: 60
  triggers:
  - type: cron
    metadata:
      timezone: Asia/Tokyo
      start: 0 15 * * *
      end: 10 15 * * *
      desiredReplicas: "3"

実際の検証では cooldownPeriod を 60 に設定しているので、15:10 から 60 秒経過した後にスケールインしていくことが確認できました。

あと片付け

検証用に作成したクラスターを停止します。

minikube stop

検証用に作成したクラスターを削除します。

minikube delete

最後に

KEDA は公式のドキュメントが充実しており、インストールから動作確認までスムーズに行うことができました。
Kubernetes のデフォルトでは出来ないゼロスケーリング(Pod をゼロにすること)の挙動も見れて満足です。

実際の運用では cooldownPeriod をどのくらいに設定するかなど、アプリケーション側の仕様などを含めて検討する必要がありそうです。

今回は時間をトリガーにしましたが、Prometheus のクエリもサポートされているので、Nginx のメトリクスを使用したスケール制御もできそうです。
こちらは次の機会に紹介できればと思います。

最後までお読みいただきありがとうございました。


採用情報
お問い合わせ