Implementation of Intelligent HPA

Implementation of Intelligent HPA

KubeFest Tokyo 2020 の資料です。

Cc51eff3fb508929891d79dc8a382d80?s=128

Mizuki Urushida

June 13, 2020
Tweet

Transcript

  1. 負荷を予測して事前スケーリングする HPA の Custom Controller 実装
 @zuiurs (Mizuki Urushida) KubeFest

    Tokyo 2020 (2020/06/13)
  2. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 2

    みなさん HPA 使ってますか❓

  3. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 3

  4. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 4

    負荷を予測してスケールできたら
 もっと良いと思いませんか❓

  5. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 5

  6. 負荷を予測して事前スケーリングする HPA の Custom Controller 実装
 @zuiurs (Mizuki Urushida) KubeFest

    Tokyo 2020 (2020/06/13)
  7. 自己紹介
 7 • Mizuki Urushida (@zuiurs)
 • 2018~ CyberAgent, Inc.


    • 最近やったこと
 ◦ Kubernetes-native Testbed の構築・実装
 ◦ Cluster Autoscaler の Cloud Provider 実装
 ◦ Prow による CI/CD 基盤作成中
 ◦ HPA に時系列予測を組み込む Custom Controller の実装
 • 夕方までマンションが断水してます

  8. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 8

  9. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 9

    ☺ Horizontal Pod Autoscaler
 ☺ Background / Motivation
 ☺ About Intelligent HPA
 ☺ Architecture
 ☺ Tips of implemtation

  10. Horizontal Pod Autoscaler 10

  11. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 11

    HPA についておさらい

  12. Horizontal Pod Autoscaler
 12 • 指定したメトリクスのしきい値を
 基準に Pod を増減させる仕組み
 apiVersion:

    autoscaling/v2beta2 kind: HorizontalPodAutoscaler spec: minReplicas: 1 maxReplicas: 30 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 Deployment ( 66% / Pod ) 40% 70% Deployment ( 50% / Pod ) 90% 40% 60% 70% 30% *
  13. 複数メトリクスの監視
 13 • 最大レプリカ数が選択される
 ◦ 一方が小さくなったときに
 誤ってスケールダウンされない
 apiVersion: autoscaling/v2beta2 kind:

    HorizontalPodAutoscaler spec: metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - type: External external: metric: name: nginx.net.request_per_s target: type: AverageValue averageValue: 10 5 replicas
 7 replicas
 7 replicas

  14. 外部メトリクスの参照
 14 • Datadog/Prometheus のメトリクスを参照できる
 HPA
 metrics.k8s.io/v1beta1
 external.metrics.k8s.io/v1beta1
 kube-system/
 metrics-server


    default/
 datadog-cluster-agent-metrics-api 

  15. Background / Motivation 15

  16. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 16

    HPA は実測値をもとに
 スケールします

  17. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 17

    負荷上がったし
 レプリカ数増やすかー

  18. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 18

    負荷上がったし
 レプリカ数増やすかー
 負荷が上がらないと増えない

  19. しきい値設定に注意する
 19 • 許容負荷ギリギリに設定していると間に合わない
 ◦ 余裕をもたせたしきい値にする
 ◦ 余裕をもたせすぎるとリソースの無駄遣いになってしまう
 • READY

    まで時間のかかるアプリケーションだと設定が難しい
 ◦ StatefulSet は比較的そういうものが多い
 起動ラグ

  20. しきい値設定に注意する
 20 • 許容負荷ギリギリに設定していると間に合わない
 ◦ 余裕をもたせたしきい値にする
 ◦ 余裕をもたせすぎるとリソースの無駄遣いになってしまう
 • READY

    まで時間のかかるアプリケーションだと設定が難しい
 ◦ StatefulSet は比較的そういうものが多い
 起動ラグ

  21. Cluster Autoscaler 併用時の懸念
 21 • Pod が起動するためのリソースがクラスタにないかも
 ◦ CA は仕組み上

    Pending Pod が現れないと Node を増やせない
 ◦ Cluster Autoscaler の仕組みの詳細はこちら
 • READY までの時間が Node の起動時間と一致してしまう
 ノード起動ラグ

  22. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 22

    めんどくせえ!

  23. About Intelligent HPA 23

  24. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 24

    cyberagent-oss/intelligent-hpa

  25. Intelligent HPA (IHPA)
 25 • HPA への予測エントリの注入と
 予測ジョブやメトリクスの管理をするコントローラー
 ◦ Kubebuilder

    v2 を使用して実装
 ◦ 社内向けに作ったものを OSS 化
 • メトリクス管理は Datadog のみ実装している
 ◦ いずれ Prometheus (未検証) でクラスタ内完結させたい
 Intelligent
 HPA
 HPA
 Deployment
 生成
 操作

  26. その他特徴
 26 • メトリクスの予測ロジックのカスタマイズ
 ◦ 予測ロジックを入れたコンテナイメージを作って指定する
 • 予測メトリクスの調整機能
 ◦ 予測値の外れ度合いに応じて、次の予測値を調整


    • Type External の対応

  27. Minimum Usage
 27 • HPA を使っているようなイメージで使えるように設計
 apiVersion: ihpa.ake.cyberagent.co.jp/v1beta2 kind: IntelligentHorizontalPodAutoscaler

    spec: metricProvider: name: datadog datadog: apikey: xxx appkey: yyy template: spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - type: External external: metric: name: forecasted_cpu target: type: AverageValue averageValue: 10M 注入された
 予測エントリ
 Applied manifest
 Generated HPA

  28. • 予測値の参照は Datadog を経由
 • 先に参照するために時間をずらす
 ◦ 例) 9:00 の予測値は

    8:55 にずらす
 ◦ → 8:55 になると 9:00 の値が見える
 予測値を参照するためのずらし
 28 apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - type: External external: metric: name: forecasted_cpu target: type: AverageValue averageValue: 10M 注入された
 予測エントリ
 Generated HPA
 実測値
 予測値

  29. • 実測値のエントリを残して実負荷の
 レプリカ数を下回らないようにする
 ◦ 予測値は先に上昇する一方で
 先に下降し始める
 実測値のエントリの残存
 29 apiVersion: autoscaling/v2beta2

    kind: HorizontalPodAutoscaler spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - type: External external: metric: name: forecasted_cpu target: type: AverageValue averageValue: 10M 注入された
 予測エントリ
 Generated HPA
 実測値
 予測値

  30. Architecture 30

  31. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 31

  32. CRD とその役割
 32 • 責任の分割と単独利用性を考慮
 • IntelligentHorizontalPodAutoscaler (IHPA)
 ◦ IHPA

    に関わる全リソースの CRUD に集中
 • FittingJob
 ◦ 予測ジョブを実行して対象の
 ConfigMap に結果を出力
 • Estimator
 ◦ ConfigMap 内の予測データを
 Datadog などのプロバイダに送信

  33. CRD とその役割
 33 • 責任の分割と単独利用性を考慮
 • IntelligentHorizontalPodAutoscaler (IHPA)
 ◦ IHPA

    に関わる全リソースの CRUD に集中
 • FittingJob
 ◦ 予測ジョブを実行して対象の
 ConfigMap に結果を出力
 • Estimator
 ◦ ConfigMap 内の予測データを
 Datadog などのプロバイダに送信
 生成
 予測
 送信

  34. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 34

    あとは HPA に祈る

  35. IntelligentHorizontalPodAutoscaler
 35 • HPA の対象メトリクスの予測エントリを生成
 ◦ cpu とかは例外的に kubernetes.cpu.usage.total に変換するなど


    • 各種リソースをつなぎこむ
 ◦ FittingJob/Estimator は独立しているため、
 データ共有用の ConfigMap を統一
 ◦ ConfigMap に書き込むための RBAC をそれぞれ紐付ける
 予測データとして “cm1” を監視させる
 出力先として “cm1” 指定する

  36. FittingJob
 • 指定時刻周辺で学習を実行
 ◦ Affinity などで実行ノードを指定可能
 • デフォルトイメージは Prophet を使用した時系列予測


    ◦ Datadog へのアクセス・各種入出力はライブラリにしているので
 予測モデルの実装に集中できるようにしている
 n 時台に実行
 { "provider":{ "datadog":{ "apikey":"xxx", "appkey":"yyy" } }, "targetMetricsName":"nginx.net.request_per_s", "targetTags":{ "kube_deployment":"nginx" }, "seasonality":"daily", "dataConfigMapName":"cm1", "dataConfigMapNamespace":"loadtest", "customConfig":"" } 36
  37. Estimator
 37 • 予測データをずらして送信
 ◦ READY になるまでの時間 = ずらす時間として設定すると良い
 ▪

    時間のかかるアプリでも、かからないものとして値を考えられる
 timestamp,yhat,yhat_upper,yhat_lower 1582253873,176.89,244.83,50.89 1582253933,126.80,251.26,8.17 1582253993,134.48,268.67,75.97
  38. Estimator の予測値調整
 38 • Upper/Lower の値の範囲で予測値を調整する
 ◦ Prophet の設定では 90%ile/10%ile

    の値を吐き出す
 ◦ 予測の外れ度合いをチェック

  39. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 39

  40. Tips of implementation 40

  41. Kubebuilder のマニフェストカスタマイズ
 41 • マニフェスト生成は kustomize が使用されている
 ◦ 大体のパラメータは自由に変えられる
 ▪

    Namespace や Label など
 resources: - manager.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller newName: cyberagentoss/intelligent-hpa-controller newTag: latest apiVersion: apps/v1 kind: Deployment metadata: name: controller-manager namespace: system spec: template: spec: imagePullSecrets: - name: pull-secret • イメージを置換したり
 • パッチをあてたり

  42. controller-runtime の Watch と Own
 42 • Watch()
 ◦ 対象

    API の全リソースに対して発火
 • Own()
 ◦ 対象 API のうち自身の OwnerReference のついたものに対して発火
 ◦ Estimator の ConfigMap への予測データ格納監視はこれが役立った
 • 仕組みや基本的な機能についてはこちらの資料が詳しい
 ◦ Kubebuilder/controller-runtime 入門
 Estimator
 ConfigMap
 ConfigMap
 ConfigMap
 Watch()
 Estimator
 ConfigMap
 ConfigMap
 ConfigMap
 Own()

  43. マニフェスト設計における下位リソースの定義方法
 43 apiVersion: databases.spotahome.com/v1 kind: RedisFailover spec: redis: replicas: 3

    image: redis:4.0-alpine imagePullPolicy: IfNotPresent Redis Operator
 
 直接的
 パッチ的 (?)
 なにそれ
 ・書いたものがそのまま作られる 
 ・省略できない
 ・一部のフィールドだけ書ける 
 ・省略できる
 例
 ・Deployment の Pod 定義 
 ・CronJob の Job 定義 
 ・Redis Operator の Redis/Sentinel 定義 
 ・TiDB Operator の PD などの定義
 定義
 ・k8s.io/api から引っ張るだけなので楽 
 ・YAMLを書くときの階層が深くなる 
 ・本家と同じような定義をするので面倒 
 ・階層がフラットになる 
 Defaulting
 コード内で行う必要がある 
 CRD の機能でできる 
 • IHPA はパッチ的な定義を選択
 ◦ 下位リソースを隠蔽するのに
 こちらの方が都合が良かった

  44. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 44

    type JobPatchSpec struct { // related to Job ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"` BackoffLimit *int32 `json:"backoffLimit,omitempty"` Completions *int32 `json:"completions,omitempty"` // related to Pod Affinity *corev1.Affinity `json:"affinity,omitempty"` ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"` NodeSelector map[string]string `json:"nodeSelector,omitempty"` ServiceAccountName string `json:"serviceAccountName,omitempty"` Tolerations []corev1.Toleration `json:"tolerations,omitempty"` Volumes []corev1.Volume `json:"volumes,omitempty"` // related to Container Args []string `json:"args,omitempty"` Command []string `json:"command,omitempty"` Env []corev1.EnvVar `json:"env,omitempty"` EnvFrom []corev1.EnvFromSource `json:"envFrom,omitempty"` Image string `json:"image,omitempty"` ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` Resources corev1.ResourceRequirements `json:"resources,omitempty"` }
  45. Predictive HPA
 45 • 対抗馬
 ◦ 名前が良いので嫉妬している
 • 作り終わってホッとしていたらなんか出てきた
 •

    アプローチの違い
 ◦ IHPA: メトリクスを予測・HPA 経由でスケール
 ◦ PHPA: レプリカ数を予測・Scale Subresource 経由でスケール
 • 詳細はこちら

  46. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 46

    cyberagent-oss/intelligent-hpa

  47. まとめ (3 行)
 47 • HPA は一部ケースではしきい値決定が非常に難しい
 • 予測値に対してスケールすると HPA

    がうまく働きやすくなる
 • 予測値エントリを注入する Custom Controller を作りました

  48. Implement custom controller for metrics prediction @KubeFest Tokyo 2020 48

    Thank you for your watching! Any Question?