Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Implementation of Intelligent HPA

Implementation of Intelligent HPA

KubeFest Tokyo 2020 の資料です。

Mizuki Urushida

June 13, 2020
Tweet

More Decks by Mizuki Urushida

Other Decks in Technology

Transcript

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

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

  2. 自己紹介
 7 • Mizuki Urushida (@zuiurs)
 • 2018~ CyberAgent, Inc.


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

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

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

  4. 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% *
  5. 複数メトリクスの監視
 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

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

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

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

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

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

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

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

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

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

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

  11. 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

  12. • 予測値の参照は 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
 実測値
 予測値

  13. • 実測値のエントリを残して実負荷の
 レプリカ数を下回らないようにする
 ◦ 予測値は先に上昇する一方で
 先に下降し始める
 実測値のエントリの残存
 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
 実測値
 予測値

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

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

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

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

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


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

  17. 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
  18. 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
  19. 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 • イメージを置換したり
 • パッチをあてたり

  20. 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()

  21. マニフェスト設計における下位リソースの定義方法
 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 はパッチ的な定義を選択
 ◦ 下位リソースを隠蔽するのに
 こちらの方が都合が良かった

  22. 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"` }
  23. Predictive HPA
 45 • 対抗馬
 ◦ 名前が良いので嫉妬している
 • 作り終わってホッとしていたらなんか出てきた
 •

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

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

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