本文の内容は、2021年10月7日にDavid de Torres Huertaが投稿したブログ(https://sysdig.com/blog/kubernetes-hpa-prometheus/)を元に日本語に翻訳・再構成した内容となっております。
この記事では、Prometheusメトリクスを使用するKubernetes HPAをデプロイするためにKedaを設定する方法を学んでいきます。
Kubernetes Horizontal Pod Autoscalerは、CPUやメモリなどのリソースの使用状況に応じてポッドをスケールアップすることができます。これは多くのシナリオで有用ですが、Webサーバーの接続待ちやAPIのレイテンシーなど、より高度なメトリクスが必要なユースケースもあります。また、他のケースでは、複数のメトリクスを数式で組み合わせたり、アグリゲーションを行う必要があるかもしれません。
Kedaは、Prometheusのクエリと他の複数のスケーラーを使って、Kubernetesのポッドをスケールすることができるオープンソースプロジェクトです。
Kubernetes HPA
Kubernetes HPAは、KubernetesメトリクスAPIエンドポイントの1つに存在するメトリクスに依存してオブジェクトをスケールすることができます。Kubernetes HPAがどのように機能するかについては、こちらの記事で詳しく説明しています。Kubernetes HPAは非常に便利ですが、2つの重要な制限があります。1つ目は、メトリクスの組み合わせができないことです。現在確立している接続数と最大接続数で接続使用量を計算するなど、複数のメトリクスを組み合わせることが便利なシナリオがあります。
2つ目の制限は、Kubernetesがデフォルトで公開しているメトリクスの数が少ないことです。時には、アプリケーションがより高度なメトリクスを公開することがありますが、それは自分自身またはエクスポーターを介して行われます。より多くのメトリクスを公開するには、Kubernetes APIのメトリクスエンドポイントで公開する必要があります。
HPAとPrometheusのメトリクスをKedaで接続する
Kedaは、Kubernetes HPAでのPrometheusメトリクスの使用を簡素化するオープンソースプロジェクトです。Kedaのインストール
Kedaをインストールするには、Helmを使うのが一番簡単です。helm repo add kedacore https://kedacore.github.io/charts helm repo update kubectl create namespace keda helm install keda kedacore/keda --namespace keda
その他のインストール方法については、Kedaのドキュメントページをご覧ください。
Kedaはどのようにしているのか?
Kedaには、Kubernetesのオペレータがあり、ScaledObjectというCustom Resource Definition (CRD)オブジェクトを定義することで、メトリクスサーバとHPAの両方を作成します。このオブジェクトでは、何をどのようにスケールさせるかを定義することができます。何をスケールさせられるのか
簡単:ほとんど何でもです:Kedaでは、DeploymentsやStatefulSetsなど、通常のKubernetesのワークロードをスケールすることができます。また、他のCRDをスケールすることもできます。ジョブをスケールするための別のCRDも用意されています。
スケールの方法
ここで魔法がかかります。Kedaではトリガーを定義することができ、様々な種類のトリガーがあります。この記事では、Prometheusのトリガーに焦点を当てます。ScaledObject に対して Prometheus トリガーを設定する際には、Prometheus エンドポイントと Prometheus クエリーを定義します。Kedaはその情報を使ってPrometheusサーバーに問い合わせ、Kubernetesの外部メトリクスAPIでメトリクスを作成します。ScaledObjectを作成すると、Kedaは自動的にそのためのKubernetes HPAを作成します。
これだけです。Kubernetes APIのメトリクスエンドポイントでのメトリクスの発行や、Kubernetes HPAオブジェクトの作成も気にする必要はありません!
例を挙げてみましょう
nginx-serverのデプロイメントのためのHPAが必要だと想像してください。Nginx exporterからのnginx_connections_waitingメトリクスに基づいて、1から5のレプリカにスケールさせたいとします。500以上の接続待ちがある場合は、新しいポッドをスケジュールします。HPAを起動するためのクエリーを作成してみましょう:
sum(nginx_connections_waiting{job="nginx"})
簡単でしょう?このクエリーは、nginxジョブのnginx_connections_waitingメトリクス値の合計を返すだけです。
Prometheusのクエリー言語であるPromQLについてもっと知りたいですか?PromQLのスタートガイドをご覧ください。
この例のために、ScaledObjectを定義しましょう:apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: nginx-scale namespace: keda-hpa spec: scaleTargetRef: kind: Deployment name: nginx-server minReplicaCount: 1 maxReplicaCount: 5 cooldownPeriod: 30 pollingInterval: 1 triggers: - type: prometheus metadata: serverAddress: https://prometheus_server/prometheus metricName: nginx_connections_waiting_keda query: | sum(nginx_connections_waiting{job="nginx"}) threshold: "500"
metricNameパラメーターに注目してください。これは、クエリーからの値を受け取るために設定したカスタム名です。Keda はクエリーの結果を取得し、それをもとに nginx_connections_waiting_keda メトリクスを作成します。そして、このメトリクスを使ってエスカレーションのトリガーとします。また、serverAddressの変更も忘れないでください。:-)
あとは、ScaledObjectの定義を適用するだけで、HPAが動き出します。
Kedaは他に何ができますか?
Prometheus サーバーでメトリクスを使用し、Prometheus クエリーを適用して好きなように組み合わせることができるという利点に加えて、Keda にはさらに特別な機能があります。- デフォルトのKubernetes HPAでは1以上の最小値しか許可されていませんが、Kedaではオブジェクトをゼロまでスケールダウンすることができます。
- エラー接続などでメトリクスから値を取得できない場合に備えて、レプリカの数を定義することができます。
- 認証付きのPrometheusエンドポイントとのセキュアな接続をサポートしています。
まとめ
本記事では、Kubernetes APIのメトリクスエンドポイントを拡張することなく、簡単にKubernetes HPAを作成する方法を学びました。Kedaをインストールして設定するだけです。例題では、PrometheusのPromQLクエリーを使ってオートスケーラーを起動する方法も学びました。