この記事ではKubernetesのオートスケールの機能の一つであるVerticalPodAutoScalerについてまとめていきます。
VerticalPodAutoScaler
VerticalPodAutoScaler(VPA)は、ユーザーがPod内のコンテナに対するリソース要求を設定する必要性をなくします。設定すると、使用状況に基づいて要求が自動的に設定されるため、適切なリソース量が各Podで使用できるように、ノードへの適切なスケジューリングが可能になります。
VerticalPodAutoScalerの動作例
まずはREADMEにある内容に従ってインストールして動作を見てみましょう。
READMEによると1.9以上のクラスタを用意すると良いようです。今回はminikubeで1.10.0のクラスタを用意しました。
インストール手順に従ってインストールします
$ git clone git@github.com:kubernetes/autoscaler.git
$ cd autoscaler/vertical-pod-autoscaler
$ ./hack/vpa-up.sh
customresourcedefinition.apiextensions.k8s.io "verticalpodautoscalers.poc.autoscaling.k8s.io" created
customresourcedefinition.apiextensions.k8s.io "verticalpodautoscalercheckpoints.poc.autoscaling.k8s.io" created
clusterrole.rbac.authorization.k8s.io "system:metrics-reader" created
clusterrole.rbac.authorization.k8s.io "system:vpa-actor" created
clusterrole.rbac.authorization.k8s.io "system:vpa-checkpoint-actor" created
clusterrole.rbac.authorization.k8s.io "system:evictioner" created
clusterrolebinding.rbac.authorization.k8s.io "system:metrics-reader" created
clusterrolebinding.rbac.authorization.k8s.io "system:vpa-actor" created
clusterrolebinding.rbac.authorization.k8s.io "system:vpa-checkpoint-actor" created
clusterrolebinding.rbac.authorization.k8s.io "system:replicasets-reader" created
serviceaccount "vpa-admission-controller" created
clusterrole.rbac.authorization.k8s.io "system:admission-controller" created
clusterrolebinding.rbac.authorization.k8s.io "system:admission-controller" created
serviceaccount "vpa-updater" created
deployment.extensions "vpa-updater" created
serviceaccount "vpa-recommender" created
deployment.extensions "vpa-recommender" created
Generating certs for the VPA Admission Controller in /tmp/vpa-certs.
Generating RSA private key, 2048 bit long modulus
.....+++
............................................................................................................+++
e is 65537 (0x010001)
Generating RSA private key, 2048 bit long modulus
.......................................................................................................+++
.......................+++
e is 65537 (0x010001)
Signature ok
subject=CN = vpa-webhook.kube-system.svc
Getting CA Private Key
Uploading certs to the cluster.
secret "vpa-tls-certs" created
Deleting /tmp/vpa-certs.
deployment.extensions "vpa-admission-controller" created
service "vpa-webhook" created
インストールは以上で完了です。とても簡単にできますね!
それではサンプルのアプリケーションと設定があるのでそれを投入して試します。
$ cat examples/hamster.yaml
# This config creates a deployment with two pods, each requesting 100 millicores
# and trying to utilize slightly above 500 millicores (repeatedly using CPU for
# 0.5s and sleeping 0.5s).
# It also creates a corresponding Vertical Pod Autoscaler that adjusts the requests.
# Note that the update mode is left unset, so it defaults to "Auto" mode.
apiVersion: "poc.autoscaling.k8s.io/v1alpha1"
kind: VerticalPodAutoscaler
metadata:
name: hamster-vpa
spec:
selector:
matchLabels:
app: hamster
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hamster
namespace: default
spec:
replicas: 2
template:
metadata:
labels:
app: hamster
spec:
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"]
$ kubectl apply -f examples/hamster.yaml
verticalpodautoscaler.poc.autoscaling.k8s.io "hamster-vpa" created
deployment.extensions "hamster" created
サンプルの設定とアプリケーションをデプロイしてしばらく待ちます。しばらくするとVPAオブジェクトのStatusにRecomendationのリソース設定が追加されます。
$ kubectl describe vpa
Name: hamster-vpa
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"poc.autoscaling.k8s.io/v1alpha1","kind":"VerticalPodAutoscaler","metadata":{"annotations":{},"name":"hamster-vpa","namespace":"default"}...
API Version: poc.autoscaling.k8s.io/v1alpha1
Kind: VerticalPodAutoscaler
Metadata:
Cluster Name:
Creation Timestamp: 2018-05-23T05:23:03Z
Generation: 1
Resource Version: 7270
Self Link: /apis/poc.autoscaling.k8s.io/v1alpha1/namespaces/default/verticalpodautoscalers/hamster-vpa
UID: 5de52ff8-5e49-11e8-b4d6-0800271d2683
Spec:
Selector:
Match Labels:
App: hamster
Update Policy:
Update Mode: Auto
Status:
Conditions:
Last Transition Time: 2018-05-23T05:23:28Z
Status: True
Type: Configured
Last Transition Time: 2018-05-23T05:23:28Z
Status: True
Type: RecommendationProvided
Last Update Time: 2018-05-23T05:26:29Z
Recommendation:
Container Recommendations:
Max Recommended:
Cpu: 1135508m
Memory: 460504404800
Min Recommended:
Cpu: 132m
Memory: 53677237
Name: hamster
Target:
Cpu: 788m
Memory: 319572800
Events: <none>
アプリケーションのPodをみると作り変えられていて以下の設定が追加されていました。
resources:
limits:
memory: "424430400"
requests:
cpu: 788m
memory: "319572800"
そしてしばらくすると2つ立ち上がっていたPodの片方がPendingになりました。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
hamster-b445b55f7-9wd76 1/1 Running 0 8m
hamster-b445b55f7-j2874 0/1 Pending 0 7m
理由を見てみると 0/1 nodes are available: 1 Insufficient cpu, 1 Insufficient memory.
とのことで要求するリソースが増えたためminikubeのVMのリソースが足りないようです。実際にこれが本番で発生するとサービスダウンに繋がりかねないので注意が必要そうです。
VerticalPodAutoScalerの仕組み
アーキテクチャの図はこちらにあります。この図にもありますが、VerticalPodAutoScalerはつぎの3つのコントローラと一つのCRDリソースによって実現されているようです。
- コントローラ
- VPA admission controller
- VPA recommmender
- VPA updater
- CRD
- VerticalPodAutoScaler
簡単に動きを説明するとVerticalPodAutoScalerオブジェクトにVPAの設定を記載して、それをもとにrecommenderがmetrics-serverからメトリクスを収集して推奨のリソース設定を算出します。その算出したリソース設定をadmission controllerがPod作成時に設定するという流れのようです。updaterは現在は更新が必要なPodを探し、それを削除(evict)することでReplicaSet controllerにPodを再作成させることによって実現しているようです。ただこの方法は一時的にレプリカ数が減ることや再起動を必要とすること、ReplicaSet Controllerに依存してしまうことから将来的にはリソース設定の部分だけを置き換える(in-place updates)の方式に変更を考えているようです。
推奨のリソースの算出方法はRequestに記載された使用量を超過する時間が一定割合以下(例えば1%)を保つように算出するようです。
VerticalPodAutoScalerの開発状況
VerticalPodAutoScalerは現在(2018/5/22)はalpha stateです。https://github.com/kubernetes/features/issues/21 でトラックされていますがbetaの予定などもまだ決まっていないようです。