Cluster Autoscaler を利用する

Prev Next

VPC環境で利用できます。

Kubernetesは、クラスタ自動スケーリングとリソース管理のために Cluster AutoscalerVertical Pod Autoscalerの2つの機能を提供します。このうち、Cluster Autoscalerを使用して、クラスタのワーカーノードを自動的に拡張または縮小できます。これにより、クラスタリソースをより柔軟かつ効率的に管理できます。

このガイドでは、Ncloud Kubernetes Serviceでの Cluster Autoscalerの機能と使用方法について説明します。

Cluster Autoscaler

Cluster Autoscalerは、Kubernetesクラスタのサイズを自動的に調整して、リソースの使用を最適化します。リソース不足によりスケジューリングできなかった Podが存在する場合、クラスタを拡張します。逆に、クラスタ内のノードの一部が継続的に低いリソース使用率を示す場合、そのノードを縮小してリソースの無駄遣いを防ぎます。このプロセスは、Podの要件とクラスタの現在のリソース状態に基づいて自動的に行われます。

Cluster Autoscalerの動作のためには、Podのリソースリクエスト(requests)と制限(limits)が定義されている必要があります。この情報は、Cluster Autoscalerがクラスタのリソース使用率を分析し、必要に応じてクラスタのサイズを調整するために必須です。リソースリクエストは、Podの起動時に必要な最小リソース量を指定し、リソース制限は、Podの使用できる最大リソース量を制限します。

Cluster Autoscaler動作の仕組み

Cluster Autoscalerはクラスタのリソース使用率を分析し、必要に応じてクラスタのサイズを調整します。このプロセスは、Podの要件とクラスタの現在のリソース状態に基づいて自動的に行われます。

  • スケールアップの条件
    • 新しく作成した Podが一定時間以上 Pendingステータスになり、現在のクラスタの最大ノード数とノードプールの maxSize制限を超えない場合、ノードが追加されます。
    • Cluster Autoscalerは Pending Podのリソースリクエスト(Requests)をベースにノードの追加有無を決定します。
  • スケールダウンの条件
    • クラスタ内のノードの一部が継続的に低いリソース使用率を示す場合、そのノードを縮小します。
    • ノードの CPU/Memoryリクエスト(Requests)の合計がノードの allocatableに比べて scale-down-utilization-threshold(デフォルト値: 0.5)未満の場合、低使用ノードとみなします。
    • 基本的に--scale-down-unneeded-time(デフォルト値: 10分)の間、他の Podがそのノードを必要としない場合、縮小候補に登録されます。
    • その後、Cluster Autoscalerは Podを他のノードに安全に移動できるか確認した後、次のノードを削除します。
    • ただし、以下のような場合、縮小対象から除外されます。
      • Controller(例: Deployment, StatefulSetなど)によって制御されない場合
      • Local Storageが設定されている場合
      • 他のノードに Podが移動できない場合
      • Annotation "cluster-autoscaler.kubernetes.io/safe-to-evict": "false"が設定されている場合

Cluster Autoscalerに関する詳細は、Cluster Autoscaler FAQで確認できます。

Cluster Autoscalerの有効化

Ncloud Kubernetes Serviceのクラスタは、基本的に Cluster Autoscaler機能が無効な状態で提供されます。ユーザーはコンソールのノードプール設定でこの機能を簡単に有効にでき、これにより自動的にクラスタのサイズを調整し、リソースの使用を最適化できます。

  1. NAVERクラウドプラットフォームコンソールの VPC環境で、 i_menu > Services > Containers > Ncloud Kubernetes Service > Clustersメニューを順にクリックします。
  2. Cluster Autoscalerを有効にしたいノードプールを選択します。
  3. 上部の [変更] ボタンをクリックします。
  4. [設定] ボタンをクリックし、最小ノード数と最大ノード数を入力します。
参考
  • クラスタのウォーカーノードの総数は、Cluster Autoscalerの最大ノード数を含めて計算されます。クラスタを運用する際には、その要素を考慮して適切な管理が必要です。
  • 初期設定時に現在のノード数が設定された最小ノード数より少ない場合でも、自動的にノード数を増加させません。必要に応じて、ノード数を手動で調整してから設定する必要があります。
  1. [変更] ボタンをクリックして、Cluster Autoscalerを有効にします。
  2. Kubectlで Cluster Autoscalerの動作を確認します。
    $ kubectl get configmap -n kube-system cluster-autoscaler-status -o yaml
    ...
    data:
    status: |
        Cluster-autoscaler status at 2024-02-20 07:04:01.141727455 +0000 UTC:
        Cluster-wide:
        Health:      Healthy (ready=5 unready=0 (resourceUnready=0) notStarted=0 longNotStarted=0 registered=5 longUnregistered=0)
                    LastProbeTime:      2024-02-20 07:04:01.121214914 +0000 UTC m=+2227353.262936722
                    LastTransitionTime: 2024-01-25 12:22:06.170599081 +0000 UTC m=+38.312320847
        ScaleUp:     NoActivity (ready=5 registered=5)
                    LastProbeTime:      2024-02-20 07:04:01.121214914 +0000 UTC m=+2227353.262936722
                    LastTransitionTime: 2024-01-25 12:22:06.170599081 +0000 UTC m=+38.312320847
        ScaleDown:   NoCandidates (candidates=0)
                    LastProbeTime:      2024-02-20 07:04:01.121214914 +0000 UTC m=+2227353.262936722
                    LastTransitionTime: 2024-01-25 12:22:06.170599081 +0000 UTC m=+38.312320847
        
        NodeGroups:
        Name:        node
        Health:      Healthy (ready=2 unready=0 (resourceUnready=0) notStarted=0 longNotStarted=0 registered=2 longUnregistered=0 cloudProviderTarget=2 (minSize=1, maxSize=8))
                    LastProbeTime:      2024-02-20 11:25:31.98194832 +0000 UTC m=+2243044.123670024
                    LastTransitionTime: 2024-02-20 11:13:49.540592255 +0000 UTC m=+2242341.682313956
        ScaleUp:     NoActivity (ready=2 cloudProviderTarget=2)
                    LastProbeTime:      2024-02-20 11:25:31.98194832 +0000 UTC m=+2243044.123670024
                    LastTransitionTime: 2024-02-20 11:25:11.920272102 +0000 UTC m=+2243024.061993805
        ScaleDown:   NoCandidates (candidates=0)
                    LastProbeTime:      2024-02-20 11:25:31.98194832 +0000 UTC m=+2243044.123670024
                    LastTransitionTime: 2024-02-20 11:25:11.920272102 +0000 UTC m=+2243024.061993805
    ...
    
参考

Cluster Autoscalerを使用する場合、以下の事項を考慮してください。

  • Cluster Autoscaler機能を開始または停止するまで、1分から5分程度かかります。
  • Cluster Autoscalerの使用中には手動でノード数を変更できません。そのため、ノード数を手動で変更するにはその機能を未設定に変更する必要があります。
  • Cluster Autoscalerは、クラスタ内でその機能を設定したノードプールのみ適用されます。

Cluster Autoscalerの例

Cluster Autoscalerと Horizontal Pod Autoscalerを使って Kubernetesクラスタで負荷テストを行います。テストを通じて、クラスタの Pod数とノード数が動的に調整される過程を確認できます。

使用されたユースケースは Horizontal Pod Autoscaler Walkthroughで詳しく確認できます。

  1. Cluster Autoscalerをテストするクラスタを準備します。

  2. Cluster Autoscalerと Metrics Serverが正常に動作しているかを確認します。

    • Cluster Autoscalerの確認
    $ kubectl get configmap -n kube-system cluster-autoscaler-status -o yaml
    ...
    data:
    status: |
        Cluster-autoscaler status at 2024-02-20 07:04:01.141727455 +0000 UTC:
        Cluster-wide:
        Health:      Healthy (ready=5 unready=0 (resourceUnready=0) notStarted=0 longNotStarted=0 registered=5 longUnregistered=0)
                    LastProbeTime:      2024-02-20 07:04:01.121214914 +0000 UTC m=+2227353.262936722
                    LastTransitionTime: 2024-01-25 12:22:06.170599081 +0000 UTC m=+38.312320847
        ScaleUp:     NoActivity (ready=5 registered=5)
                    LastProbeTime:      2024-02-20 07:04:01.121214914 +0000 UTC m=+2227353.262936722
                    LastTransitionTime: 2024-01-25 12:22:06.170599081 +0000 UTC m=+38.312320847
        ScaleDown:   NoCandidates (candidates=0)
                    LastProbeTime:      2024-02-20 07:04:01.121214914 +0000 UTC m=+2227353.262936722
                    LastTransitionTime: 2024-01-25 12:22:06.170599081 +0000 UTC m=+38.312320847
        
        NodeGroups:
        Name:        node
        Health:      Healthy (ready=2 unready=0 (resourceUnready=0) notStarted=0 longNotStarted=0 registered=2 longUnregistered=0 cloudProviderTarget=2 (minSize=1, maxSize=8))
                    LastProbeTime:      2024-02-20 11:25:31.98194832 +0000 UTC m=+2243044.123670024
                    LastTransitionTime: 2024-02-20 11:13:49.540592255 +0000 UTC m=+2242341.682313956
        ScaleUp:     NoActivity (ready=2 cloudProviderTarget=2)
                    LastProbeTime:      2024-02-20 11:25:31.98194832 +0000 UTC m=+2243044.123670024
                    LastTransitionTime: 2024-02-20 11:25:11.920272102 +0000 UTC m=+2243024.061993805
        ScaleDown:   NoCandidates (candidates=0)
                    LastProbeTime:      2024-02-20 11:25:31.98194832 +0000 UTC m=+2243044.123670024
                    LastTransitionTime: 2024-02-20 11:25:11.920272102 +0000 UTC m=+2243024.061993805
    ...
    
    • Metrics Serverの確認
    $ kubectl top pods -n kube-system
    NAME                                      CPU(cores)   MEMORY(bytes)           
    cilium-mct9p                              7m           96Mi            
    cilium-operator-846758784c-t2hpj          2m           21Mi            
    cilium-qqwdl                              6m           88Mi            
    cilium-sspl4                              6m           88Mi
    ...
    
  3. php-apache deploymentをクラスタにリリースします。

    $ kubectl apply -f https://k8s.io/examples/application/php-apache.yaml
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: php-apache
    spec:
    selector:
        matchLabels:
        run: php-apache
    replicas: 1
    template:
        metadata:
        labels:
            run: php-apache
        spec:
        containers:
        - name: php-apache
            image: registry.k8s.io/hpa-example
            ports:
            - containerPort: 80
            resources:
            limits:
                cpu: 500m
            requests:
                cpu: 200m
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: php-apache
    labels:
        run: php-apache
    spec:
    ports:
    - port: 80
    selector:
        run: php-apache
    
  4. Horizontal Pod Autoscaler(HPA)を作成して確認します。

    • HPA作成
    $ kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
    
    • HPA確認
    $ kubectl get hpa
    NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    php-apache   Deployment/php-apache   0%/50%    1         10        1          144m
    
  5. 負荷をかけ、Podの増加を確認します。

    • 別のターミナルで負荷が増加
    $ 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"
    
    • HPAの観測とレプリカ数の増加を確認
    $ kubectl get hpa
    NAME         REFERENCE               TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
    php-apache   Deployment/php-apache   106%/50%   1         10        7          154m
    
  6. 新しく作成された Podの Pendingを確認し、Cluster Autoscalerの動作を確認します。

    • Podの Pendingステータスの確認
    $ kubectl get pods -o wide | grep php-apache
    ...
    php-apache-78c9f8cbf6-4n794          0/1     Pending   0             20s
    php-apache-78c9f8cbf6-c8xdc          0/1     Pending   0             24s
    php-apache-78c9f8cbf6-t75w2          0/1     Pending   0             24s
    php-apache-78c9f8cbf6-wc98s          1/1     Running   0             24s
    ...
    
    • Cluster Autoscalerの動作確認
    $ kubectl get configmap -n kube-system cluster-autoscaler-status -o yaml
    ...
    Cluster-wide:
      Health:      Healthy (ready=3 unready=0 (resourceUnready=0) notStarted=0 longNotStarted=0 registered=3 longUnregistered=0)
                   LastProbeTime:      2024-02-20 11:15:50.82048015 +0000 UTC m=+2242462.962201862
                   LastTransitionTime: 2024-01-25 12:22:06.170599081 +0000 UTC m=+38.312320847
      ScaleUp:     InProgress (ready=3 registered=3)
                   LastProbeTime:      2024-02-20 11:15:50.82048015 +0000 UTC m=+2242462.962201862
                   LastTransitionTime: 2024-02-20 11:14:29.611869206 +0000 UTC m=+2242381.753590773
      ScaleDown:   NoCandidates (candidates=0)
                   LastProbeTime:      2024-02-20 11:15:50.82048015 +0000 UTC m=+2242462.962201862
                   LastTransitionTime: 2024-01-25 12:22:06.170599081 +0000 UTC m=+38.312320847
    
    NodeGroups:
      Name:        node
      Health:      Healthy (ready=1 unready=0 (resourceUnready=0) notStarted=0 longNotStarted=0 registered=1 longUnregistered=0 cloudProviderTarget=2 (minSize=1, maxSize=8))
                   LastProbeTime:      2024-02-20 11:15:50.82048015 +0000 UTC m=+2242462.962201862
                   LastTransitionTime: 2024-02-20 11:13:49.540592255 +0000 UTC m=+2242341.682313956
      ScaleUp:     InProgress (ready=1 cloudProviderTarget=2)
                   LastProbeTime:      2024-02-20 11:15:50.82048015 +0000 UTC m=+2242462.962201862
                   LastTransitionTime: 2024-02-20 11:14:29.611869206 +0000 UTC m=+2242381.753590773
      ScaleDown:   NoCandidates (candidates=0)
                   LastProbeTime:      2024-02-20 11:15:50.82048015 +0000 UTC m=+2242462.962201862
                   LastTransitionTime: 2024-02-20 11:13:49.540592255 +0000 UTC m=+2242341.682313956
    ...
    
  7. ウォーカーノードの拡張と Podのスケジューリングを確認します。

    • ワーカーノードの拡張の確認
    $ kubectl get nodes
    NAME                 STATUS            ROLES    AGE    VERSION
    node-1               Ready             <none>   13m    v1.27.9
    node-2               Ready             <none>   2m8s   v1.27.9
    node-3               Ready             <none>   88d    v1.27.9
    node-4               Ready             <none>   15d    v1.27.9
    
    • Podの Runningステータスの確認
    $ kubectl get pods | grep php-apache
    
  8. 負荷が停止すると、Pod数が減少します。その後、Cluster Autoscalerはノードのリソース使用量を監視し、必要に応じてワーカーノード数を減らしてクラスタの規模を縮小します。

参考
  • クラスタを構成する際に選択したノードの仕様によって結果が変わる可能性があるため、テスト前にノードの仕様を適切に考慮します。
  • 負荷が停止した後も、特定の条件により、ノード削減がすぐに行われない場合があります。例えば、ノードに重要なシステム Podが実行されている場合や、ローカルストレージを使用する Podの場合、ノード削減が制限されることがあります。
  • 負荷テストによるクラスタの拡張と縮小は実際の運用環境での性能と異なる場合があるため、実際の環境に適用する前にテスト結果を基に十分に検討が必要です。

トラブルシューティング

Cluster Autoscalerの使用中に問題が発生した場合は、Ncloud Kubernetes Service のトラブルシューティング-拡張性とパフォーマンス問題をご参照ください。