GKE で実行されている Spring Boot アプリケーションがあり、準備に 7 分ほどかかります。次のように、1 秒あたりのカスタム リクエスト メトリックに基づいて HPA を作成しました。
kind: "HorizontalPodAutoscaler"
metadata:
name: X
namespace: X
spec:
maxReplicas: 10
minReplicas: 3
scaleTargetRef:
apiVersion: "apps/v1"
kind: "Deployment"
name: "X"
metrics:
- type: "Pods"
pods:
metric:
name: "istio_requests_per_second"
target:
type: "AverageValue"
averageValue: 30
istio_requests_per_secondメトリクスは、使用可能なポッド全体の平均 RPS をすでに計算しているため、ポッドごとに同じ値になります。たとえば、合計で 150 RPS があり、使用可能な Pod が 5 つある場合、istio_requests_per_secondは 30 になります。
istio_requests_per_secondが 30 をわずかに超えると、新しく作成されたPodの 1 つがリクエストの一部を受け取る準備ができるまで、HPA は Pod を生成し続けます (メトリックが 32 RPS に増加した場合に 2 RPS としましょう)。新しく作成された Pod の準備が整う前に、それらはリクエストを受信せず、HPA は RPS の量を目標値 (30) 付近に維持しようとするため、これは完全に理にかなっています。
問題は、RPS がわずかに増加した場合に、HPA が数十個のポッドを生成することを望まないことです。たとえば、32 RPS の場合、1 つの新しいポッドで十分です。主な問題は起動時間が長いことだと思います。これは、スケールアップの決定時と Pod の準備が整う時との間に自動スケーリングのラグがあるためです。
GKE で実行しているため、--horizontal-pod-autoscaler-sync-period などの kube- controller-manager フラグを変更できません。
私も Kubernetes 1.17 で実行しているため、段階的なスケーリングを構成するための動作フィールドは問題外です。その上、スケーリングを制限したくありません。 istio_requests_per_secondが実際には 100 RPS を超えて急上昇している可能性があります。
TL;DR:起動が遅いアプリケーションの 1 秒あたりのリクエスト数がわずかに増加した場合に、何十ものポッドを生成しないように Kubernetes HPA を構成するにはどうすればよいですか?