はじめに
こんにちは。ACS事業部)土居です。
本記事はエーピーコミュニケーションズ Advent Calender 2022 17日目の記事になります。
2022年10月2日のAKS ReleaseにてVertical Pod Autoscaler(以降VPAと呼ぶ)がプレビュー扱いになりました。 丁度Microsoft IgniteやKubeCon + CloudNativeCon North America 2022 の開催が近かった事もあり、この時期周辺ではAKSに多くのアップデートがありましたが、個人的に待ち望んでいた機能の一つです。
Vertical Pod Autoscalerとは?
Vertical Pod AutoscalerはPodの垂直方向の自動スケーリングを行う機能です。
これだけだとちょっと分かりづらいので、AKSでの主なスケーリングに関する機能とその位置づけを見ながら比較していきます。
スケーリングに関する機能 | 説明 |
---|---|
Horizontal Pod Autoscaler(HPA) | Podの水平方向の自動スケーリングを行います。HPAはDeployment のreplicas を増減することでスケーリングを実現します。 |
KEDA(プレビュー) | KEDAもPodの水平方向の自動スケーリング機能です。内部的にKEDAはHPAと連携して動作します。KEDAの特徴として、イベント駆動型のスケーリングを実現できる点です。HPAではCPU ,Memory など主にk8sのmetricsを監視したスケーリングを実現します。KEDAは、Azure Service Bus やAzure Storage キュー のキューの長さ, Azure Event Hubs のイベント数など外部サービスを監視したスケーリングが実現できます。KEDAに関しては、弊社のブログでも紹介しているので気になる方は御覧ください。 |
Vertical Pod Autoscaler(VPA)(プレビュー) | Podの垂直方向の自動スケーリングを行います。VPAはPod のrequest を増減することでPodが利用するリソースを調整することが可能です。HPA、KEDAと異なりPodの数を増やしてスケーリングするわけではありません。 |
Cluster Autoscaler | Cluster AutoscalerはAKS Workerノードの水平方向の自動スケーリングを行います。AKSのWorkerノードの実態はVirtual Machine Scale Setsなので、VMSSのスケーリングと内部的にはリンクしています。 |
AKSでは、HPA、Cluster Autoscalerを使ったスケーリングの設定を行うことが今まで多かったのですが、今後の選択の幅が広がったと感じています。
一方で、VPAはHPA(KEDA)と組み合わせる事は複雑かつ動作安定性に欠けるため推奨されていなかったりと使い方が難しいとも思います。
Vertical Pod Autoscaler should not be used with the Horizontal Pod Autoscaler (HPA) on CPU or memory at this moment. However, you can use VPA with HPA on custom and external metrics.
以降、AKSでVPAを動かしてみながら利用できそうなシーンを考えてみます。
AKSにVPAを導入する
公式のドキュメントに細かな手順がありますので、こちらを参考に行っていきます。
まずはAKSクラスターを作成していきます。本記事執筆時点(2022.12.17)ではAKSの既定のKubernetes Versionは1.23系になっています。VPAは1.24以上で導入可能なので注意しましょう。
az aks create --resource-group doi-test --name doi-test --node-count 1 --node-vm-size Standard_B2ms --kubernetes-version 1.24
VPAの機能はプレビュー扱いのため、aks-vpapreview プレビュー機能をインストールしましょう。
az feature register --namespace Microsoft.ContainerService --name AKS-VPAPreview
作成したAKSクラスターに対してVPAの機能を有効化します。
az aks update --resource-group doi-test --name doi-test --enable-vpa
VPA有効化の前後で、kubectl get pod
を使った比較を行いました。vpa-admission-controller
, vpa-recommender
, vpa-updater
の3つのコンポーネントがそれぞれ追加されている事が確認できます。
# VPA有効化前のkubectl get podの出力 k_doi@Azure:~$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system azure-ip-masq-agent-tvsqg 1/1 Running 0 2m14s kube-system cloud-node-manager-zhjhc 1/1 Running 0 2m14s kube-system coredns-59b6bf8b4f-6qclw 1/1 Running 0 79s kube-system coredns-59b6bf8b4f-qfd66 1/1 Running 0 2m33s kube-system coredns-autoscaler-5655d66f64-gvp9c 1/1 Running 0 2m33s kube-system csi-azuredisk-node-xpf9l 3/3 Running 0 2m14s kube-system csi-azurefile-node-hg9ps 3/3 Running 0 2m14s kube-system konnectivity-agent-595665fdfb-nbpcc 1/1 Running 0 2m33s kube-system konnectivity-agent-595665fdfb-rx7t2 1/1 Running 0 2m33s kube-system kube-proxy-fdk4l 1/1 Running 0 2m14s kube-system metrics-server-58df99c858-gwfh4 2/2 Terminating 0 2m32s kube-system metrics-server-7dd74d8758-h866j 2/2 Running 0 73s kube-system metrics-server-7dd74d8758-nztvj 2/2 Running 0 73s
# VPA有効化後のkubectl get podの出力 k_doi@Azure:~$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system azure-ip-masq-agent-tvsqg 1/1 Running 0 5m23s kube-system cloud-node-manager-zhjhc 1/1 Running 0 5m23s kube-system coredns-59b6bf8b4f-6qclw 1/1 Running 0 4m28s kube-system coredns-59b6bf8b4f-qfd66 1/1 Running 0 5m42s kube-system coredns-autoscaler-5655d66f64-gvp9c 1/1 Running 0 5m42s kube-system csi-azuredisk-node-xpf9l 3/3 Running 0 5m23s kube-system csi-azurefile-node-hg9ps 3/3 Running 0 5m23s kube-system konnectivity-agent-595665fdfb-nbpcc 1/1 Running 0 5m42s kube-system konnectivity-agent-595665fdfb-rx7t2 1/1 Running 0 5m42s kube-system kube-proxy-fdk4l 1/1 Running 0 5m23s kube-system metrics-server-7dd74d8758-h866j 2/2 Running 0 4m22s kube-system metrics-server-7dd74d8758-nztvj 2/2 Running 0 4m22s kube-system vpa-admission-controller-b4f5d975d-2x2pn 1/1 Running 0 84s kube-system vpa-recommender-5fd94767fb-l6z6f 1/1 Running 0 84s kube-system vpa-updater-56f9bfc96f-fr5vx 1/1 Running 0 84s
VPAは以下の3つのコンポーネントから構成されています。
コンポーネント | 説明 |
---|---|
Recommender | metrics serverからPodのメトリクスを取得し、Resource Requestの推奨値を計算する |
Updater | VPAの定義に従い、推奨値から外れたResource Requestを持ったPodを削除する |
Admission Controller | Resource Requestの値を書き換え、Podを再作成する |
kubernetes/autoscaler GitHub リポジトリから Vertical Pod Autoscaler の例のマニフェストを利用します。 まずは、Deployment
部分だけApplyしてみます。
kubectl apply -f deployment_vpa.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: hamster spec: selector: matchLabels: app: hamster replicas: 2 template: metadata: labels: app: hamster spec: securityContext: runAsNonRoot: true runAsUser: 65534 # nobody containers: - name: hamster image: k8s.gcr.io/ubuntu-slim:0.1 resources: requests: cpu: 100m memory: 50Mi command: ["/bin/sh"] args: - "-c" - "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done"
このDeployment
はresource.requests
でCPU 100 millicores , Memory 50 Mi のリソースを予約しています。kubectl describe node
からも確認できます。
一方で、実際の使用リソースは設定されているresource.requests
とはかけ離れており、CPU 450 millicores前後、Memory 1 Mi となっています。
k_doi@Azure:~$ kubectl describe node Name: aks-nodepool1-26322312-vmss000002 Roles: agent ︙ ︙ Non-terminated Pods: (16 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age --------- ---- ------------ ---------- --------------- ------------- --- default hamster-78f9dcdd4c-44d8d 100m (5%) 0 (0%) 50Mi (0%) 0 (0%) 16m default hamster-78f9dcdd4c-9th2v 100m (5%) 0 (0%) 50Mi (0%) 0 (0%) 16m ︙ ︙ Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 1170m (61%) 10990m (578%) memory 1480Mi (27%) 8818Mi (164%)
k_doi@Azure:~$ kubectl top pod NAME CPU(cores) MEMORY(bytes) hamster-78f9dcdd4c-44d8d 455m 1Mi hamster-78f9dcdd4c-9th2v 457m 1Mi
次に、kubernetes/autoscaler GitHub リポジトリから Vertical Pod Autoscaler の例のマニフェストからVPA部分をApplyしてみます。spec.resourcePolicy.containerPolicies[].resources.minAllowed
とspec.resourcePolicy.containerPolicies[].resources.maxAllowed
でVPAで割り当て可能なリソースの下限上限を設定が可能です。
また、spec.updatePolicy.updateMode
を指定することで、VPAによるPod再作成等の動作を変更することができます。今回は指定していないため、Auto
が適用されます。詳細は下記を参照下さい。
updateMode | 説明 |
---|---|
Auto | Pod の作成時にリソース要求を割り当て、優先更新メカニズムを使用して既存の Pod でそれらを更新します。 |
Recreate | Autoとほぼ同様 |
Initial | ポッドの作成時にのみリソース リクエストを割り当てる |
Off | ポッドのリソース要件を自動的に変更しません。推奨事項のみ計算されます |
k_doi@Azure:~$ kubectl apply -f vpa.yaml
apiVersion: "autoscaling.k8s.io/v1" kind: VerticalPodAutoscaler metadata: name: hamster-vpa spec: # recommenders field can be unset when using the default recommender. # When using an alternative recommender, the alternative recommender's name # can be specified as the following in a list. # recommenders: # - name: 'alternative' targetRef: apiVersion: "apps/v1" kind: Deployment name: hamster resourcePolicy: containerPolicies: - containerName: '*' minAllowed: cpu: 100m memory: 50Mi maxAllowed: cpu: 1 memory: 500Mi controlledResources: ["cpu", "memory"]
しばらくすると、Podが再作成されます。再作成されたPodのresource.requests
を確認すると、VPAにより適切な値で修正されていることがわかります。
k_doi@Azure:~$ kubectl describe pod hamster-78f9dcdd4c-grtll Name: hamster-78f9dcdd4c-grtll Namespace: default ︙ State: Running Started: Sat, 17 Dec 2022 07:21:17 +0000 Ready: True Restart Count: 0 Requests: cpu: 548m memory: 262144k Environment: <none>
VPAのマニフェストがどのような推奨値を計算しているか、kubectl describe vpa
でStatus.Recommendation.Container Recommendations
の確認ができます。
Target
がVPAが計算したrequestsの推奨値で実際にrequestsとして置き換えられる値でもあります。(若干値が異なるのは筆者のコマンド実行タイミングの問題なので気にしないで下さい。)
Uncapped Target
がspec.resourcePolicy.containerPolicies[].resources.maxAllowed
で設定したリソース上限を無視した状態でVPAが計算したrequestsの推奨値になります。
k_doi@Azure:~$ kubectl describe vpa hamster-vpa ︙ ︙ Spec: Resource Policy: Container Policies: Container Name: * Controlled Resources: cpu memory Max Allowed: Cpu: 1 Memory: 500Mi Min Allowed: Cpu: 100m Memory: 1Mi Target Ref: API Version: apps/v1 Kind: Deployment Name: hamster Update Policy: Update Mode: Auto Status: Conditions: Last Transition Time: 2022-12-17T07:20:16Z Status: True Type: RecommendationProvided Recommendation: Container Recommendations: Container Name: hamster Lower Bound: Cpu: 503m Memory: 262144k Target: Cpu: 587m Memory: 262144k Uncapped Target: Cpu: 587m Memory: 262144k Upper Bound: Cpu: 1 Memory: 500Mi Events: <none>
以下の理由から、個人的にはVPAはupdateMode
をOff
にして、計算された推奨値を確認するために利用するのが現状は適していると考えています。
Podのrequestsが変更されることにより、他のPodのスケールにも影響を及ぼす可能性がある。
Deploymentのマニフェストのrequestの定義と実態が異なる可能性がある。
Podのrequestsの適正な値を見つけることは難しい(モニタリングツールとにらめっこすることが多々ある)
おわりに
いかがだったでしょうか?AKSでのVPA利用はまだプレビュー段階ですが、正式なリリースが出るのが楽しみですね。
私達ACS事業部はAzure・AKSを活用した内製化のご支援をしております。ご相談等ありましたらぜひご連絡ください。
また、一緒に働いていただける仲間も募集中です!
切磋琢磨しながらスキルを向上できる、エンジニアには良い環境だと思います。ご興味を持っていただけたら嬉しく思います。