【入門編】KEDA (Kubernetes Event-driven Autoscaling) 活用術:カスタムメトリクスとKafka・SQS連動のスケーリング設定 – インフラ構成管理(IaC)活用バイブル

こんにちは!Kubernetesの世界へようこそ。

Kubernetesでコンテナを動かしていると、必ずぶつかる壁があります。それが「オートスケーリング(Podの自動増減)」です。「アクセスが増えたからPodを増やしたい」「夜間はPodを減らしてコストを削りたい」——そんな要望に応える仕組みとして、Kubernetesには標準で HPA(Horizontal Pod Autoscaler) が備わっています。

しかし、実務でAWS SQSやApache Kafkaのようなメッセージキューを使った「非同期処理(バッチ処理やワーカー構成)」を組み始めた途端、標準のHPAだけでは歯が立たなくなる瞬間に直面します。

「キューにメッセージが10万件も溜まっているのに、CPU使用率が上がらないからPodが増えてくれない…!」
こんな悲鳴をあげた経験はありませんか?

そこで登場するのが、今回解説する KEDA(Kubernetes Event-driven Autoscaling) です。
これをマスターすれば、メッセージキューの滞留数やカスタムメトリクスに完全連動した、美しく無駄のない自動スケーリングが実現できます。毎日の運用や夜間障害対応が劇的に楽になりますよ。

今回は、KEDAの基礎概念から、AWS SQSやKafkaと連動させる具体的な設定手順、実務で使えるチューニングのコツまで、分かりやすく丁寧にお伝えしていきますね。

—

1. 標準HPAの限界とKEDAが求められる背景

まず、「なぜ標準のHPAでは不十分で、KEDAが必要なのか?」という本質的な理由から紐解いていきましょう。

標準HPAの弱点:リアクティブ(後手に回る)なスケーリング

標準のHPAは、主にPodの CPU使用率 や メモリ使用率 を監視してスケーリングを行います。

Webサーバーのように「アクセスが増える = CPU使用率が上がる」という単純なシステムなら、これで問題ありません。しかし、メッセージキュー(SQSやKafka)を扱うワーカーシステムではどうでしょうか?

1. キューに大量のジョブ(メッセージ)が投入される。
2. ワーカーPodは1件ずつ丁寧に処理するため、CPU使用率は一定のまま(100%には達しない)。
3. HPAは「CPUに余裕があるな」と判断し、Podを増やさない。
4. 結果として、キューの滞留時間がどんどん延び、処理の遅延が発生する。

つまり、CPU/メモリ監視では「キューにどれだけ仕事が溜まっているか」という未来の負荷を予測できないのです。仕事が溜まっているなら、CPUが高かろうが低かろうが、今すぐワーカーを増やすべきですよね。

KEDAが解決する3つの革命

KEDA(ケーダ)は、Cloud Native Computing Foundation (CNCF) の卒業プロジェクトであり、この問題を完璧に解決してくれます。

【従来のHPA】
[ SQS / Kafka ] —> (無視)
[ Pod CPU/Mem ] —> [ HPA ] —> Pod数を変更

【KEDA導入後】
[ SQS / Kafka ] —> [ KEDA ] —> [ HPA (自動生成) ] —> Pod数を変更
(キュー数を監視) (メトリクス変換)

KEDAの優れたポイントは以下の3点です。

1. イベント駆動型のスケーリング:
SQSやKafkaのメッセージ数、Redisのキー数、Prometheusのクエリ結果など、外部のイベント(メトリクス)を直接トリガーにしてPodをスケールできます。
2. 0へのスケール(Scale to Zero)と1からの起動:
標準HPAは最低1つのPodを残す必要がありますが、KEDAは「キューが0件ならPodを0台にする」ことが可能です。無駄なEC2/GKEコストを極限まで削れます。
3. 標準HPAとの親和性:
KEDAは既存のHPAを置き換えるのではなく、裏でKubernetes標準の `HorizontalPodAutoscaler` リソースを自動生成して運用します。既存のKubernetesエコシステムを破壊しません。

—

2. KEDAのアーキテクチャとインストール

仕組みが理解できたら、さっそくKEDAをKubernetesクラスターに導入してみましょう!

KEDAの基本構造

KEDAは主に2つのコンポーネントで動いています。

  • KEDA Operator: カスタムリソース(`ScaledObject` など)を監視し、KubernetesのHPAを自動作成・管理するブレインです。
  • Metrics Server: 外部(SQSやKafkaなど)から取得したメトリクスを、KubernetesのAPI Serverが理解できる形式に変換して渡す役割を果たします。

インストール手順(Helmを使用)

最も簡単で推奨されている Helm を使ったインストール手順です。

1. Helmリポジトリの追加と更新
helm repo add keda https://kedacore.github.io/charts
helm repo update

2. keda ネームスペースを作成してインストール
helm install keda keda/keda –namespace keda –create-namespace

インストールが成功したか確認してみましょう。

kubectl get pods -n keda

`keda-operator-…` や `keda-metrics-apiserver-…` といったPodが `Running` になっていれば準備完了です!簡単ですね。

—

3. 実践!AWS SQS連動のスケーリング構築

ここからは、実際に「AWS SQSのキュー数(メッセージ残数)に応じてワーカーPodを自動スケーリングさせる」 マニフェストを作っていきましょう。

KEDAでは、主に以下の2つのカスタムリソース(CRD)を使います。
1. `TriggerAuthentication`:AWSなどの認証情報(IAMロールや秘密鍵)を安全に定義する。
2. `ScaledObject`:「何をトリガーに、どのDeploymentを、最小〜最大何台まで増減させるか」を定義する。

ステップ1:認証設定(TriggerAuthentication)

まずは、KEDAがAWS SQSのキュー数を読みに行くための権限を設定します。実務ではセキュリティの観点から Pod Identity や IRSA (IAM Roles for Service Accounts) を使うのがベストプラクティスですが、ここでは理解しやすいようにAWSクレデンシャル(Secret)を参照する形式で記述します。

apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-aws-credentials
namespace: default
spec:
secretTargetRef:

  • parameter: awsAccessKeyId # KEDA内部で使うパラメータ名

name: aws-sqs-secret # Kubernetes Secretのリソース名
key: AWS_ACCESS_KEY_ID # Secret内のキー名

  • parameter: awsSecretAccessKey

name: aws-sqs-secret
key: AWS_SECRET_ACCESS_KEY

ステップ2:スケーリング定義(ScaledObject)

次に、本丸である `ScaledObject` を作成します。ここがKEDAの最も魅力的な部分です。

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: sqs-worker-scaledobject
namespace: default
spec:
# 1. スケール対象とするDeploymentの名前
scaleTargetRef:
name: my-sqs-worker-deployment

# 2. ポーリング間隔(何秒ごとにSQSのキュー数を確認するか)
pollingInterval: 15 # デフォルト: 30秒

# 3. クールダウン期間(メッセージが消えてからScale to Zeroにするまでの待機秒数)
cooldownPeriod: 300 # デフォルト: 300秒(5分)

# 4. 最小・最大Pod数(0に設定することで Scale to Zero が可能に!)
minReplicaCount: 0
maxReplicaCount: 20

# 5. トリガー(スケーリングの条件)の設定
triggers:

  • type: aws-sqs

authenticationRef:
name: keda-aws-credentials # 上で定義した認証リソースを指定
metadata:
queueURL: https://sqs.ap-northeast-1.amazonaws.com/123456789012/my-work-queue
queueLength: “5” # ターゲット値:1Podあたり「5メッセージ」を基準とする
awsRegion: ap-northeast-1

💡 `queueLength: “5”` の意味

ここが非常に重要なポイントです!
`queueLength` は「1つのPodが処理するべき理想のメッセージ数」を表します。
例えば、現在SQSに 20件 のメッセージが溜まっている場合:
`20件 ÷ queueLength(5) = 4` と計算され、KEDAは自動的に Pod数を 4台 に増やすよう指示を出します。直感的でとても分かりやすいですよね!

—

(参考)Apache Kafkaを使う場合はどう書くの?

もし環境が Kafka の場合は、`triggers` の部分を以下のように書き換えるだけで対応できます。エンジニアにとって学習コストが低いのもKEDAの素晴らしい特徴です。

triggers:

  • type: kafka

metadata:
bootstrapServers: kafka.default.svc.cluster.local:9092
topic: my-topic
consumerGroup: my-consumer-group
lagThreshold: “10” # 1Podあたりの許容メッセージ遅延数(ラグ)

—

4. 動作確認:キュー数に応じたスケーリングの挙動を見る

設定をデプロイしたら、実際に動かしてみましょう!

1. マニフェストの適用

kubectl apply -f trigger-auth.yaml
kubectl apply -f scaled-object.yaml

2. 初期状態の確認

初期状態ではSQSにメッセージが0件のため、Pod数が0(または設定した `minReplicaCount`)になっているはずです。

kubectl get pods -l app=my-sqs-worker
No resources found in default namespace. (Pod数が0になっている)

3. メッセージの投入と自動スケーリングの観測

スクリプトやAWS CLIを使って、SQSに一気に 50件 のメッセージを投入してみます。

別ウィンドウで以下のコマンドを実行して、リアルタイムでPodの変化を監視してみましょう。

kubectl get pods -l app=my-sqs-worker -w

すると、以下のようにニョキニョキとPodが立ち上がる様子が観察できます!

NAME READY STATUS RESTARTS AGE
my-sqs-worker-7d4889c8d5-x8z92 0/1 Pending 0 2s
my-sqs-worker-7d4889c8d5-x8z92 1/1 Running 0 5s
my-sqs-worker-7d4889c8d5-abc12 1/1 Running 0 5s
… (計算通り、50件 ÷ 5 = 10台まで一気にスケールアウト!)

メッセージの処理が進み、SQSのキュー数が0になると、`cooldownPeriod`(設定した5分間)の経過後に、再び安全にPodが0台(`Scale to Zero`)へ戻ります。

この感動的な挙動を一度体験すると、もう標準HPAのみの運用には戻れなくなりますよ!

—

5. 実務で役立つスケール設定のチューニングポイントと注意点

最後に、本番環境でKEDAを運用する際に「知っておくべきプロの知見」を3つ共有します。

① ハンチング(スケールの乱高下)を防ぐ `cooldownPeriod` の調整

処理が終わった瞬間にPodを0にしてしまうと、「直後にまた1件メッセージが入ってきた」ときに、毎回Podの起動遅延(コールドスタート)が発生してしまいます。

  • 対策: `cooldownPeriod` を 300秒(5分)〜 600秒(10分)程度に設定し、メッセージが途絶えてもしばらくPodを待機させておきましょう。急な連続投入にもスムーズに対応できます。

② スケールイン(縮小)の動作をマイルドにする `behavior` の活用

KEDAの `ScaledObject` 内には、Kubernetes HPAの `behavior` 設定をそのまま記述できます。「増やす時は一気に、減らす時は慎重に」という設定を入れ込むのが実務の鉄則です。

spec:
advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 過去5分間の最高負荷を考慮して縮小を判断
policies:

  • type: Percent

value: 10 # 一度に10%ずつしかPodを減らさない
periodSeconds: 60

③ クラウド破産を防ぐ `maxReplicaCount` の限界値設定

万が一、アップストリームのシステム異常で数百万件の無効なメッセージがSQSに流入した場合、`maxReplicaCount` が未設定または巨大すぎると、何千ものPodが起動してクラウド破産を引き起こします。

必ず「自社のノードインフラやデータベースの許容量に合わせた `maxReplicaCount`」を明示的に設定してください。

—

まとめ:KEDAでKubernetesのスケーリングを最適化しよう

今回は、KEDAを用いたイベント駆動型のPod自動スケーリングについて解説しました。

  • 標準HPA はCPU/メモリ等の「現在値」を見るため、キュー処理には後手に回りやすい。
  • KEDA を導入すれば、SQSやKafkaのメッセージ滞留数を直接トリガーにして「未来の負荷」に即座に対応できる。
  • Scale to Zero(0への縮小) を実現し、無駄なインフラコストを劇的にカットできる。

最初は小さな開発環境やバッチ用のワーカーPodから試してみてください。
「メッセージが入ってきた瞬間に必要な分だけPodが立ち上がり、仕事を終えたら綺麗に消えていく」——この快感を一度味わえば、あなたのインフラ構築スキルは一歩先の次元へ進むはずです。

これをマスターして、毎日の運用を劇的に楽にしていきましょうね!応援しています!

タイトルとURLをコピーしました