LoginSignup
0
0

More than 3 years have passed since last update.

Wavefrontで学ぶHorizontal Pod Autoscaler ~Wavefront情報からスケールする

Last updated at Posted at 2020-08-11

この文章は、WavefrontでHorizontal Pod Autoscaler シリーズの第二回目です。

シリーズ

第一回 : 概要編
第二回 : Wavefrontの情報からスケールする ← いまここ
第三回 : サーバーレスもどきを実装する

始めに

概要にも記載したよう、この記事では、Wavefrontのメトリクスをもとに、HPAを実装する方法を紹介します。

今回はまずシンプルにCPUベースでのHPAを実装します。

前提知識

前提知識として、HPAとしてKuberenetesの利用できるAPIとしては3つあります。

  1. metrics.k8s.io : Coreとよばれるメトリクスである、マニュアルにあるよう、CPUとMemoryの使用率を報告します。実際の収集方法はmetrics-serverもしくは Heapster経由で取得します。なお、それらはKubernetesのデフォルトで動いているわけではなく、別途起動しないといけないものです。
  2. custom.metrics.k8s.io : 上とは別に外部データソースからメトリクスを収集してメトリクスに反映するものです。ここに一部実装可能なものが紹介されています。CNCF的にはPrometheusが推奨されています。
  3. external.metrics.k8s.io : これも外部データソースからメトリクスですが、さらに自由度の高い定義ができるようになっています。

このうち、Wavefrontでは、2と3の方法をサポートしています。
2で使えるメトリクス一覧は以下の定義されています。

これが実際のどのWavefrontのメトリクスとマッピングされるかはあとで、触れます。
3の方法では、Annotationを使い好きなメトリクスをマッピングさせることもできます。

準備編

さて検証を始める前に以下が必要です。

  • WavefrontのアカウントとAPIキー
  • Kubernetes環境
  • Helm(v3がおすすめ) cli

なお、Wavefrontのアカウントないよ、という場合ですが、Trialの申し込みをお勧めします。
もし、それも面倒な場合、非常に多くの制約をもちますが、サインアップ不要のFreemiumアカウントもあるにはあります。

現状WavafrontのFreemiumアカウントはSpring Boot経由でないと、作成ができないようになっています。最低限、ここで紹介したようにHelloWorldアプリを作成してください。作成すると~/.wavefront_freemiumにAPIキーが含まれます。

インストール

まずは、Wavefrontのコンポーネントをインストールします。
インストールするのは、以下の2つです。

  • Wavefront Collector
  • Wavefront HPA Adaptor

どちらでも使うので、以下のmyvalues.yamlを用意します。
XXXXには取得したWavefrontのアカウントとAPIキーを指定します。またClusterNameは判別しやすい任意の名前をつけてください。

clusterName: mhoshi-test

wavefront:
  url: https://XXXXX.wavefront.com
  token: XXXXXXXXXXXXXXX

さらに、HelmのRepositoryをダウンロードします。

helm repo add wavefront https://wavefronthq.github.io/helm/
helm repo update

Wavefront Collectorのインストール

以下の手順でインストールします。

kubectl create namespace wavefront
helm install -f myvalues.yaml wavefront wavefront/wavefront --namespace wavefront 

Wavefront HPA Adapterのインストール

以下の手順でインストールします。

kubectl create namespace wavefront-adapter
helm install -f myvalues.yaml wavefront-adapter wavefront/wavefront-hpa-adapter --namespace wavefront-adapter

以上でインストールの完了です。

CPU情報でスケールしてみる

では、HPAを早速ためしてみます。
まず作業用のネームスペースを作成します。

kubectl create ns hpa

なんでもいいのでKubernetesのDeploymentを作成します。
筆者の場合は手っ取り早く以下で作ります。

kubectl create deployment --image=nginx hpa-pods -n hpa

次に、HPAの定義を作ります。


cat <<EOF | kubectl apply -n hpa -f -
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: example-hpa-custom-metrics
spec:
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Pods
    pods:
      metricName: cpu.usage_rate
      targetAverageValue: 300m
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hpa-pods
EOF

これは、最小1、最大5Podまでを定義したHPAです。
そして、targetAverageValue: 300mにあるよう、300millisecondのCPU使用率に落ち着くことを期待しています。

HPAができたことを確認します。なお、直後はTARGETSunknownになっているかもしれないですが、これはメトリクスがまだWavefrontに届いていない場合で、すこしまてば、値が取得されます。

kubectl get hpa -n hpa
NAME                         REFERENCE             TARGETS          MINPODS   MAXPODS   REPLICAS   AGE
example-hpa-custom-metrics   Deployment/hpa-pods   <unknown>/300m   1         5         0          8s

しばらくすると、TARGETSに値が入るはずです。

kubectl get hpa -n hpa
NAME                         REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
example-hpa-custom-metrics   Deployment/hpa-pods   0/300m    1         5         1          6m20s

CPU負荷をあげていきます。
手っ取り早い方法がContainerに入って、無限ループをつくってしまう方法です。

kubectl exec -it `kubectl get pods -l app=hpa-pods -n hpa -o name` -n hpa bash

Containerログイン後、以下のコマンドを実行します。以下のコマンドは何もしない無限ループを1つ作ります。理論的には、このコマンドによって1つのvCPU使用率を100%にします。

while true ; do : ; done &

WavefrontのUIを開きます。
Metrics Viewerを開いて、以下の式を入力します。ClusterNameはそれぞれ指定したものを記載してください。

ts("kubernetes.pod.cpu.usage_rate",  pod_name="hpa-*" and namespace_name="hpa")

これは、namepsace名hpaのpod名hpa-*の全てのCPU使用率を算出しています。
すると以下のようにCPU使用率があがっていることがわかります。

image.png

現在設定上はCPU使用率300mを超えた場合で、スケリーングを開始するようにしています。
しばらく放置すると、pod数が5に変動します。

% kubectl get hpa -n hpa
NAME                         REFERENCE             TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
example-hpa-custom-metrics   Deployment/hpa-pods   219200m/300m   1         5         5          19m
% kubectl get po -n hpa
NAME                       READY   STATUS    RESTARTS   AGE
hpa-pods-8d86f4dc5-2xn52   1/1     Running   0          8m46s
hpa-pods-8d86f4dc5-7wnpw   1/1     Running   0          8m46s
hpa-pods-8d86f4dc5-qbdn9   1/1     Running   0          7m12s
hpa-pods-8d86f4dc5-r55hb   1/1     Running   0          8m46s
hpa-pods-8d86f4dc5-wgc8g   1/1     Running   0          20m

また、CPUをぶん回したPodを止めるには以下を実行します。

kubectl delete po hpa-pods-8d86f4dc5-wgc8g -n hpa

しばらくすると、Podがまた1で落ち着きます。

kubectl get hpa -n hpa
NAME                         REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
example-hpa-custom-metrics   Deployment/hpa-pods   0/300m    1         5         1          35m

どうやってメトリクスは計算されている?

これについては、コードがみるのが早いです。
まず、WavefrontへのQueryを担っているのが以下の部分です。

この中でCodeのコメントアウト行にもコメントされていますが、HPAの定義をもとに以下に変換されます。


    // if Prefix=kubernetes, metric='cpu.usage_rate', resType='pod', namespace='default' and names=['pod1', 'pod2']
    // ts(kubernetes.pod.cpu.usage_rate, (pod_name="pod1" or pod_name="pod2") and (namespace_name="default"))
    query := fmt.Sprintf("ts(%s.%s.%s%s)", t.prefix, resType, metric, filters)

つまり、HPAを以下のように定義した場合、


spec:
  ...
  metrics:
  - type: Pods
    pods:
      metricName: cpu.usage_rate
      targetAverageValue: 300m

Wavefrontへは<prefix>.<type>.<metricName>のメトリクスを探しにいきます。
この場合

  • <prefix> は起動オプションでkubernetesがデフォルト
  • <type> はHPAの定義のtype: Podsからpodに変換
  • <metricName> はHPA定義のmetricName: cpu.usage_rateからcpu.usage_rate

つまり、kubernetes.pod.cpu.usage_rateを参照し、pod名やNamespaceを絞り込んでいくようになっています。

より標準の実装方法は、こちらにも詳しく記載されています。

まとめ

この回では、Wavefrontの統計にやってくるCPU情報をもとにHPAを実装しました。
次回の「サーバーレスもどきを実装する」ではより突飛なメトリクスを元にHPAを実装してみます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0