Kubernetes Event-driven Autoscaling(KEDA)で実現する夜間・休日のインフラコスト削減

Kubernetes Event-driven Autoscaling(KEDA)で実現する夜間・休日のインフラコスト削減

はじめに

こんにちは、データシステム部MLOpsブロックの木村です。MLOpsブロックでは、継続的にGoogle Cloudのコスト削減に取り組んでいます。その一環として、夜間や休日といった利用されていない時間帯にも稼働し続けることで発生していた、開発・検証・テスト環境の余分なコストに着目しました。

この課題を解決するために、MLOpsブロックではKubernetes Event-driven Autoscaling(以下KEDA)を導入しました。KEDAは、Kubernetes環境でイベントドリブンによるオートスケールを実現するオープンソースのツールです。KEDAにより利用されていない時間帯のPodを停止させ余分なコストを削減しました。

本記事ではKEDAを導入したモチベーションや効果、導入する際に直面した課題や、加えて事故なく本番環境へ適用するために工夫した点をご紹介します。KEDAの導入でさらなるコスト削減を目指したい方々の助けになれば幸いです。

目次

背景

前提として、MLOpsチームではパブリッククラウドにGoogle Cloudを使用し、Google Kubernetes Engine(以下、GKE)上にサービスを構築しています。また、1Pod1Nodeの構成をとっているため、Podの数に対応するNodeが存在します。GKEのNodeはCompute EngineのVM上で稼働し、稼働時間と台数・マシンタイプに応じてコストが発生します。加えて、バッチ処理のような単発実行のPodとは異なり、API Podは常時稼働が必要です。保守対象のAPIも52個と多く、GKEのNodeを実行しているCompute EngineのコストがGoogle Cloud全体のコストの中で大きな割合を占めていることが課題となっていました。

この課題を解決するために、MLOpsブロックではPod台数を見直すことでCompute Engineのコストを削減できないか検討しました。

本番環境ではユーザー影響を出さないように、可用性・パフォーマンスの観点から十分なPodの台数を維持する必要があります。そのため、Podの台数を減らす際は慎重に対応する必要があります。一方、開発・検証・テスト環境では、開発者が開発・検証・テスト目的でのみ利用されるため、営業時間外は稼働する必要がありません。

そこで、開発・検証・テスト環境のPodを営業時間外に停止した場合、どの程度のコスト削減が可能か試算したところ、Compute Engineのコストを約30%削減できると見込まれました。

これらを踏まえ、開発・検証・テスト環境では営業日以外にPodを停止し、本番環境では時間帯ごとのトラフィックを分析した上でPodをスケールインすることで、余分なVMコストを削減する方針に決定しました。

KEDAを導入した経緯

これまでMLOpsブロックではKubernetes標準のHorizontal Pod Autoscaler(以下、HPA)を使用して、Podのオートスケールを行っていました。しかし、Compute Engineのコスト削減を進める中で、標準のHPAだけでは対応が難しい課題に直面しました。

標準のHPAでは対応できなかった課題は、以下の2点です。

1. Podの台数を0台にできない

標準のHPAでは、最小でも1台までしかスケールインできないため、深夜や週末などの時間帯にもPodが維持され、GKEで余分なコストが発生していました。

2. スケジュールベースのオートスケールができない

標準のHPAではトラフィックベースのスケールが可能です。しかし、負荷の増加を検知してからPodのスケジューリングや起動が完了するまで時間がかかるため、急激な負荷変動には対応できず、スケールアウトが負荷の変動に間に合わないことがあります。そのため、本番環境ではトラフィックの多い週末を基準にPod数を維持する必要があり、ピーク時と比較して負荷の少ない時間帯でも過剰なリソースが維持され、余分なコストが発生していました。

解決策

標準のHPAの課題を解決するために、MLOpsブロックではKEDAを導入しました。KEDAを活用することで柔軟なスケール要件に対応できます。具体的には、「開発・検証・テスト環境のPodを夜間や週末の業務時間外に完全停止すること」や「本番環境のPodを負荷の少ない時間帯に合わせてスケールインすること」を実現できます。また事前にスケジュールを設定できる点はコスト面以外にも利点があります。従来の運用では、負荷試験時に検証環境のPod数を本番環境と同じ台数まで増加させたい場合など、一時的にPodをスケールアウトし、作業完了後にスケールインしていました。このとき完了後のスケールインを忘れるミスが度々ありました。スケールアウト・スケールインを事前にスケジュール設定することで、作業漏れの防止にもつながります。

KEDAの導入

KEDAの概要

KEDAの主要な機能と構成コンポーネントをご紹介します。

KEDAは標準のHPAの仕組みを活用しながら、次の拡張機能を提供し、柔軟なスケーリングを可能にします。

  • ゼロスケール
    Podを完全に停止する1→0や0→1のスケールが可能。

  • イベントドリブンなオートスケール
    CPUやメモリに加えて、メッセージキューの長さやAPIリクエスト数などの外部メトリクスをトリガーにスケーリングを制御できる。

  • スケジュールベースのオートスケール
    KEDAのCustom ResourceであるScaledObjectにあらかじめスケジュールを設定することで、特定の時間帯や曜日にPod数をオートスケールできる。

KEDAのアーキテクチャ

次図はKEDAのアーキテクチャを示す概念図です。KEDAの公式ドキュメントより引用します。

KEDAアーキテクチャ

KEDAはKubernetes標準のHPAと連携し、Podの台数を0⇄1にスケールできる拡張機能を提供します。

ScaledObjectというカスタムリソースに、スケール対象やトリガー(CPU使用率、スケジュールなど)を設定できます。KEDAはその設定に基づき外部イベントを定期的に監視し、必要に応じてHPAの作成とスケールを行います。

HPAが1⇄nのスケールを担い、KEDAが0⇄1のスケールを補完することで、より柔軟なオートスケールが可能になります。

KEDAのコンポーネント

KEDAには3つの主要なコンポーネントが存在します。

実装コンポーネント 機能 役割
keda-operator KubernetesのDeploymentを0⇄1にスケールし、イベントがないときはPodをスケールインする Agent
keda-operator-metrics-apiserver 外部メトリクスなどのイベントをHPAに提供し、スケールアウトを支援する Metrics
keda-admission ScaledObjectなどのリソース変更が適用される前に、自動的にバリデーションを行い、誤った設定の適用を防止する Admission Webhooks

KEDAの導入によるコスト削減の試算

KEDAを利用するとゼロスケールとスケジュールベースのオートスケールにより、Compute Engineのコスト削減を実現できます。一方でKEDAのコンポーネントを稼働するための追加コストも発生します。小規模なクラスタやPod停止時間が短い場合、KEDAの追加コストがPod停止によるコスト削減を上回るおそれがあります。そのため、導入前に期待されるコスト削減効果を見積もることが重要です。

KEDA導入による週あたりのCompute Engineの削減コストは、次の式で見積もりました。

KEDA導入によるCompute Engineの削減コスト = Compute Engineのコスト ×(週あたりの停止時間 / 168h)- KEDAの運用コスト

MLOpsブロックでは、保守している52個のAPIのうち、開発・検証・テスト環境にある38個のAPIに対応するPod(38台)を対象としました。

これらのPodは、平日夜間(1日8時間 × 平日5日間)と、土日終日(1日24時間 × 休日2日間)の稼働が不要なため、週あたり合計88時間分を停止対象としています。38台のPodを対象に停止することで、週あたり3,344Pod時間(38台 × 88時間)の削減効果が見込めます。

一方で、KEDAの運用には、開発・検証・テストでPodが15台必要です。そのため、週あたりのKEDAの運用コストは2,520Pod時間(15台 × 24時間 × 7日)となります。

以上より週あたり824Pod時間の削減となります。

加えてAPIが稼働するNodeは、KEDAが稼働するNodeよりも高スペックなマシンタイプを要求するNodeが多くあります。そのため実際の削減コストはPod時間以上の効果が見込めます。

さらに、MLOpsブロックではモニタリングにDatadogを使用しています。Datadog AgentはDaemonSetとして各Node上で常に動作しているため、起動中のNodeごとにモニタリングコストが発生します。KEDAによって不要な時間帯のPodが停止されることで、Datadogのモニタリング対象リソースも削減され、Datadogのコスト削減にもつながります。

これらの結果から、KEDAの導入はCompute EngineおよびDatadogの両面で、十分なコスト削減効果が見込めると判断しました。

KEDAの導入方法

ここからは具体的なKEDAの導入方法を説明します。
次の項目について実際のコードを交えて解説します。

  • インストール方法
  • Podのリソース設定と冗長化
  • ScaledObjectの設定
  • スケジュールベースのトリガー設定
  • CPUトリガーの設定
  • スケジュール・CPU使用率を組み合わせたトリガー設定

インストール方法

KEDAを使用するには、KEDAのCustom OperatorをKubernetesクラスタに追加する必要があります。

インストール方法については、公式ドキュメントを参考にしました。また、KEDAのバージョンとKubernetesの互換性については、KEDA公式ドキュメント(GitHub) を事前に参照してください。MLOpsブロックではKubernetesv1.30系を使用しており、KEDA v2.16.0 との互換性を確認した上で導入しました。

KEDAのインストール方法には、マニフェストを直接適用する方法と kustomize を利用して環境ごとに管理する方法の2つがあります。

マニフェストを直接適用する方法

次のコマンドでKEDAv2.16.0をKubernetesクラスタにインストールできます。この操作によりKEDAのCustom Resource Definition(CRD)やCustom Controller、関連リソースが作成されkeda名前空間にデプロイされます。またScaledJobのCRDはサイズが大きく、クライアント側で処理しきれないため、以下のように--server-sideを指定してKubernetes APIサーバー側で適用する必要があります。

> kubectl apply --server-side -f https://github.com/kedacore/keda/releases/download/v2.16.0/keda-2.16.0.yaml

namespace/keda serverside-applied
customresourcedefinition.apiextensions.k8s.io/cloudeventsources.eventing.keda.sh serverside-applied
customresourcedefinition.apiextensions.k8s.io/clustercloudeventsources.eventing.keda.sh serverside-applied
customresourcedefinition.apiextensions.k8s.io/clustertriggerauthentications.keda.sh serverside-applied
customresourcedefinition.apiextensions.k8s.io/scaledjobs.keda.sh serverside-applied
customresourcedefinition.apiextensions.k8s.io/scaledobjects.keda.sh serverside-applied
customresourcedefinition.apiextensions.k8s.io/triggerauthentications.keda.sh serverside-applied
serviceaccount/keda-operator serverside-applied
role.rbac.authorization.k8s.io/keda-operator serverside-applied
clusterrole.rbac.authorization.k8s.io/keda-external-metrics-reader serverside-applied
clusterrole.rbac.authorization.k8s.io/keda-operator serverside-applied
rolebinding.rbac.authorization.k8s.io/keda-operator serverside-applied
rolebinding.rbac.authorization.k8s.io/keda-auth-reader serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/keda-hpa-controller-external-metrics serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/keda-operator serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/keda-system-auth-delegator serverside-applied
service/keda-admission-webhooks serverside-applied
service/keda-metrics-apiserver serverside-applied
service/keda-operator serverside-applied
deployment.apps/keda-admission serverside-applied
deployment.apps/keda-metrics-apiserver serverside-applied
deployment.apps/keda-operator serverside-applied
apiservice.apiregistration.k8s.io/v1beta1.external.metrics.k8s.io serverside-applied
validatingwebhookconfiguration.admissionregistration.k8s.io/keda-admission serverside-applied
kustomizeを使用する方法

MLOpsチームでは、KEDAのマニフェストに対して環境ごとのパッチを適用できるようにするため、kustomize を活用し、KEDAをインストールしました。

kustomizeは、ベースとなるマニフェストと環境ごとの差分を管理するツールです。環境差分のパッチをベースマニフェストに適用することで、各環境に対応したマニフェストを生成・管理します。

kustomization.yamlに以下のマニュフェストを記載し、kustomize buildで生成したマニフェストをkubectl applyすることでKEDAをインストールできます。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: keda
resources:
    - https://github.com/kedacore/keda/releases/download/v2.16.0/keda-2.16.0.yaml

Podのリソース設定と冗長化

KEDAの各コンポーネントに対して、コンテナに割り当てるCPU・メモリの配分と水平スケールによる冗長化の構成値を適切に設定する必要があります。

MLOpsブロックでは、KEDAの公式ドキュメントに記載されている設定値を基準にしつつ、本番環境に適したリソース配分と冗長化構成を採用しました。

Podのリソース設定

CPU・メモリの使用率には余裕があるためデフォルトの設定値を適用しました。CPU・メモリの使用状況を確認し、必要に応じてResource RequestsとResource Limitsを調整してください。

pod CPU (Limits/Request) Memory (Limits/Request)
keda-admission 1 core / 1 core 1000Mi / 1000Mi
keda-metrics-apiserver 1 core / 1 core 1000Mi / 1000Mi
keda-operator 1 core / 1 core 1000Mi / 1000Mi
冗長化の設定

一方、KEDAの冗長化設定は開発・検証・テストの各環境、および本番環境で異なる値を設定しました。KEDAの公式ドキュメントでは、高可用性を考慮した構成としてkeda-metrics-apiserverは1台、keda-operatorは2台が推奨されています。開発・検証・テスト環境はこの値を使用し、本番環境ではさらなる可用性向上のため、どちらも3台構成を採用しました。

pod 開発環境 検証環境 テスト環境 本番環境
keda-admission 1台構成 1台構成
keda-metrics-apiserver 2台、AZ分散 3台構成、AZ分散
keda-operator 2台、AZ分散 3台構成、AZ分散

以下は開発・検証・テストの各環境におけるKEDAコンポーネントのDeployment構成です。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-admission
  namespace: keda
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: keda-admission-webhooks
        resources:
          requests:
            cpu: 1000m
            memory: 1Gi
          limits:
            cpu: 1000m
            memory: 1Gi
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: cloud.google.com/gke-nodepool
                operator: In
                values:
                - <nodepool名>
      tolerations:
      - key: "dedicated"
        operator: "Equal"
        value: <nodepool名>
        effect: "NoSchedule"
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-metrics-apiserver
  namespace: keda
spec:
  replicas: 2
  template:
    spec:
      containers:
      - name: keda-metrics-apiserver
        resources:
          requests:
            cpu: 1000m
            memory: 1Gi
          limits:
            cpu: 1000m
            memory: 1Gi
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: cloud.google.com/gke-nodepool
                operator: In
                values:
                - <nodepool名>
      tolerations:
      - key: "dedicated"
        operator: "Equal"
        value: <nodepool名>
        effect: "NoSchedule"
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-operator
  namespace: keda
spec:
  replicas: 2
  template:
    spec:
      containers:
      - name: keda-operator
        resources:
          requests:
            cpu: 1000m
            memory: 1Gi
          limits:
            cpu: 1000m
            memory: 1Gi
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: cloud.google.com/gke-nodepool
                operator: In
                values:
                - <nodepool名>
      tolerations:
      - key: "dedicated"
        operator: "Equal"
        value: <nodepool名>
        effect: "NoSchedule"

本番環境では、上記のマニフェストに対してkustomizeを使用してパッチを当てることで環境ごとに異なる設定値を上書きして適用しています。

次の記述はkustomizeを使用して本番環境に適用するパッチ内容です。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-metrics-apiserver
  namespace: keda
spec:
  replicas: 3
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keda-operator
  namespace: keda
spec:
  replicas: 3

上記マニフェストを適用することでkeda-metrics-apiserverkeda-operatorを3台で構成でき、冗長化できます。

スケジュールベースのトリガー設定

ScaledObjectに次のマニフェストを適用すると、特定の時間にPodをオートスケールできます。この節では主要な設定のみを抜粋しています。詳細な設定方法は、公式ドキュメントを参照してください。

spec:
  scaleTargetRef:
    name: <deployment-name>  # スケール対象のDeployment名
  minReplicaCount: 0  # 最小Replica数を0に設定(ゼロスケールを有効化)
  maxReplicaCount: 3  # 最大Replica数を3に設定
  triggers:
    - type: cron
      metadata:
        timezone: Asia/Tokyo  # タイムゾーンを指定
        start: 0 7 * * 1-5  # 平日の午前7時にスケーリングを開始
        end: 0 23 * * 1-5  # 平日の午後23時にスケーリングを終了
        desiredReplicas: "1"  # スケールアウト時のPod数
ゼロスケール時に注意すべきPDBの設定

KEDAでPodをゼロスケールさせる場合、PodDisruptionBudget(PDB)の設定を見直す必要があります。PDBとは、Kubernetesにおいて常に最低限稼働させておくべきPod数を保証するための仕組みです。

PDBのminAvailableに1以上が設定されていると、「最低でも1つのPodを稼働させる」という制約が働くため、Podのゼロスケールがブロックされます。

そのため、開発・検証・テスト環境などでゼロスケールを実現したい場合は、PDBのminAvailableを0に設定しておく必要があります。

CPU使用率に応じたトリガー設定

HPAと同様にCPU使用率をトリガーとするスケールも可能です。

負荷に応じてPodをスケールするには、次のマニフェストのようにCPUトリガーを設定します。この設定により、CPU使用率が50%を超えるとPodが自動的にスケールアウトします。

triggers:
  - type: cpu
    metricType: Utilization
    metadata:
      value: "50"  # CPU使用率が50%を超えた場合にスケールアウト

スケジュール・CPU使用率を組み合わせたトリガー設定

CronトリガーとCPUトリガーを組み合わせた最終的なScaledObjectの構成は次のマニフェストになります。

この構成により、次のオートスケールを実現できます。

  • 夜間(23:00〜07:00)

    • Podをゼロスケールし、余分なリソース消費を抑える。
  • 日中(07:00〜23:00)

    • 最低1つのPodを維持し、CPU使用率が50%以上になるとスケールアウトして負荷に対応する。
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: <scaledobject-name>  # ScaledObjectの名前を指定
  namespace: keda  # 対象のNamespaceを指定
spec:
  scaleTargetRef:
    name: <deployment-name>  # スケール対象のDeployment名
  minReplicaCount: 0  # 最小Replica数を0に設定(ゼロスケールを有効化)
  maxReplicaCount: 3  # 最大Replica数を3に設定
  triggers:
    - type: cpu
      metricType: Utilization
      metadata:
        value: "50" # CPU使用率が50%を超えた場合にスケールアウト
    - type: cron
      metadata:
        timezone: Asia/Tokyo  # タイムゾーンを指定
        start: 0 7 * * 1-5  # 平日の午前7時にスケーリングを開始
        end: 0 23 * * 1-5  # 平日の午後23時にスケーリングを終了
        desiredReplicas: "1"  # スケールアウト時のPod数

KEDA導入時の注意点

KEDAを導入する際、MLOpsブロックが特に注意したポイントをご紹介します。

既存のHPA無効化時のPod調整と導入タイミング

KEDAを導入する際、すでにHPAが適用されている環境では競合が発生します。これはKEDAが内部的にHPAを生成・管理する仕組みを持っているためです。そのため、KEDAを導入する前に既存のHPAを無効化する必要があります。

ただし、HPAを無効化するとKEDAを導入するまでの間Pod数が固定され負荷変動に対応できなくなります。特に本番環境では可用性・パフォーマンスの観点から慎重な対応が求められます。そのためHPAを無効化する前にminReplicasを適切に設定しスケールアウトしておくことで、急激なリクエスト増加に備える必要があります。

これらの点を考慮し、HPA無効化前に、minReplicas の見直しを行いました。トラフィックのピーク時にも対応できるように、現在の構成で許容可能なリクエスト数に対して、直近1週間の最大リクエスト数が上回るか接近している場合に minReplicasを増加させました。

さらに、移行時のエラーを最小限に抑えるため、HPAの無効化からKEDAの適用までの一連の作業を、トラフィックが少ない午前中に適用を実施しました。

KEDAの導入効果・メリット

導入によるコスト削減

MLOpsブロックでは開発・検証・テスト環境において合計で38個のAPIに対してKEDAを活用し、夜間および土日終日にPod停止を実施しました。この施策によりCompute Engineのコストを大幅に削減できました。

削減額の算出

以下の算出額はゼロスケールによるCompute Engineの削減分のみを対象としており、モニタリングツールのコスト削減や本番環境のリソース最適化は含まれていません。

KEDA導入前後の比較では、平日のCompute Engineコストは約27%削減されました。また、休日(土日)においては約45%の削減効果が見られました。1

年間のコスト削減効果

Compute Engine のコスト削減

区分 削減率 対象日数(年間)
平日 約27% 261日
休日(土日) 約45% 104日

KEDAの導入により0台へのスケールインができるようになりました。これにより稼働していない時間帯にかかっていたCompute Engineのコストを大幅に削減できました。

Datadog のコスト削減

モニタリング対象リソースの削減により、Datadogのコストも約40%削減される効果がありました。

KEDA導入後の課題と解決策

KEDA導入後にいくつかの課題が発生しました。これらの課題と解決策を紹介します。

外形監視の課題と解決策

MLOpsチームでは、サービスの可用性を担保するため、外部から定期的にリクエストしてAPIの応答状況を確認する外形監視を導入しています。KEDAによってPod数を0にスケールダウンしている間に外形監視を継続するとリクエストが失敗し、不要なアラートが発生します。

この問題を回避するために、APIの外形監視をScaledObjectのトリガーと同じスケジュールで停止するように設定していました。しかし、Pod数が0台の状態から起動する際、Podのスケジューリングやコンテナの立ち上げに時間を要するため外形監視のリクエストに間に合いませんでした。例えば、7:00に外形監視を開始する設定の場合、同じタイミングでAPIをスケールアウトしても、コンテナがReady状態になりAPIがレスポンスを返せるのは7:10頃になります。その結果、外形監視がPodの起動前に開始され、アラートの誤報が発生しました。

この問題を解決するため、APIごとに異なる起動時間を考慮し、外形監視が開始されるまでに確実にPodがReadyになるようにScaledObjectの設定をより早い時間に調整しました。これによりPodの起動が完了してから外形監視を行えるようになり、不要なアラートの発生を防ぐことができました。

外形監視に加え、自チームが管理する以外のサービスから送信されるリクエストも考慮する必要がありました。KEDAの導入前は営業時間外にはAPIを使用しないため、Podを停止しても問題ないと想定していました。しかし、実際には自チームが管理する以外の他のAPIからのリクエストを見落としておりPod停止中にリクエストがタイムアウトすることでアラートを発生させてしまいました。

これを解決するために、リクエストが発生する時間帯に合わせて、Podの停止および起動のタイミングを調整しました。さらに、他チームのAPIリクエストがこの時間帯に重ならないよう、リクエストの送信タイミングも調整してもらうことで対応しました。

Argo RolloutsでKEDAを適用するための設定変更

MLOpsブロックでは、Kubernetes上でプログレッシブデリバリーを実現するために、カナリアリリースをサポートするArgo Rolloutsを使用しています。Argo Rolloutsについては、計測SREチームの記事でも触れられていますのでぜひこちらもご参照ください。

techblog.zozo.com

通常、KEDAではDeploymentをスケール対象とする場合はscaleTargetRefnameのみを指定すればよく、apiVersionkindを省略できます。一方で、Rolloutのようなカスタムリソースを対象とするにはscaleTargetRefapiVersionkindを明示的に指定する必要があります。

そのため、Argo RolloutsのCustomResourceである、Rolloutリソースを適用するには、スケール対象の指定方法を変更する必要がありました。

設定例は以下の通りです。

spec:
  scaleTargetRef:
    apiVersion: argoproj.io/v1alpha1
    kind: Rollout
    name: <rollout-name>  # スケール対象のRollout名

今後の展望

今回は開発・検証・テスト環境を対象にKEDAの導入による夜間・休日のPod数の削減を実施し、コスト削減しました。一方で本番環境では標準のHPAからKEDAのScaledObjectに置き換えたのみで、スケジュールベースでのオートスケールによるコスト削減は未着手です。

現在の本番環境では時間帯ごとのトラフィックに応じたPod台数調整ができていないため、余剰なリソースが残っています。具体的には平日朝方などのトラフィックが少ない時間帯でも、必要以上のPod台数が維持されている状況です。今後は時間帯ごとのトラフィックを分析し、実際の負荷に応じたスケーリングルールを適用することで余分なリソースの削減と最適なスケーリングを実現していきます。

まとめ

最後までお読みいただきありがとうございました。本記事ではKEDAを導入した目的や効果に加え、導入に際しての課題や安全に本番環境へ適用するための工夫した点をご紹介しました。KEDAの導入により、MLOpsブロックではGKEにおける大幅なコスト削減に成功しました。またKEDAのスケジュールベースのオートスケールにより運用負荷の低減にも繋がりました。本記事が皆様のお役に立てば幸いです。

最後になりますが、ZOZOでは一緒にサービスを作り上げてくれる方を募集中です。MLOpsブロックでも絶賛採用を行っているため、ご興味ある方は以下のリンクからぜひご応募ください。

hrmos.co


  1. 本試算はゼロスケール対象のdev/stg/qa環境のみを分母として計算しています
カテゴリー