---
# System prepended metadata

title: dreamkast のオートスケーリングのために KEDA を使ってみる

---

# dreamkast のオートスケーリングのために KEDA を使ってみる

## Goals

- 目的
    - カンファレンス本番時のみ、普段よりも大きな minReplicas, maxReplicas が設定された HPA を利用したい
- 出来た
    - オートスケールさせたい Rs の minReplicas をカンファレンス当日のみ大きめに設定する
- 出来なかった
    - 対象の Rs の maxReplicas を動的に変更する

## About KEDA

doc: https://keda.sh/docs/2.8/concepts/

- 「KEDA は HPA v2 の `type: External` の指定先」相当と考えると分かりやすい
    - +αでゼロスケール可能という利点もあるが、今回は関係なし
- そもそも HPA v2 の `type: External` って？ → Prometheus とかの外部のメトリクスをもとにオートスケールするための機能
    - Prometheus の場合、 [prometheus-adapter](https://github.com/kubernetes-sigs/prometheus-adapter) をインストールすることで HPA Controller -> APIServer -> prometheus-adapter -> Prometheus という流れで Prometheus のメトリクスを参照可能
    - 参考. 
        - https://blog.studysapuri.jp/entry/2020/11/30/scheduled-scaling-with-hpa
- prometheus-adapter は「Prometheus のための external APIServer」だったが、 KEDA は「様々なサービスのための external APIServer proxy」みたいな感じ
    - KEDA は HPA v1 で動くような作りになってるのでこの説明は厳密には間違ってる (APIServer として動作はしない) が、まあ気にしない

- つまり、KEDA が提供するのは「オートスケールの指標」であって、「HPA.spec の `maxReplicas`, `minReplicas` を動的に設定する機能」ではない
    - ただ、オートスケールの指標を提供できるということは実質的に minReplicas 以上の最小 Pod 数を設定することが可能 (後述)

### NOTICES

- 既存の HPA と KEDA の ScaledObject を同じターゲットに対して併用することは出来ない
    - [ドキュメント](https://keda.sh/docs/2.8/faq/#dont-combine-scaledobject-with-horizontal-pod-autoscaler-hpa)

## Concrete example

方針: KEDA の [External Scaler](https://keda.sh/docs/2.0/scalers/external/) と [CPU Scaler](https://keda.sh/docs/2.0/scalers/cpu/) を利用して、「基本的に CPU ベースのオートスケール」「カンファレンス当日だけ minReplicas を大きめに引き上げる」を実現する

- external scaler のソースコード: https://github.com/cloudnativedaysjp/dreamkast-external-scaler
- マニフェスト
    - 平時には minReplicas: 2, maxReplicas: 6 で CPU Utilization 60% をしきい値とした HPA が効く
    - カンファレンス当日には minReplicas が 4 になるように動作する
        - 勿論この場合も、 CPU Utilization 60% をしきい値として 4~6 の範囲でオートスケールする

```yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.14.2
          ports:
            - containerPort: 80
          resources:
            limits:
              cpu: 100m
              memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  ports:
    - port: 8000
      targetPort: 80
      protocol: TCP
  selector:
    app: nginx
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app
  pollingInterval:  30
  minReplicaCount:  2
  maxReplicaCount:  6
  advanced:
    horizontalPodAutoscalerConfig:
      behavior:
        scaleDown:
          policies:
          - type: Percent
            value: 100
            periodSeconds: 15
  triggers:
  - type: cpu
    metadata:
      type: Utilization
      value: "60"
  - type: external
    metadata:
      scalerAddress: ${dreamkast-external-scalerのアドレス}
      minReplicas: "4"
```

## Another concerns

- そもそも KEDA を利用せずとも、HPA v2 + 自前 APIServer で良いのでは？
    - その通り of the year 2022
    - [この辺](https://qiita.com/go_vargo/items/c7a526c0d4dbc9199dd4) とか読んで自前 APIServer を作ってみるのが良いかも知れない
        - どのくらい大変か分かってないので要 PoC 作成

