このトピックでは、Horizontal Pod Autoscaler (HPA) や CronHPA などのワークロードスケーリング機能を使用する際に発生する可能性のある一般的な問題とそのソリューションについて説明します。
目次
HPA メトリックの current フィールドが unknown と表示される原因
HPA のモニタリングデータの current フィールドが unknown の場合、kube-controller-manager がモニタリングデータソースにアクセスして対応するデータを取得できず、HPA のスケーリングが失敗することを示します。
Name: kubernetes-tutorial-deployment
Namespace: default
Labels: <none>
Annotations: <none>
CreationTimestamp: Mon, 10 Jun 2019 11:46:48 0530
Reference: Deployment/kubernetes-tutorial-deployment
Metrics: ( current / target )
resource cpu on pods (as a percentage of request): <unknown> / 2%
Min replicas: 1
Max replicas: 4
Deployment pods: 1 current / 0 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True SucceededGetScale the HPA controller was able to get the target's current scale
ScalingActive False FailedGetResourceMetric the HPA was unable to compute the replica count: unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server is currently unable to handle the request (get pods.metrics.k8s.io)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedGetResourceMetric 3m3s (x1009 over 4h18m) horizontal-pod-autoscaler unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server is currently unable to handle the request (get pods.metrics.k8s.io)原因 1:リソースメトリックのデータソースが利用不可
まず、kubectl top pod コマンドを実行してデータが返されるか確認します。すべての Pod からデータが返されない場合は、kubectl get apiservice を実行して、リソースメトリックを提供するデータソースのステータスを確認します。返されるデータの例は次のとおりです。
v1beta1.metrics.k8s.io の API Service が kube-system/metrics-server でない場合、Prometheus Operator のインストールによって上書きされていないか確認してください。上書きされている場合は、次の YAML テンプレートをデプロイすることでサービスを復元できます。
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
name: v1beta1.metrics.k8s.io
spec:
service:
name: metrics-server
namespace: kube-system
group: metrics.k8s.io
version: v1beta1
insecureSkipTLSVerify: true
groupPriorityMinimum: 100
versionPriority: 100これが問題でない場合は、ご利用のクラスターの 操作 > アドオン管理 ページに移動し、metrics-server コンポーネントがインストールされていることを確認します。詳細については、「metrics-server」をご参照ください。
原因 2:ローリングアップデートまたはスケールアウト中にメトリックを取得できない
Pod が作成または更新された後、metrics-server がそのメトリックを取得するには時間が必要です。操作完了後、約 2 分待ってから再度確認してください。
原因 3:request フィールドが設定されていない
デフォルトでは、HPA は 実使用量/request を使用率として使用します。そのため、Pod の resource フィールドに request フィールドが含まれているか確認してください。
原因 4:メトリック名が正しくない
メトリック名が、大文字と小文字の区別を含めて正しいか確認してください。たとえば、HPA がサポートするメトリック cpu を誤って CPU と記述した場合、モニタリングデータの current フィールドは unknown と表示されます。
HPA スケーリング失敗のトラブルシューティング
HPA のスケーリングは、メトリック取得の異常により失敗することがあります。この場合、HPA のモニタリングデータの current フィールドは unknown と表示されます。これにより、HPA はスケーリングの決定に必要なメトリックを取得できず、Pod の数を調整できなくなります。「ノードの自動スケーリングに関するよくある質問」をご参照いただき、原因のトラブルシューティングと適切なソリューションの適用を行ってください。
ローリングアップデート中に HPA が余分な Pod を作成する原因
ローリングアップデート中、Kubernetes の controller-manager は、まだメトリックが利用できない Pod に対してゼロ値を報告します。これにより、HPA が必要以上に多くの Pod を作成することがあり、この現象はスケーリングスラッシングまたは過剰なスケーリングとして知られています。これを防ぐために、以下の構成を使用できます。
クラスターレベルの構成
この動作を防ぐには、Container Service for Kubernetes (ACK) が提供する metrics-server を最新バージョンにアップグレードし、特定の起動パラメーターを有効にします。
これはグローバル設定であり、クラスター内のすべての関連ワークロードに影響します。
# metrics-server の起動パラメーターに次のオプションを追加します。
--enable-hpa-rolling-update-skipped=true ワークロードレベルの構成
特定のワークロードでの過剰なスケーリングを防ぐには、次のいずれかの方法を使用します。
方法 1:ワークロードの Pod テンプレートに次のアノテーションを追加して、ローリングアップデート中の HPA 評価を一時停止します。
# このアノテーションをワークロードの spec.template.metadata.annotations に追加して、ローリングアップデート中の HPA 評価を一時的に一時停止します。 HPARollingUpdateSkipped: "true"方法 2:ワークロードの Pod テンプレートに次のアノテーションを追加して、アプリケーションの起動後に HPA が監視するウォームアップ期間を定義します。
# このアノテーションをワークロードの spec.template.metadata.annotations に追加して、設定されたウォームアップ期間をスキップします。 HPAScaleUpDelay: 3m # 3m は一例です。要件に基づいて期間を設定してください。
しきい値に達しても HPA がスケーリングしない原因
HPA は、CPU やメモリの使用量がしきい値を超えたかどうかだけを考慮するわけではありません。スケーリングアクションがすぐに逆転する可能性があるかどうかも計算し、スケーリングスラッシングを防ぎます。
たとえば、スケールアウトのしきい値が 80% で、それぞれ 70% の CPU 使用率を持つ 2 つの Pod があるとします。この場合、HPA はスケールインしません。これは、1 つの Pod に減らすと負荷が集中し、CPU 使用率が 80% のスケールアウトしきい値を超えてしまい、すぐに新しいスケールアウトがトリガーされると計算するためです。
HPA メトリック収集間隔の設定方法
v0.2.1-b46d98c-aliyun より後のバージョンの metrics-server では、起動パラメーター --metric-resolution を設定します。例:--metric-resolution=15s。
CronHPA と HPA の互換性とその仕組み
はい、CronHPA は HPA と互換性があります。Container Service for Kubernetes (ACK) では、CronHPA は scaleTargetRef を HPA に設定することで HPA オブジェクトと連携します。その後、CronHPA は HPA を使用して実際のスケーリングターゲットを見つけます。この設計により、CronHPA は HPA の状態を認識できます。CronHPA は、Deployment のレプリカ数を直接調整するのではなく、HPA を介して動作するため、2 つのオートスケーラー間の競合を防ぎます。詳細については、「CronHPA と HPA の連携を有効にする」をご参照ください。
初期リソース急増による HPA の過剰なスケーリングを防止する方法
Java のようなウォームアップ期間を必要とする言語で書かれたアプリケーションでは、コンテナの起動後数分間、CPU とメモリの使用量が急増することがあります。これにより、HPA が不要なスケールアウトをトリガーする可能性があります。これを防ぐには、ACK が提供する metrics-server コンポーネントをバージョン 0.3.9.6 以降にアップグレードし、Pod 仕様にアノテーションを追加してこの動作を防ぎます。アップグレード手順については、「クラスターを v1.12 にアップグレードする前に metrics-server コンポーネントをアップグレードする」をご参照ください。
次の YAML は、不要なスケーリングを防ぐためのアノテーションを含む Deployment の例です。
監査ログでメトリック値がしきい値を下回っているにもかかわらず HPA がスケーリングした原因
原因
Horizontal Pod Autoscaler は、次の数式を使用して、現在のメトリックと目的のメトリックの比率に基づいて目的のレプリカ数を計算します:目的のレプリカ数 = ceil(現在のレプリカ数 × (現在のメトリック / 目的のメトリック))。
この数式は、目的のレプリカ数の精度が、現在のレプリカ数、現在のメトリック、および目的のメトリックの精度に依存することを示しています。HPA で広く使用されているリソースメトリックを例に取ります。現在のレプリカ数を取得するために、HPA はまず scale サブリソース (subResources) を scaleTargetRef で定義されたオブジェクトから取得します。次に、scale オブジェクトの status から Selector の値を取得し、labelselector に変換します。このセレクターは、Pod を照合して取得するための条件として使用されます。いずれかの時点で、この条件を使用して取得された Pod のすべてが scaleTargetRef で定義されたオブジェクトに属するわけではない場合、計算された目的のレプリカ数が不正確になる可能性があります (たとえば、リアルタイムメトリックがしきい値を下回っている場合でもスケールアップするなど)。
Pod 数が不正確になる一般的な理由には、次のものがあります:
ローリングアップデートが進行中である。
scaleTargetRef オブジェクトに属さない Pod が同じラベルを持っている。次のコマンドを実行して、そのような Pod を確認できます:
kubectl get pods -n {namespace_name} -l {value_of_scale_subresource_status.selector}
ソリューション
ローリングアップデートに関連する問題については、「ローリングアップデート中に HPA が余分な Pod を作成する原因」をご参照ください。
他の Pod が同じラベルを共有している場合は、それらを見つけます。まだ使用中の場合は、ラベルを変更します。不要になった場合は、削除します。
HPA による Pod のスケールイン順序の制御可否
いいえ。HPA はワークロードのレプリカ数を調整するだけで、どの特定の Pod を終了するかは決定しません。Pod を管理するコントローラー (Deployment など) が、終了順序とグレースフルシャットダウン期間を決定します。
しかし、ECS インスタンスやサーバーレス ECI リソース、または複数のノードプールなど、異なるノードタイプが混在する環境では、カスタム ResourcePolicy を設定することで、スケールインの優先度に影響を与えることができます。HPA を Deployment および ResourcePolicy とともに使用して、ECS ノード上の Pod よりも ECI ノード上の Pod のスケールインを優先させることができます。詳細については、「弾力的なリソースの優先度スケジューリングをカスタマイズする」をご参照ください。
HPA 使用率メトリックの単位の意味
使用量メトリックは、通常、単位のない整数値、または m 単位の整数値です。変換率は 1000m = 1 です。たとえば、`tcp_connection_counts` が 70000m の場合、70 に相当します。
kubectl get hpa 実行後に target 列が unknown と表示された場合の対処法
この問題をトラブルシューティングするには、次の手順に従います。
kubectl describe hpa <hpa_name>を実行して、HPA が失敗した理由を確認します。ConditionsフィールドでAbleToScaleがFalseと示されている場合は、Deployment が正しく実行されていることを確認します。ConditionsフィールドでScalingActiveがFalseと示されている場合は、次のステップに進みます。
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/"を実行します。Error from server (NotFound): the server could not find the requested resourceが返された場合は、alibaba-cloud-metrics-adapter の起動ステータスを確認します。alibaba-cloud-metrics-adapter が正しく実行されている場合は、HPA メトリックが Ingress に関連しているかどうかを確認します。関連している場合は、まず Simple Log Service (SLS) コンポーネントをデプロイする必要があります。詳細については、「Nginx Ingress アクセスログの収集と分析」をご参照ください。
HPA メトリックが正しく入力されていることを確認します。sls.ingress.route の値は
<namespace>-<svc>-<port>のフォーマットです。namespace:Ingress の名前空間。svc:Ingress の Service の名前。port:Ingress に関連付けられた Service のポート名。
HPA でサポートされているメトリックの確認方法
サポートされているメトリックのリストについては、「Alibaba Cloud HPA metrics」をご参照ください。次の表に、一般的に使用されるいくつかのメトリックを示します。
メトリック | 説明 | 追加パラメーター |
sls_ingress_qps | 指定された Ingress ルートの QPS。 | sls.ingress.route |
sls_alb_ingress_qps | 指定された ALB Ingress ルートの QPS。 | sls.ingress.route |
sls_ingress_latency_avg | すべてのリクエストの平均レイテンシー。 | sls.ingress.route |
sls_ingress_latency_p50 | リクエストの 50 パーセンタイルレイテンシー。 | sls.ingress.route |
sls_ingress_latency_p95 | リクエストの 95 パーセンタイルレイテンシー。 | sls.ingress.route |
sls_ingress_latency_p99 | リクエストの 99 パーセンタイルレイテンシー。 | sls.ingress.route |
sls_ingress_latency_p9999 | リクエストの 99.99 パーセンタイルレイテンシー。 | sls.ingress.route |
sls_ingress_inflow | Ingress の受信帯域幅。 | sls.ingress.route |
カスタム Nginx Ingress ログフォーマットでの自動スケーリング
SLS Ingress メトリックを使用して Pod を水平スケーリングする方法については、「Nginx Ingress メトリックに基づく Pod のスケーリング」をご参照ください。これには、ご利用のクラスターで Nginx Ingress のログ収集を Simple Log Service (SLS) に有効化し、正しく構成する必要があります。
デフォルトでは、クラスター作成時に Simple Log Service が有効になっています。デフォルト設定を維持した場合、クラスター作成後に SLS コンソール でアクセスログ分析ダッシュボードを表示し、Nginx Ingress のリアルタイムステータスをモニタリングできます。
クラスター作成時に Simple Log Service を無効にした場合は、スケーリングに SLS Ingress メトリックを使用するために、再度有効にして構成する必要があります。詳細については、「Nginx Ingress アクセスログの収集と分析」をご参照ください。
Nginx Ingress のログフォーマットをカスタマイズする必要があり、Ingress Controller のアクセスログフォーマットを変更した場合は、CRD 構成の正規表現抽出のための
processor_regexセクションを変更する必要があります。これは、クラスターで初めて Simple Log Service (SLS) を有効にしたときにデプロイされる AliyunLogConfig CRD が、ACK のデフォルトの Ingress Controller のログフォーマットにのみ適用されるためです。詳細については、「DaemonSet-CRD を使用したコンテナログの収集」をご参照ください。
CLI を使用した QPS メトリック sls_ingress_qps の取得方法
以下のコマンドを使用して、sls_ingress_qps メトリックを取得できます:
kubectl get --raw /apis/external.metrics.k8s.io/v1beta1/namespaces/*/sls_ingress_qps?labelSelector=sls.project={{SLS_Project}},sls.logstore=nginx-ingressこの場合、 {{SLS_Project}} は ACK クラスターの SLS プロジェクトの名前です。カスタム名を指定しない場合、デフォルトは k8s-log-{{ClusterId}} です。ここで、[ {{ClusterId}} ] はクラスターの ID です。
コマンドが次のエラーを返す場合:
Error from server: {
"httpCode": 400,
"errorCode": "ParameterInvalid",
"errorMessage": "key (slb_pool_name) is not config as key value config,if symbol : is in your log,please wrap : with quotation mark \"",
"requestID": "xxxxxxx"
}これは、このメトリックに利用可能なデータがないことを示します。これは、ALB Ingress が構成されていないのに sls_alb_ingress_qps のような ALB Ingress メトリックをクエリした場合などに発生する可能性があります。
コマンドが次のような結果を返す場合:
{
"kind": "ExternalMetricValueList",
"apiVersion": "external.metrics.k8s.io/v1beta1",
"metadata": {},
"items": [
{
"metricName": "sls_ingress_qps",
"timestamp": "2025-02-26T16:45:00Z",
"value": "50", # QPS 値
"metricLabels": {
"sls.project": "your-sls-project-name",
"sls.logstore": "nginx-ingress"
}
}
]
}これは、Kubernetes 外部メトリックの QPS が取得されたことを示しており、value が QPS 値です。
alibaba-cloud-metrics-adapter イメージのプル失敗
現象
ack-alibaba-cloud-metrics-adapter コンポーネントをバージョン 1.3.7 にアップグレードすると、イメージのプルが次のエラーで失敗します:
Failed to pull image "registry-<region-id>-vpc.ack.aliyuncs.com/acs/alibaba-cloud-metrics-adapter-amd64:v0.2.9-ba634de-aliyun".
原因
ack-alibaba-cloud-metrics-adapter コンポーネントは、現在インプレースアップグレードをサポートしていません。
ソリューション
コンポーネントをアップグレードするには、次の手順に従います:
現在のコンポーネント構成をバックアップします。
古いバージョンのコンポーネントをアンインストールします。
バックアップした構成を使用して、最新バージョンのコンポーネントをインストールします。
このプロセス中、メトリックの収集が停止するため、関連する HPA オブジェクトのスケーリングは一時停止されます。