HPA(Horizontal Pod Autoscaler) は、ポットのCPUの使用率を監視しながら、ポッドのレプリカ数を増減するものです。一方、 CA(Cluster Autoscaler) は、リソース要求に対してノードの資源が不足している状態を解消するために、ノードを追加します。
この二つの組み合わせで、ワークロードすなわち、CPU使用率に応じたノード増減について、IKS(IBM Cloud Kubernetes Service) で検証してみます。
オートスケール環境の設定
- CA環境の設定は、IKS クラスタ・オートスケーラーの検証を参照してください。
- HPAの設定は、コントローラーに対して、CPU使用率に応じてポッド数を変更する方式になりますから、デプロイメントやステートフルセットなど、コントローラーをデプロイした後に有効化します。
コンテナをデプロイして、HPAを有効化するマニフェストは、GitHubの https://github.com/takara9/container-workload/blob/master/deploy-hpa.yml においてあります。そのなかで、HPA部分を抜き出したのが以下です。 この中で、「scaleTargetRef.name」デプロイメントのオブジェクト名を記述してオートスケール対象とします。その他の項目は、読んで解ると思います。
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: workload
namespace: default
spec:
maxReplicas: 20
minReplicas: 1
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: workload
targetCPUUtilizationPercentage: 50
初期状態
マニフェストを適用した直後の状態は、ノード数が2です。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
10.74.139.152 Ready <none> 7d5h v1.12.5+IKS
10.74.139.154 Ready <none> 5d18h v1.12.5+IKS
直後では、このターミナル出力の一番したの行で、メトリックスサーバーによって、CPUの使用率が算出されていませんから、HPAは働きません。したがって、ポッド数は、マニフェストに記述された5個のままです。
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/workload-7fb9688459-jnwdv 1/1 Running 0 8s
pod/workload-7fb9688459-qr85m 1/1 Running 0 8s
pod/workload-7fb9688459-rjb6p 1/1 Running 0 8s
pod/workload-7fb9688459-rx4tf 1/1 Running 0 8s
pod/workload-7fb9688459-v689s 1/1 Running 0 8s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 172.21.0.1 <none> 443/TCP 7d5h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/workload 5 5 5 5 8s
NAME DESIRED CURRENT READY AGE
replicaset.apps/workload-7fb9688459 5 5 5 9s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/workload Deployment/workload <unknown>/50% 1 20 0 8s
ワークロード実行
HPAは、CPU使用率のターゲット 50% になるように、ポッドのレプリカ数を徐々に増やすように動作します。ここでは、無限ループのコンテナ maho/testwkldを実行していますから、一気に最大数までレプリカ数を上げることになります。
次の実行状態では、まだ、ノードが追加されていませんから、2台のノードで対応できる7つのポッドが実行している状態です。7つの理由は、IKS クラスタ・オートスケーラーの検証 に書いてあります。
このように、HPAによって、ポッド数を増やすことで、ポッド一つあたりのCPU使用率を下げるように、そして、コンテナのスペックによりリソースを占有して能力を増強するように動作します。しかし、ノードのリソースが足りなくなると、ポッドはデプロイされず、ペンディング状態となります。 ここでは、HPAは、19個のポッドが必要と判断して、7個のポッドが実行状態となりましたが、残りの12個は、ペンディング状態になっています。そのため、これからの CA が働き始めます。
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/workload-7fb9688459-6f892 0/1 Pending 0 78s
pod/workload-7fb9688459-7wdn8 0/1 Pending 0 77s
pod/workload-7fb9688459-c64p9 1/1 Running 0 93s
pod/workload-7fb9688459-d694x 0/1 Pending 0 93s
pod/workload-7fb9688459-dd4qt 0/1 Pending 0 32s
pod/workload-7fb9688459-dhgmm 0/1 Pending 0 93s
pod/workload-7fb9688459-j2v4l 0/1 Pending 0 78s
pod/workload-7fb9688459-j5mvw 0/1 Pending 0 32s
pod/workload-7fb9688459-jnwdv 1/1 Running 0 2m34s
pod/workload-7fb9688459-k25cc 0/1 Pending 0 78s
pod/workload-7fb9688459-kzx7k 0/1 Pending 0 32s
pod/workload-7fb9688459-m9pm5 1/1 Running 0 93s
pod/workload-7fb9688459-q9jgz 0/1 Pending 0 32s
pod/workload-7fb9688459-qr85m 1/1 Running 0 2m34s
pod/workload-7fb9688459-rjb6p 1/1 Running 0 2m34s
pod/workload-7fb9688459-rx4tf 1/1 Running 0 2m34s
pod/workload-7fb9688459-tw9xb 0/1 Pending 0 32s
pod/workload-7fb9688459-v689s 1/1 Running 0 2m34s
pod/workload-7fb9688459-x6t77 0/1 Pending 0 93s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 172.21.0.1 <none> 443/TCP 7d5h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/workload 19 19 19 7 2m35s
NAME DESIRED CURRENT READY AGE
replicaset.apps/workload-7fb9688459 19 19 7 2m35s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/workload Deployment/workload 131%/50% 1 20 19 2m34s
スケールアップ結果
次は、CA によるスケールアップ過程で、IaaSのコマンドを実行して、増設された仮想サーバーがプロビジョニングの進行状態を確認したものです。この動作は、データセンターによって差がありますが、新しデータセンターでは、2~3分でプロビジョニングが完了します。
$ bx ks workers iks2
ID プライベート IP 状態 状況
kube-dal12-cra95d5d38-w1 10.74.139.152 normal Ready
kube-dal12-cra95d5d38-w13 10.74.139.155 provisioning Preparing to meter worker
kube-dal12-cra95d5d38-w14 10.74.139.176 provisioning Waiting for IBM Cloud infrastructure: Setup provision configuration
kube-dal12-cra95d5d38-w15 10.74.139.158 provisioning Waiting for IBM Cloud infrastructure: Publish server data
kube-dal12-cra95d5d38-w4 10.74.139.154 normal Ready
最終的に、Kubernetesのクラスタに組み込まれ、最大値まで増強された結果が、以下です。今回の検証では無限ループのポッドを利用しましたから、最大値までスケールアップしました。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
10.74.139.152 Ready <none> 7d5h v1.12.5+IKS
10.74.139.154 Ready <none> 5d18h v1.12.5+IKS
10.74.139.155 Ready <none> 4m59s v1.12.5+IKS
10.74.139.158 Ready <none> 3m6s v1.12.5+IKS
10.74.139.176 Ready <none> 33s v1.12.5+IKS
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/workload-7fb9688459-4qdlg 1/1 Running 0 3m12s
pod/workload-7fb9688459-622dt 1/1 Running 0 5m5s
pod/workload-7fb9688459-66wmr 1/1 Running 0 3m34s
pod/workload-7fb9688459-6f892 1/1 Running 0 24m
pod/workload-7fb9688459-7wdn8 1/1 Running 0 24m
pod/workload-7fb9688459-8j92f 1/1 Running 0 5m5s
pod/workload-7fb9688459-c64p9 1/1 Running 0 25m
pod/workload-7fb9688459-j2v4l 1/1 Running 0 24m
pod/workload-7fb9688459-j5mvw 1/1 Running 0 24m
pod/workload-7fb9688459-jnwdv 1/1 Running 0 26m
pod/workload-7fb9688459-k25cc 1/1 Running 0 24m
pod/workload-7fb9688459-kzx7k 1/1 Running 0 24m
pod/workload-7fb9688459-m9pm5 1/1 Running 0 25m
pod/workload-7fb9688459-q9jgz 1/1 Running 0 24m
pod/workload-7fb9688459-qr85m 1/1 Running 0 26m
pod/workload-7fb9688459-rjb6p 1/1 Running 0 26m
pod/workload-7fb9688459-rx4tf 1/1 Running 0 26m
pod/workload-7fb9688459-tw9xb 1/1 Running 0 24m
pod/workload-7fb9688459-v689s 1/1 Running 0 26m
pod/workload-7fb9688459-x6t77 1/1 Running 0 25m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 172.21.0.1 <none> 443/TCP 7d5h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/workload 20 20 20 20 26m
NAME DESIRED CURRENT READY AGE
replicaset.apps/workload-7fb9688459 20 20 20 26m
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/workload Deployment/workload 111%/50% 1 20 20 26m
ワークロード停止とスケールダウン結果
次は、スケールダウンを確認してみます。デプロイメントを消すわけには行かないので、ポッドの仕様のコンテナを変更して、無限ループのコンテナから、Nginxに変更してワークロードを減らします。
最終的な確認の記録が、翌朝になってしまったので、この結果から時間が判らないですが、コンテナを変更後、約10分でノードのキャンセルが始めります。
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/workload-55568bc7fb-gsz8w 1/1 Running 0 11h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 172.21.0.1 <none> 443/TCP 7d17h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/workload 1 1 1 1 12h
NAME DESIRED CURRENT READY AGE
replicaset.apps/workload-55568bc7fb 1 1 1 11h
replicaset.apps/workload-7fb9688459 0 0 0 12h
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/workload Deployment/workload 0%/50% 1 20 1 12h
$ kubectl get no
NAME STATUS ROLES AGE VERSION
10.74.139.152 Ready <none> 7d17h v1.12.5+IKS
10.74.139.154 Ready <none> 6d6h v1.12.5+IKS
まとめ
これで、HPAとCAを組み合わせることで、クラウドベンダーに依存しない k8s の機能でCPU使用率ベースのオートスケールが実現できることが、確認できました。
テスト中に発見したことですが、CAを設定すると、クラウドのコンソールから自由にノード数を変更できなくなり、ConfigMapを修正してくださいとのメッセージが表示されるようになります。