1. TOP
  2. BLOG
  3. TECH ARTICLE:連載 第7回
    メトリクスサーバとHPAの
    Podオートスケール
TECH ARTICLE

2024年06月24日

連載 第7回
メトリクスサーバとHPAの
Podオートスケール

今回はポッドオートスケールを確認します。実習を通して、詳細設定の確認、実運用の環境に適用時には何を考慮すべきかを確認します。

オートスケール(Autoscaling)は、システムの負荷または需要に応じて自動的にリソースを拡張または縮小し、アプリケーションの性能とサービスの可用性を維持する機能です。これはクラウド環境で主に使用され、自動的にアプリケーション及びインフラストラクチャーの拡張を管理します。

クバネティスはポッドとノードのオートスケールが可能です。ポッドは主にHPA(Horizontal Pod Autoscaler)を利用し、自動でポッドの数を水平(Horizontal)に増加させたり、減少させたりします。ノードはClusterAutoscalerとKarpenterを利用してポッドが実行されるノードの数を変更できます。

主な内容:

  • オートスケールの理解
  • メトリクスサーバを利用したノードとポッドのリソース使用量のモニタリング

実習課題:

  • メトリクスサーバのインストール
  • ポッドオーケストレーション(HPA)の実習

今回の実習で使用するソースファイルのGitHubディレクトリは次の通りです。

1. オートスケールの主な構成要素

オートスケールを設定するための主な構成要素を確認します。

  • モニタリング:オートスケールはシステムの負荷を基準にリソースの数を増減させるため、システムの負荷を測定するためのモニタリングが必要です。主にCPU使用量、メモリ使用量、ネットワークトラフィックなどのメトリクスを収集してシステムの状態を把握します。
  • 調整基準の設定:ユーザはオートスケールのための調整の基準を設定します。例えば、CPU使用量が設定した閾値を超過するとリソースを拡張し、閾値から下がるとリソースを縮小することに応じた閾値の基準を設定します。閾値に対する反応時間も調整できます。例えば、CPU使用量が減少し、再度増加するような変化が頻繁に発生する場合に、これに対応する頻繫な変動を防止するためにスケールダウンの安定化時間を5分などと指定できます。
  • スケーリングポリシー:オートスケールは多様なスケーリングポリシーをサポートします。主に垂直スケーリング(Vertical Scaling)と水平スケーリング(Horizontal Scaling)があります。垂直スケーリングはインスタンスのリソースサイズを変更してリソースを調節(例:cpu request 0.5 core to 1 Coreなど)し、水平スケーリングはインスタンスの数を調節してアプリケーションの負荷に合わせて増加や縮小をします。

オートスケールは以上のような要素を利用してシステムの負荷の変動に自動的に対応して、リソースを効率的に使用し、アプリケーションの性能と可用性を維持します。これによりユーザは手動でリソースを管理したり、予測された負荷に対して準備したりする必要が無く、自動的にシステムを調整して効率的な運用ができます。

クラウド環境では自動化されたオートスケールが特に有用で、クラウドベンダーが提供するオートスケール機能を使用できます。しかし、オンプレミス環境では増加するポッドを受入れ可能なノードの数が限定されるため、オートスケールの使用に制約があります。

2. メトリクスサーバを利用したリソース使用量の確認

オートスケールを適用するには、先ず、システムのリソースの使用量を把握する必要があります。クバネティス環境でポッドとノードのCPUとメモリの使用量を確認するにはメトリクスサーバが必要です。インストールはArgoCDとhelmを使用します。Helmでアプリケーションをインストールする方法は第8回で確認します。今回は簡単に実行コマンドだけを記述します。

1.	$ (⎈ |switch-singapore-test:monitoring) helm repo add metrics-server 
2.	$ (⎈ |switch-singapore-test:monitoring) helm pull metrics-server/metrics-server --version 3.10.0
3.	$ (⎈ |switch-singapore-test:monitoring) tar xvfz metrics-server-3.10.0.tgz 
4.	$ (⎈ |switch-singapore-test:monitoring) rm -rf metrics-server-3.10.0.tgz 
5.	$ (⎈ |switch-singapore-test:monitoring) mv metrics-server metrics-server-3.10.0
6.	$ (⎈ |switch-singapore-test:monitoring) cd metrics-server-3.10.0
7.	$ (⎈ |switch-singapore-test:monitoring) mkdir ci
8.	$ (⎈ |switch-singapore-test:monitoring) cp values.yaml ci/

helm Valueファイルを下記のように変更します。

ci/values.yaml

1.	apiService:
2.	insecureSkipTLSVerify: true

ArgoCDを利用して配布するためにArgoCD アプリケーションファイルを準備します。下記のようにargo-cd-app-of-appsディレクトリに移動します。

1.	$ (⎈ |switch-seoul-stage:kubecost) cd ../argo-cd-app-of-apps 

メトリクスサーバ用のArgoCD Application CRDファイルを生成します。

templates/metrics-server-applications.yaml

1.	apiVersion: argoproj.io/v1alpha1
2.	kind: Application
3.	metadata:
4.	    name: metrics-server
5.	    namespace: argocd
6.	    finalizers:
7.	    - resources-finalizer.argocd.argoproj.io
8.	spec:
9.	    destination:
10.	        namespace: kube-system
11.	        server: {{ .Values.spec.destination.server }}
12.	    project: default
13.	    source:
14.	        path: metrics-server-3.10.0
15.	        helm:
16.	            valueFiles:
17.	            - ci/values.yaml
18.	    repoURL: {{ .Values.spec.source.repoURL }}
19.	    targetRevision: {{ .Values.spec.source.targetRevision }}

ArgoCDのApps Applicationは下記のように ‘templates’ ディレクトリのアプリケーションファイルを自動的に認識できるようにsyncPolicy/automatedオプションが設定されています。

apps-applications.yaml

1.	syncPolicy:
2.	    automated:
3.	        prune: true
4.	        selfHeal: true

ArgoCD GUIで確認すると下記のように ‘metrics-server’ リソースを確認できます。

画面上のメニューの ‘SYNC’ をクリックするとリソースが配布されます。

kube-systemネームスペースを確認すると下記のようにmetrics-serverポッドが実行されます。

1.	$ (⎈ |switch-singapore-test:kube-system) k get pod metrics-server-6f9cdd486c-2fqm2 
2.	NAME READY STATUS RESTARTS AGE
3.	metrics-server-6f9cdd486c-2fqm2 0/1 Running 0 24s

メトリクスサーバは各ノードに配布されたkubeletと cAdvisorを利用して全体ノードとポッドのリソース使用量を収集しますが、APIサーバでそのリソース使用量を照会できます。コマンドは ‘k top’ を使用します。

ノード使用量の照会は次の通りです。

1.	$ (⎈ |switch-singapore-test:kube-system) k top nodes
2.	NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% 
3.	ip-10-110-24-222.ap-southeast-1.compute.internal 171m 8% 2256Mi 31% 
4.	ip-10-110-47-109.ap-southeast-1.compute.internal 88m 4% 907Mi 12% 

ポッド使用量の照会は次の通りです。

1.	$ (⎈ |switch-singapore-test:kube-system) k top pods
2.	NAME CPU(cores) MEMORY(bytes) 
3.	aws-load-balancer-controller-7d96db6884-nrcgf 2m 24Mi 
4.	aws-node-84wfr 3m 41Mi
5.	(省略)

以上でメトリクスサーバのインストールが完了しました。

3. HPA(Horizontal Pod Autoscaler)の実習

HPAはアプリケーションの負荷が増加してリソース使用量が変化すると、自動的にポッドの数を調整します。前述でインストールしたメトリクスサーバが収集したCPUとメモリ使用量を確認し、閾値を超過又は下回ると自動的にポッドの数を増減させます。

詳細な使用法を例で確認します。先ず、テストで使用するポッドを配布します。

php-apachedeploy.yaml

1.	apiVersion: apps/v1
2.	kind: Deployment
3.	metadata:
4.	    name: php-apache
5.	spec:
6.	    selector:
7.	        matchLabels:
8.	            run: php-apache
9.	    replicas: 1
10.	    template:
11.	        metadata:
12.	            labels:
13.	                run: php-apache
14.	        spec:
15.	            containers:
16.	            - name: php-apache
17.	                image: registry.k8s.io/hpa-example
18.	                ports:
19.	                - containerPort: 80
20.	                resources:
21.	                    limits:
22.	                        cpu: 500m
23.	                    requests:
24.	                        cpu: 200m
25.	---
26.	apiVersion: v1
27.	kind: Service
28.	metadata:
29.	    name: php-apache
30.	    labels:
31.	        run: php-apache
32.	spec:
33.	    ports:
34.	    - port: 80
35.	    selector:
36.	        run: php-apache

. spec.template.spec.containers.resources.requests.cpu: 200m
ポッドが実行するノードにリクエスト(request)可能なCPU Coreを入力します。単位は1,000m = 1 Coreでv200mは0.2 vCoreを意味します。

上記の例はクバネティス公式ホームページに記載されています。外部接続で負荷が増加するPHP Apacheサンプルアプリケーションです。先ず、リソースを生成します。

1.	$ (⎈ |switch-singapore-test:default) k apply -f php-apache.yaml 
2.	deployment.apps/php-apache created
3.	service/php-apache created
4.	
5.	$ (⎈ |switch-singapore-test:default) k get deploy,svc
6.	NAME READY UP-TO-DATE AVAILABLE AGE
7.	deployment.apps/php-apache 1/1 1 1 40s
8.	
9.	NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
10.	service/kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 59d
11.	service/php-apache ClusterIP 172.20.92.196 <none> 80/TCP 39s

php-apache デプロイメントとサービスが正常にインストールされました。

次に、HPAリソースを生成します。HPAもクバネティスリソースで、YAMLファイルで作成できます。

php-hpa.yaml

1.	apiVersion: autoscaling/v2
2.	kind: HorizontalPodAutoscaler
3.	metadata:
4.	    name: php-apache
5.	    namespace: default
6.	spec:
7.	    maxReplicas: 10
8.	    metrics:
9.	    - resource:
10.	        name: cpu
11.	        target:
12.	            averageUtilization: 50
13.	            type: Utilization
14.	        type: Resource
15.	minReplicas: 1
16.	scaleTargetRef:
17.	    apiVersion: apps/v1
18.	    kind: Deployment
19.	    name: php-apache

. spec.maxReplicas
増加するポッドの最大数を指定します。

. spec.metrics.resource.name: cpu
ポッドの数が増加する基準となるメトリクスを入力します。CPU、メモリなどを入力できます。

. spec.metrics.resource.target.averageUtilization: 50
averageUtilization(平均使用量)の基準をパーセンテージで閾値を指定しました。基準になる数値はポッドに指定したResource Requestです。今回の例は Requestに 200m(0.2Core)を指定してaverageUtilizationに50を指定しました。100m(50%)以上を使用するとポッドが増加します。注意事項はResourceのLimitではなくRequestです。対象となる全てのポッドの平均使用量を基準に使用量を測定します。

. spec.metrics.type: Resource
リソース使用量を基準にメトリクスを指定します。 Resource以外のCustomメトリクスを使用すると、セッション数、遅延時間などの多様なメトリクスを追加できます。

. spec.scaleTargetRef.kind: Deployment
HPAが実行対象のリソースを指定します。今回の例ではphp-apacheという名称の Deploymentリソースです。

. spec.scaleTargetRef.name: php-apache
デプロイメント中のphp-apacheという名称のリソースをHPA Targetに指定します。

php-apache HPAリソースを配布します。

1.	$ (⎈ |switch-singapore-test:default) k apply -f php-hpa.yaml 
2.	horizontalpodautoscaler.autoscaling/php-apache created

HPAリソースを確認できます。

1.	$ (⎈ |switch-singapore-test:default) k get hpa
2.	NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
3.	php-apache Deployment/php-apache 0%/50% 1 10 1 64s

. TARGETS
CPU使用量のTargetが50%で、現在は0%で使用量がありません。

. MINPODS、MAXPODS、REPLICAS
値はそれぞれ1、10、1で、現在はphp-apache ポッドのReplica数が1つでCPU使用量がTargetより小さいためMINPODS数は同じです。

それでは、負荷を発生させてphp-apacheポッドのリソース使用量を増加させます。下記のスクリプトはbusyboxイメージを実行して ‘0.01’ 秒間隔で前に実行したphpポッドに接続する例です。

1.	$ (⎈ |switch-singapore-test:default) kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
2.	
3.	If you don't see a command prompt, try pressing enter.
4.	OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!

また、ウィンドウを開いてHPAの変化を確認します。

1.	$ (⎈ |switch-singapore-test:kube-system) k get hpa -w
2.	NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
3.	php-apache Deployment/php-apache 133%/50% 1 10 1 4m53s
4.	php-apache Deployment/php-apache 239%/50% 1 10 3 5m
5.	php-apache Deployment/php-apache 128%/50% 1 10 5 5m15s
6.	php-apache Deployment/php-apache 53%/50% 1 10 5 5m30s

-w(watch)オプションを使用するとリアルタイムで変化を確認できます。負荷が発生して、 ‘TARGETS’ が133%から239%に増加します。これによりポッドの数(REPLICAS)も同じく1 -> 3 -> 5と増加します。

1.	$ (⎈ |switch-singapore-test:default) k get pod
2.	NAME READY STATUS RESTARTS AGE
3.	load-generator 1/1 Running 0 3m44s
4.	php-apache-7495ff8f5b-66zzq 1/1 Running 0 113s
5.	php-apache-7495ff8f5b-d4fdp 1/1 Running 0 3m23s
6.	php-apache-7495ff8f5b-kghnk 1/1 Running 0 3m8s
7.	php-apache-7495ff8f5b-l6n86 1/1 Running 0 28m
8.	php-apache-7495ff8f5b-ldljv 1/1 Running 0 3m23s
9.	php-apache-7495ff8f5b-msx5z 1/1 Running 0 3m8s

ポッドの数を確認すると上記のように自動的に増加します。このように外部ユーザ接続が増加してリソース使用量が増加すると、クバネティスはHPA設定で自動的にポッドを増加します。アプリケーションのリソース使用量により自動的にポッドの数を調節できるため、管理者の追加の設定が必要なく自動的にトラフィックを処理できるため、非常に便利です。

参考までに基準となるメトリクスは、CPUまたはメモリのいずれか1つか、CPUとメモリの2つのメトリクスを同時に指定できます。

4. HPA適用時の考慮すべき事柄

オートスケールを実運用の環境に適用するには幾つか考慮すべき事柄があります。先ず、負荷の増加と減少が素早く繰り返すために、ポッドの数も減少と増加を素早く繰り返す現象(Flapping)を防止するため、安定化時間(stabilizationWindowSeconds)を適切に指定する必要があります。

1.	behavior:
2.	    scaleDown:
3.	        stabilizationWindowSeconds: 300
4.	        policies:
5.	        - type: Percent
6.	            value: 100
7.	            periodSeconds: 15
8.	    scaleUp:
9.	        stabilizationWindowSeconds: 0
10.	        policies:
11.	            - type: Percent
12.	                value: 100
13.	                periodSeconds: 15
14.	            - type: Pods
15.	                value: 4
16.	                periodSeconds: 15
17.	            selectPolicy: Max

. behavior.scaleDown.stabilizationWindowSeconds: 300
ポッドの減少と増加が素早く繰り返すことを防止するために安定化時間(stabilizationWindowSeconds)を指定できます。上記の例は300s(5分)を設定して5分後にポッドの数を減少させます。

. behavior.scaleDown.policies.value: 100, periodSeconds: 15
一回で減少できるポッドの数を実行中のポッドを100%に指定してMIN PODS数まで減らすようにします。15秒毎に最大100%までポッド数を減らせます。

. behavior.scaleUp.stabilizationWindowSeconds: 0
ポッド数の減少と異なりポッド数が増加時に、安定化時間を ‘0’ に設定しました。増加するトラフィックを素早く処理するために安定化時間を ‘0’ に指定する場合が多いです。

. behavior.scaleUp.policies.value: 100, periodSeconds: 15, value:4, periodSeconds: 15
前述のscaleDown 設定と同じで、15秒毎にポッド数を100% または4つのポッドまで増加できるように設定しました。

更に、実トラフィックは増加しますがオートスケール反応が遅いためトラフィックを処理できないケースが発生することがあります。新しくノードを実行するための時間(Karpenter基準は約40s程度)とポッドを実行する時間などが追加で必要です。予想トラフィックに合わせてクバネティスのノードを事前にCronjob などで増加できます。または ‘over-provisioner’ を利用して事前に空いているノードを準備する方法も可能です。

ユーザトラフィックはシステムリソース使用量に比例して増加できない場合があります。別途のユーザ定義メトリクスが必要です。ユーザ接続コネクション数を基準にポッドの数を増加できるように ‘Service Monitor’、 ‘Keda’ などを使用できます。

以上でシステム負荷により自動的にポッドの数を増減させるHPAを確認しました。

最後に、実習で使用したリソースは下記のように削除します。

1.	$ (⎈ |switch-singapore-test:default) k delete -f php-apache.yaml -f php-hpa.yaml 
2.	deployment.apps "php-apache" deleted
3.	service "php-apache" deleted
4.	horizontalpodautoscaler.autoscaling "php-apache" deleted

お気軽にお問い合わせください

製品に関する事やご不明な点など、お気軽にご相談ください。
また、ジェニファーソフトでは2週間の無償トライアルを提供しています。

詳しく知りたい方は
導入や費用のご相談は