ご利用の Knative サービスへのトラフィックが変動する場合、固定された Pod 数では、トラフィックが少ないときにリソースが無駄になったり、トラフィックスパイク時にパフォーマンスが低下したりします。ASM 上の Knative Pod Autoscaler (KPA) は、各 Pod 内の Queue Proxy サイドカーを通じてリアルタイムのリクエスト同時実行数をモニタリングし、トラフィックスパイク時にはスケールアップし、アイドル期間中には(ゼロまで含めて)スケールダウンすることで、この課題を解決します。
前提条件
ASM 上の Knative を使用してデプロイされた Knative サービスが必要です。詳細については、「ASM 上の Knative を使用したサーバーレスアプリケーションのデプロイ」をご参照ください。
本トピックでは、デモ用にデフォルトドメイン名 example.com を使用します。カスタムドメイン名を使用する場合は、「ASM 上の Knative でのカスタムドメイン名の設定」をご参照ください。
KPA の仕組み
Knative Serving は、各 Pod に Queue Proxy コンテナを注入します。Queue Proxy は処理中のリクエストをトラッキングし、同時実行数メトリックを KPA にレポートします。KPA はこれらのメトリックに基づき、必要な Pod 数を計算し、基盤となる Deployment をスケーリングします。

同時実行数と QPS
| Metric | Definition |
|---|---|
| Concurrency | 1 つの Pod が同時に処理するリクエスト数 |
| QPS | 1 秒間に 1 つの Pod が完了するリクエスト数(最大スループット) |
同時実行数を高くしても、必ずしも QPS が向上するとは限りません。高負荷下では、同時実行数を増やすと CPU やメモリの競合が発生し、レスポンスレイテンシーが増加するため、QPS が低下することがあります。
自動スケーリングアルゴリズム
KPA は、Pod あたりの平均同時実行リクエスト数に基づいて Pod をスケーリングします。デフォルトでは、各 Pod は同時実行数 100 リクエストをターゲットとします。KPA は以下の 2 つのモードで動作します。
安定モード
KPA は、安定ウィンドウ(デフォルト:60 秒)にわたってすべての Pod の同時実行数を平均化し、ターゲット同時実行数を維持するように Pod 数を調整します。
パニックモード
KPA は、より短いパニックウィンドウ(デフォルト:6 秒)にわたって同時実行数を平均化します。パニックウィンドウは次のように計算されます。
Panic window = Stable window x panic-window-percentageデフォルトの panic-window-percentage は 10(安定ウィンドウの 10%)です。有効な値は 1 ~ 100 です。観測された同時実行数がパニックしきい値パーセンテージ(デフォルト:200%)を超えると、KPA は急激にスケールアップしてバーストトラフィックを吸収します。
|
Panic Target---> +--| 20
| |
| <------Panic Window (6s)
| |
Stable Target---> +-------------------------|--| 10
CONCURRENCY | | |
| <-----------Stable Window (60s)
| | |
--------------------------+-------------------------+--+ 0
120 60 0
TIME (seconds)KPA のグローバル構成
KPA は、config-autoscaler ConfigMap を通じて knative-serving 名前空間内で構成します。現在の構成を確認するには、次のコマンドを実行します。
kubectl -n knative-serving get cm config-autoscaler -o yamlConfigMap の構造は以下のとおりです。
apiVersion: v1
kind: ConfigMap
metadata:
name: config-autoscaler
namespace: knative-serving
data:
_example:
container-concurrency-target-default: "100" # Pod あたりのソフト同時実行ターゲット
container-concurrency-target-percentage: "0.7" # スケーリングトリガーの利用率係数
enable-scale-to-zero: "true" # Pod 数をゼロまでスケーリングすることを許可
max-scale-up-rate: "1000" # 評価サイクルごとの最大スケールアップ倍率
max-scale-down-rate: "2" # 評価サイクルごとの最大スケールダウン倍率
panic-window-percentage: "10" # 安定ウィンドウに対するパニックウィンドウの割合(%)
panic-threshold-percentage: "200" # パニックモードをトリガーする同時実行数の割合(%)
scale-to-zero-grace-period: "30s" # 最後の Pod がゼロにスケーリングされる前に実行される最大時間
scale-to-zero-pod-retention-period: "0s" # ゼロへのスケーリング決定後、最後の Pod がアクティブなまま維持される最小時間
stable-window: "60s" # 安定モードでの平均化に使用する時間ウィンドウ
target-burst-capacity: "200" # トラフィックバースト用に予約される追加容量
requests-per-second-target-default: "200" # RPS メトリック使用時のデフォルト RPS ターゲット_example 配下の値はデフォルト値です。パラメーターを変更するには、_example から該当項目をコピーし、data フィールドに記述してください。
config-autoscaler ConfigMap の変更は、メッシュ内のすべての Knative サービスに適用されます。単一のサービスに対して自動スケーリングを構成するには、代わりに Revision 単位のアノテーションを使用してください。「同時実行ターゲットの設定」および「スケール範囲の設定」をご参照ください。
ゼロへのスケーリングに関するパラメーター
| Parameter | Per-Revision annotation | Default | Description |
|---|---|---|---|
enable-scale-to-zero | N/A (グローバルのみ) | true | トラフィックがない場合に Pod 数をゼロまでスケーリングすることを許可 |
scale-to-zero-grace-period | N/A (グローバルのみ) | 30s | KPA が Pod をゼロにスケーリングする前に、非アクティブな Revision が実行され続ける最大時間。最小値:30 秒 |
scale-to-zero-pod-retention-period | N/A (グローバルのみ) | 0s | KPA がゼロへのスケーリングを決定した後、最後の Pod がアクティブなまま維持される最小時間 |
stable-window | autoscaling.knative.dev/window | 60s | 安定モードで同時実行数を平均化するための時間ウィンドウ |
同時実行ターゲットの設定
KPA は、以下の 2 種類の同時実行制限をサポートしています。
ソフトリミット(推奨):KPA が目的の Pod 数を計算する際に使用するターゲット値です。突然のバースト時には、実際の同時実行数が一時的にこの値を超えることがあります。
ハードリミット:強制される上限値です。この制限を超えるリクエストは、容量が利用可能になるまでバッファーされます。
アプリケーションが厳密な同時実行制御を必要とする場合にのみ、ハードリミットを使用してください。低いハードリミット値はレイテンシーを増加させ、コールドスタートを引き起こす可能性があります。
| Parameter | Per-Revision annotation | Default | Description |
|---|---|---|---|
container-concurrency-target-default | autoscaling.knative.dev/target | 100 | Pod あたりのソフト同時実行ターゲット |
containerConcurrency | N/A (Revision spec で設定) | 0 (無制限) | Pod あたりのハード同時実行制限。0 = 無制限、1 = 一度に 1 リクエスト、2-N = 特定の制限値 |
container-concurrency-target-percentage | N/A (グローバルのみ) | 0.7 | 利用率係数。スケーリングは、同時実行ターゲット × この係数でトリガーされます。例:100 x 0.7 = 70 — 平均同時実行数が 70 に達すると、KPA は Pod を追加します |
スケール範囲の設定
Revision ごとの最小および最大 Pod 数を制御するには、minScale および maxScale アノテーションを使用します。これにより、コールドスタートを軽減し、コストを管理できます。
| Annotation | Default behavior | Description |
|---|---|---|
autoscaling.knative.dev/minScale | アイドル時にすべての Pod が削除される | 常に実行しておく最小 Pod 数 |
autoscaling.knative.dev/maxScale | 上限なし | 許容される最大 Pod 数 |
これらのアノテーションを Revision テンプレートに追加します。
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/minScale: "2"
autoscaling.knative.dev/maxScale: "10"minScaleが設定されていない場合、トラフィックがないとき(ゼロへのスケーリングが有効な場合)すべての Pod が削除されます。maxScaleが設定されていない場合、Pod 数に上限はありません。ConfigMap 内で
enable-scale-to-zeroがfalseに設定されている場合、minScaleの値に関係なく、KPA は少なくとも 1 つの Pod を実行し続けます。
スケールレートパラメーター
| Parameter | Per-Revision annotation | Default | Description |
|---|---|---|---|
max-scale-up-rate | N/A (グローバルのみ) | 1000 | 1 回の評価サイクルで Pod 数がスケールアップできる最大比率。たとえば、1 つの Pod が実行中の場合、KPA は 1 サイクルで最大 1000 個の Pod までスケールアップできます |
max-scale-down-rate | N/A (グローバルのみ) | 2 | 1 回の評価サイクルで Pod 数がスケールダウンできる最大比率。たとえば、100 個の Pod が実行中の場合、KPA は 1 サイクルで最大 50 個までスケールダウンできます |
同時実行ターゲットに基づくスケーリング
この例では、同時実行ターゲットを 10 に設定して autoscale-go アプリケーションをデプロイし、負荷テストを実行して、KPA が需要に応じて Pod をスケーリングすることを検証します。
Knative サービスのデプロイ方法の詳細については、「ASM 上の Knative を使用したサーバーレスアプリケーションのデプロイ」をご参照ください。
同時実行ターゲットを
10に設定したautoscale-go.yamlという名前のファイルを作成します。apiVersion: serving.knative.dev/v1 kind: Service metadata: name: autoscale-go namespace: default spec: template: metadata: labels: app: autoscale-go annotations: autoscaling.knative.dev/target: "10" # 平均同時実行数が 10 x 0.7 = 7 を超えるとスケーリング spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/autoscale-go:0.1アプリケーションをデプロイします。
kubectl apply -f autoscale-go.yamlゲートウェイの IP アドレスを取得します。ASM コンソールにログインし、対象の ASM インスタンス名をクリックして、[ASM ゲートウェイ] > [Ingress ゲートウェイ] の順に選択します。Ingress ゲートウェイページで、[サービスアドレス] セクションの IP アドレスを確認します。
30 秒間、50 の同時リクエストで負荷テストを実行します。前のステップで取得した IP アドレスに置き換えて
<gateway-ip>を使用します。ゲートウェイアドレスの取得方法については、「ASM 上の Knative を使用したサーバーレスアプリケーションのデプロイ」の「ステップ 3:ゲートウェイアドレスの照会」をご参照ください。負荷テストツールの詳細については、hey をご参照ください。hey -z 30s -c 50 \ -host "autoscale-go.default.example.com" \ "http://<gateway-ip>?sleep=100&prime=10000&bloat=5"結果を検証します。KPA はアプリケーションを約 7 個の Pod にスケーリングします。同時実行ターゲットが 10、デフォルトの利用率係数が 70% の場合、KPA は Pod あたりの平均同時実行数が 7(10 × 0.7)を超えると Pod の追加を開始します。この先読みスケーリングにより、リクエスト量が増加しても同時実行ターゲットが超過しないようになります。

定義済みの範囲内でのスケーリング
この例では、Pod 数を 1 ~ 3 の範囲に制限するスケール範囲を設定して、同じ autoscale-go アプリケーションをデプロイします。
Knative サービスのデプロイ方法の詳細については、「ASM 上の Knative を使用したサーバーレスアプリケーションのデプロイ」をご参照ください。
同時実行ターゲットを
10、minScaleを1、maxScaleを3に設定したautoscale-go.yamlという名前のファイルを作成します。apiVersion: serving.knative.dev/v1 kind: Service metadata: name: autoscale-go namespace: default spec: template: metadata: labels: app: autoscale-go annotations: autoscaling.knative.dev/target: "10" # Pod あたりの同時実行ターゲット autoscaling.knative.dev/minScale: "1" # 常に少なくとも 1 つの Pod を実行 autoscaling.knative.dev/maxScale: "3" # Pod 数を 3 個を超えないように制限 spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/autoscale-go:0.1アプリケーションをデプロイします。
kubectl apply -f autoscale-go.yamlゲートウェイの IP アドレスを取得します。ASM コンソールにログインし、対象の ASM インスタンス名をクリックして、[ASM ゲートウェイ] > [Ingress ゲートウェイ] の順に選択します。Ingress ゲートウェイページで、[サービスアドレス] セクションの IP アドレスを確認します。
30 秒間、50 の同時リクエストで負荷テストを実行します。前のステップで取得した IP アドレスに置き換えて
<gateway-ip>を使用します。ゲートウェイアドレスの取得方法については、「ASM 上の Knative を使用したサーバーレスアプリケーションのデプロイ」の「ステップ 3:ゲートウェイアドレスの照会」をご参照ください。負荷テストツールの詳細については、hey をご参照ください。hey -z 30s -c 50 \ -host "autoscale-go.default.example.com" \ "http://<gateway-ip>?sleep=100&prime=10000&bloat=5"結果を検証します。負荷テスト中に KPA はアプリケーションを最大 3 個の Pod にスケーリングします。トラフィックが停止すると、
minScaleで指定されたとおり、1 個の Pod が実行されたままになります。スケール範囲により、過剰プロビジョニングを防ぎながら、コールドスタートを解消できます。
次のステップ
ASM ゲートウェイを使用して Knative サービスに HTTPS でアクセス:暗号化通信により Knative サービスのエンドポイントを保護します。
ASM 上の Knative を使用して Knative サービスのトラフィック分割によるカナリアリリースを実行:トラフィック分割により新しいバージョンを段階的にロールアウトします。
Knative での HPA の使用:リクエスト同時実行数ではなく CPU 使用率に基づいてスケーリングします。