0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Kubernetes】Horizontal Pod Scaler is 何

Posted at

Horizontal Pod Scalerとは

Horizontal Pod Scaler(以降HPA)とはPodのCPU使用の負荷に応じて、どの程度Podをスケールイン/アウトをするかを定義する機能です。

HPAのマニフェストの定義において、Deploymentに対して命令を送り、Replica数を制御します。
以下のマニフェストファイルを例に解説していきます。

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: aws-hpa
  namespace: aws-01
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: aws-auth-internal
  minReplicas: 1
  maxReplicas: 3
  metrics: 
  - type: ContainerResource
    containerResource:
      container: aws-auth-internal
      name: cpu
      target:
        type: Utilization
        averageUtilization: 90
  - type: ContainerResource
    containerResource:
      container: aws-auth-internal
      name: memory
      target:
        type: Utilization
        averageUtilization: 90    
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Pods
        value: 1
        periodSeconds: 300
    scaleDown:
      stabilizationWindowSeconds: 3600
      policies:
      - type: Pods
        value: 1
        periodSeconds: 300

spec.scaleTargetRef

spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment # スケーリング対象のリソース種類
    name: aws-auth-internal # スケーリング対象のDeployment名
  minReplicas: 1 # 最小レプリカ数
  maxReplicas: 3 # 最大レプリカ数

spec.scaleTargetRefにおいて、スケーリング対象のリソースを指定します。

  • kind: Deployment -> スケールする対象にDeploymentを指定しています
  • name: aws-auth-internal -> スケーリング対象のDeployment名を指定いています。ここで指定したDeployment名とDeploymentのマニフェストファイルのmetadata.nameの名称と一致させる必要があります
  • minReplicas: 1 -> 最小のレプリカ数を指定
  • maxReplicas: 3 -> 最大のレプリカ数を指定

spec.metrics

  metrics: 
  - type: ContainerResource # コンテナのリソース使用率を監視
    containerResource:
      container: aws-auth-internal # 監視対象のコンテナ名
      name: cpu # 監視するリソース = CPU
      target: 
        type: Utilization # 使用率
        averageUtilization: 90 # 使用率90%以上

spec.metricsにおいてHPAがスケーリングの判断に使用するメトリクスを定義しています。

  • type: ContainerResource -> コンテナのリソース使用率を監視することを定義しています
  • container: aws-auth-internal -> 監視対象のコンテナ名を指定しています。ここで指定したコンテナ名はDeploymentで指定するspec.containers.nameの名称と一致する必要があります
  • name: cpu -> 監視するリソースがCPUであることを示しています
  • type: Utilization -> 監視するCPUの使用率を基準にスケーリングします
  • averageUtilization: 90 -> CPU使用率の具体的な数字を定義しています。この場合90%を超えるとスケールアウトします。
 - type: ContainerResource
    containerResource:
      container: aws-auth-internal
      name: memory # 監視するリソース = メモリ
      target:
        type: Utilization
        averageUtilization: 90

リスト形式で監視するリソースの対象を複数指定します。
name: memoryとすることでメモリ使用率が90%以上の場合にスケールアウトする定義をしています。

spec.behavior

  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0 # 即時反映
      policies:
      - type: Pods
        value: 1 # 1Podずつ増加
        periodSeconds: 300
    scaleDown:
      stabilizationWindowSeconds: 3600
      policies:
      - type: Pods
        value: 1
        periodSeconds: 300

spec.behaviorにおいてスケールする挙動を定義しています。

scaleupの挙動

具体的な挙動は、メトリクスが90%を超えた場合に、stabilizationWindowSeconds: 0と定義しているため即時にスケールアウトが開始します。

  • value: 1 -> Podが1つ追加されます
  • periodSeconds: 300 -> 90%超過が300秒、つまり5分間続けば1つPodを追加します(ただし、spec.scaleTargetRefで定義している通りmaxReplicas: 3までです)
  • 時刻 00:00: CPU使用率が95% → Podが1つ増え 2つに。
  • 時刻 00:05: まだ90%超え → さらに1Pod増え 3つに(maxReplicas到達)。
  • 時刻 00:10: 3Podでも90%超えていても、これ以上増やせない(maxReplicas制限)。

scaleDownの挙動

具体的な挙動はメトリクスが継続的に90%を下回っている場合にスケールインをします。
継続的とはstabilizationWindowSeconds: 3600でメトリクスが90%を下回ってから一時的な負荷低下でスケールインすることを防ぐために3600秒、つまり1時間は様子を見るという意味になります。
1時間以内に90%を超えることがなければ、Podを一つ削除します。
そこからさらにperiodSeconds: 300で5分間隔でPodを一つ削除します。

  • 時刻 00:00: CPU使用率が95% -> Podが増える (Podが2つ)
  • 時刻 00:05: まだ90%超え → さらに1Pod増え 3つに
  • 時刻 01:05: CPU使用率が60% -> スケールインを検知開始しここから1時間メトリクスの状況を監視
  • 時刻 02:05: CPU使用率が60% -> Podが1つ削除 (Podが2つ)
  • 時刻 02:10: CPU使用率が60% -> Podが1つ削除 (Podが1つminReplicas: 1の上限となりこれ以下とはならない)

KubernetesのHPAマニフェストにおけるスケールアップ/スケールダウンの言葉の意味はAWSなどで使用されるスケールアップ/スケールダウンの意味とは異なります。
マニフェスト上ではscaleUpscaleDownと記載しておりますが、実際にはスケールアウト = Podを増やすこと、スケールイン = Podを減らすことの意味です。

検証

ローカルkindクラスター上でDeployment, HPAをapplyして動作検証してみます。
前提としてメトリクスを収集するためにmetrics-serverが必要となるめ、metrics-serverのインストールから実施していきます。
kindのクラスターは構築できている前提でお話します。
環境はWindowsのWSL2の環境で実行していきます。

metrics-serverの構築

以下コマンドでmetrics-serverをapplyします。

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created

# metrics-serverがkubeletとのTLS証明書検証をスキップする
# このコマンドを実行しておかないとmetrics-serverが正常に起動しない
kubectl patch -n kube-system deployment metrics-server --type=json \
  -p '[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'

# metrics-serverが正常に起動しているかの確認
kubectl get pods -n kube-system -l k8s-app=metrics-server
NAME                              READY   STATUS    RESTARTS   AGE
metrics-server-598746d78d-kf7nw   1/1     Running   0          49s

以下Deployment.yamlをapplyします。
以下yamlは0.1CPUを最低限保証するリソースとしてPodに割り当てます。
またlimitsで0.2CPUを上限として設定することで、Podがこの制限を超えてCPUを使用することを制限します。

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cpu-load-generator
  labels:
    app: cpu-load-generator
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cpu-load-generator
  template:
    metadata:
      labels:
        app: cpu-load-generator
    spec:
      containers:
      - name: busybox
        image: busybox
        resources:
          requests:
            cpu: "100m"  # 0.1 CPUコアをリクエスト
          limits:
            cpu: "200m"  # 0.2 CPUコアが上限
        command: ["sh", "-c"]
        args:
        - while true; do echo 'Generating CPU load...'; timeout 0.5 sha256sum /dev/zero; sleep 0.5; done

STATUSがRunningになっていればOKです。

kubectl apply -f deployment.yaml 
deployment.apps/cpu-load-generator created

kubectl get pods -w
NAME                                  READY   STATUS    RESTARTS   AGE
cpu-load-generator-6897fdd78f-qpjxq   1/1     Running             0          73s

以下のhpa.yamlをapplyします。

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-demo
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: cpu-load-generator  # Deploymentの名前と一致させる
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: ContainerResource
    containerResource:
      container: busybox  # Deploymentのコンテナ名と一致
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50  # CPU使用率50%でスケール
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Pods
        value: 1
        periodSeconds: 30  # 30秒ごとに1Pod増加
    scaleDown:
      stabilizationWindowSeconds: 60  # 1分待機後に削除
      policies:
      - type: Pods
        value: 1
        periodSeconds: 30  # 30秒ごとに1Pod削除

HPAをapplyします。

kubectl apply -f hpa.yaml 
horizontalpodautoscaler.autoscaling/hpa-demo created

以下コマンドでPodのスケール状況を確認してみます。

kubectl get hpa hpa-demo -w
NAME       REFERENCE                       TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/cpu-load-generator   118%/50%   1         5         1          17s
hpa-demo   Deployment/cpu-load-generator   117%/50%   1         5         2          31s
hpa-demo   Deployment/cpu-load-generator   115%/50%   1         5         2          46s
hpa-demo   Deployment/cpu-load-generator   116%/50%   1         5         3          61s
hpa-demo   Deployment/cpu-load-generator   113%/50%   1         5         3          76s
hpa-demo   Deployment/cpu-load-generator   115%/50%   1         5         4          92s
hpa-demo   Deployment/cpu-load-generator   118%/50%   1         5         4          107s
hpa-demo   Deployment/cpu-load-generator   112%/50%   1         5         5          2m2s
hpa-demo   Deployment/cpu-load-generator   114%/50%   1         5         5          2m32s
hpa-demo   Deployment/cpu-load-generator   115%/50%   1         5         5          2m48s
hpa-demo   Deployment/cpu-load-generator   116%/50%   1         5         5          3m3s
hpa-demo   Deployment/cpu-load-generator   113%/50%   1         5         5          3m18s

上記の結果から、hpa.yamlで定義した通りの動作になっているのがわかります。
apply直後からCPU使用率が閾値50%に対して118%と大幅に超過しています。

NAME       REFERENCE                       TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/cpu-load-generator   118%/50%   1         5         1          17s

applyから30秒経過後、CPU使用率117%と超過しており、Pod数が1 -> 2に増加しています

NAME       REFERENCE                       TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/cpu-load-generator   118%/50%   1         5         1          17s
hpa-demo   Deployment/cpu-load-generator   117%/50%   1         5         2          31s

さらに30秒経過後、CPU利用率116%と超過しており、Pod数が 2 -> 3へ増加しています。

NAME       REFERENCE                       TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/cpu-load-generator   118%/50%   1         5         1          17s
hpa-demo   Deployment/cpu-load-generator   117%/50%   1         5         2          31s
hpa-demo   Deployment/cpu-load-generator   115%/50%   1         5         2          46s
hpa-demo   Deployment/cpu-load-generator   116%/50%   1         5         3          61s

以降最終的にPod数が最大数の5つまでスケールアウトしていることがわかります。

NAME       REFERENCE                       TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/cpu-load-generator   118%/50%   1         5         1          17s
hpa-demo   Deployment/cpu-load-generator   117%/50%   1         5         2          31s
hpa-demo   Deployment/cpu-load-generator   115%/50%   1         5         2          46s
hpa-demo   Deployment/cpu-load-generator   116%/50%   1         5         3          61s
hpa-demo   Deployment/cpu-load-generator   113%/50%   1         5         3          76s
hpa-demo   Deployment/cpu-load-generator   115%/50%   1         5         4          92s
hpa-demo   Deployment/cpu-load-generator   118%/50%   1         5         4          107s
hpa-demo   Deployment/cpu-load-generator   112%/50%   1         5         5          2m2s

それでは逆にスケールインの動作確認をしてみます。
以下コマンドでPodが5つ起動していることを確認します。

kubectl get hpa hpa-demo; kubectl get pods -l app=cpu-load-generator
NAME       REFERENCE                       TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/cpu-load-generator   113%/50%   1         5         5          23m
NAME                                  READY   STATUS    RESTARTS   AGE
cpu-load-generator-6897fdd78f-2mkr5   1/1     Running   0          23m
cpu-load-generator-6897fdd78f-78scs   1/1     Running   0          22m
cpu-load-generator-6897fdd78f-nbv7d   1/1     Running   0          22m
cpu-load-generator-6897fdd78f-qpjxq   1/1     Running   0          70m
cpu-load-generator-6897fdd78f-qslsj   1/1     Running   0          21m

以下コマンドでdeploymentの負荷設定を編集します。

kubectl edit deployment cpu-load-generator

以下の-argsの値を変更します。

# 変更前
    spec:
      containers:
      - args:
        - while true; do echo 'Generating CPU load...'; timeout 0.5 sha256sum /dev/zero;

sleep 5で5秒間プロセスが完全停止するループを実行するため、CPU使用率を極小にします。

# 変更後
    spec:
      containers:
      - args:
        - while true; do echo 'Low CPU load'; sleep 5; done

以下コマンドでスケールインする遷移を確認してみましょう。

kubectl get hpa hpa-demo -w
NAME       REFERENCE                       TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/cpu-load-generator   114%/50%   1         5         5          32m
hpa-demo   Deployment/cpu-load-generator   114%/50%   1         5         5          32m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         5          33m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         4          33m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         4          33m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         3          33m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         3          34m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         2          34m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         2          34m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         1          34m

最初のスケールインでは1分待機後にPodを削除する動きをする想定ですが、
CPU使用率が32m時点ではまだ114%でそこから1分後の33mに1%まで負荷が低下し、Pod数が5 -> 4に減少しているがわかります。

NAME       REFERENCE                       TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
hpa-demo   Deployment/cpu-load-generator   114%/50%   1         5         5          32m
hpa-demo   Deployment/cpu-load-generator   114%/50%   1         5         5          32m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         5          33m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         4          33m

以降m表記で少しわかりづらいですが、1分経過せずにPodが1つずつ減少していっているのがわかります。

hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         4          33m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         4          33m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         3          33m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         3          34m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         2          34m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         2          34m
hpa-demo   Deployment/cpu-load-generator   1%/50%     1         5         1          34m

マニフェストの想定通りに検証ができましたので最後に後片付けをします。
以下コマンドでHPAとDeploymentを削除します。

kubectl delete hpa hpa-demo
horizontalpodautoscaler.autoscaling "hpa-demo" deleted

kubectl delete deployment cpu-load-generator
deployment.apps "cpu-load-generator" deleted

# 削除されていることの確認
kubectl get hpa,deploy -l app=cpu-load-generator
No resources found in default namespace.

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?