Wavefrontで学ぶHorizontal Pod Autoscaler Part-3
この文章は、Wavefrontで学ぶHorizontal Pod Autoscaler シリーズの第三回目です。
シリーズ
第一回 : 概要編
第二回 : Wavefront情報からスケールする
第三回 : サーバーレスもどきを実装する ← いまここ
始めに
前回の前提知識にもあったよう、Kubernetesは、HPAとして3つのAPIをサポートしています。
その中で、Wavefrontはexternal.metrics.k8s.io
を使った自由度の高いメトリクスの定義をサポートしています。
以下により詳細の説明があります。
ここでのポイントが実質Wavefrontのメトリクスをどれでもつかって自由にHPAができるというものです。 今回はこれをつかって、「サーバーレスもどき」のアプリケーションを作ってみます。
検証方法
今回は以下の図示されているような構成で検証します。
つまり、Kubernetesとは別に稼働しているWebアプリ(/counter
)に対して、リクエストを送信してスケールアップをするような構成です。特にリクエストがやってこない場合、徐々にスケールダウンしていきます。
なお、「サーバーレスもどき」と書いたわりに、必ず最低1つのPodが常に起動し続けます。
これは、HPAScaleToZero
とよばれるHPAのminインスタンスの値0
を許可するが、執筆時点でまだAlphaの実装であり、GAとされていないためです。
これがGAされれば、より「サーバーレスもどき」に近づくのですが、今回は諦めます。
準備
アプリの準備
今回は、すでに持っているWavefrontのアカウントに対してMetricsを送付するようなアプリケーションを書きます。様々な方法がありますが、ここでは一番手っ取り早いSpring Bootを使ったアプリを作ります。
なお以下のアプリはWavefrontにアクセスできる端末であればどこで起動しても問題ないです。PC上でもいいです。最低限OpenJDKがインストールされている必要があります。
https://github.com/mhoshi-vm/wf-demanabu-hpa
このレポジトリーをクローンします。
1git clone https://github.com/mhoshi-vm/wf-demanabu-hpa
2cd wf-demanabu-hpa
そして以下のファイルを編集します。
1vi src/main/resources/application.properties
中身はWavefrontのアカウントとAPIキーを登録してください。
1wavefront.freemium-account=false
2management.metrics.export.wavefront.uri=https://<account>.wavefront.com
3management.metrics.export.wavefront.api-token=<API key>
準備ができたら起動します。
1./mvnw spring-boot:run
ただしく起動されたら、別のプロンプトでしばらく、URLへリクエストを送信します。
1curl localhost:8080/counter
Count Complete
と出れば問題ないです。
この状態でWavefrontのUIにログインします。 そして以下のQueryを実行します。
1mdiff(5m, ts(custom.metrics.counter))
すると以下のように、curlを実行した回数分、5分間停滞するような画面になっていればOKです。
アプリは起動したままで次のステップに移ります。
HPAの準備
前回のゴミ掃除も兼ねて、作業用のネームスペースを再作成します。
1kubectl delete ns hpa
2kubectl create ns hpa
KubernetesのDeploymentを作成します。
1kubectl create deployment --image=nginx hpa-pods -n hpa
そして、今回は以下のHPAを作ります。
1cat <<EOF | kubectl apply -n hpa -f -
2apiVersion: autoscaling/v2beta1
3kind: HorizontalPodAutoscaler
4metadata:
5 name: example-hpa-external-metrics
6 annotations:
7 wavefront.com.external.metric/scale_counter: 'mdiff(5m, ts(custom.metrics.counter))'
8spec:
9 minReplicas: 1
10 maxReplicas: 5
11 metrics:
12 - type: External
13 external:
14 metricName: scale_counter
15 targetAverageValue: 1
16 scaleTargetRef:
17 apiVersion: apps/v1
18 kind: Deployment
19 name: hpa-pods
20EOF
キモがいかです。
- 参照したいメトリクスをAnnotationをつかって表現している。この場合は、
wavefront.com.external.metric/scale_counter: 'mdiff(5m, ts(custom.metrics.counter))'
- spec.metricsをAnnotationで指定した名前を定義します。この場合は
scale_counter
定義としてはこれだけです、作成されたHPAをみてみましょう
1kubectl get hpa -n hpa
2NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
3example-hpa-external-metrics Deployment/hpa-pods 0/1 (avg) 1 5 1 25m
この状態で、curl localhost:8080/counter
を3回実行します。
しばらくするとTARGETSの値がCurlを実行した1
に近い値に落ち着くと思います。またReplica数も3になります。
1kubectl get hpa -n hpa
2NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
3example-hpa-external-metrics Deployment/hpa-pods 967m/1 (avg) 1 5 3 26m
これは、つまりPodに対する平均値が計算され、3(curlの回数) / 3(podの値) = 1
となっているためです。
そして、5分後、また0
になり、ゆっくりReplica数も1
に近づいていくと思います。
1kubectl get hpa -n hpa
2NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
3example-hpa-external-metrics Deployment/hpa-pods 0/1 (avg) 1 5 1 35m
まとめ
- Wavefrontの
external.metrics.k8s.io
を使えばどんなメトリクスをつかってもHPAができます。
全三回のシリーズから、Wavefront + HPAの実装がシンプルに実現できることが体験できました。