Cluster Autoscaler 이용

Prev Next

VPC 환경에서 이용 가능합니다.

Kubernetes는 클러스터 자동 스케일링과 리소스 관리를 위해 Cluster AutoscalerVertical Pod Autoscaler 두 가지 기능을 제공합니다. 이 중 Cluster Autoscaler를 통해 클러스터의 워커 노드를 자동으로 확장하거나 축소할 수 있습니다. 이를 통해 클러스터 리소스를 보다 유연하고 효율적으로 관리할 수 있습니다.

이 가이드는 Ncloud Kubernetes Service에서 Cluster Autoscaler의 기능과 사용 방법을 설명합니다.

Cluster Autoscaler

Cluster Autoscaler는 Kubernetes 클러스터의 크기를 자동으로 조정하여 리소스 사용을 최적화합니다. 리소스 부족으로 인해 스케줄링 되지 못한 파드가 있을 때 클러스터를 확장합니다. 반대로, 클러스터 내 노드 중 일부가 지속적으로 낮은 리소스 사용률을 보이면 해당 노드를 축소하여 리소스 낭비를 방지합니다. 이 과정은 파드의 요구 사항과 클러스터의 현재 리소스 상황을 기반으로 자동으로 수행됩니다.

Cluster Autoscaler의 동작을 위해서는 파드의 리소스 요청(requests)과 제한(limits)이 정의되어 있어야 합니다. 이 정보는 Cluster Autoscaler가 클러스터의 리소스 사용률을 분석하고, 필요에 따라 클러스터의 크기를 조정하는 데 필수적입니다. 리소스 요청은 파드가 시작할 때 필요한 최소 리소스 양을 지정하고, 리소스 제한은 파드가 사용할 수 있는 최대 리소스 양을 제한합니다.

Cluster Autoscaler 동작 원리

Cluster Autoscaler는 클러스터의 리소스 사용률을 분석하고, 필요에 따라 클러스터의 크기를 조정합니다. 이 과정은 파드의 요구 사항과 클러스터의 현재 리소스 상황을 기반으로 자동으로 수행됩니다.

  • 스케일 업 조건
    • 새로 생성된 파드가 Pending 상태로 일정 시간 이상 머무르고 있으며, 현재 클러스터의 최대 노드 수와 노드풀의 maxSize 제한을 넘지 않는 경우 노드가 추가됩니다.
    • Cluster Autoscaler는 Pending 파드의 리소스 요청(Requests)을 기반으로 노드 추가 여부를 결정합니다.
  • 스케일 다운 조건
    • 클러스터 내 노드 중 일부가 지속적으로 낮은 리소스 사용률을 보이면 해당 노드를 축소합니다.
    • 노드의 CPU/Memory 요청(Requests)의 합이 노드의 allocatable 대비 scale-down-utilization-threshold(기본값: 0.5) 미만일 때 저사용 노드로 간주됩니다.
    • 기본적으로 --scale-down-unneeded-time(기본값: 10분) 동안 다른 파드가 해당 노드를 필요로 하지 않으면 축소 후보로 등록됩니다.
    • 이후 Cluster Autoscaler는 파드를 다른 노드로 안전하게 이동시킬 수 있는지 확인한 다음 노드를 제거합니다.
    • 단 아래와 같은 경우 축소 대상에서 제외됩니다.
      • 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. 네이버 클라우드 플랫폼의 콘솔에서 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 클러스터에서 부하 테스트를 진행합니다. 테스트를 통해 클러스터의 파드 수와 노드 수가 동적으로 조절되는 과정을 확인할 수 있습니다.

사용된 예제는 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. 부하를 일으켜 파드의 증가를 확인합니다.

    • 별도의 터미널에서 부하 증가
    $ 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. 신규로 생성된 파드의 Pending을 확인하고, Cluster Autoscaler의 동작을 확인합니다.

    • 파드의 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. 워커 노드의 확장 및 파드의 스케줄링을 확인합니다.

    • 워커 노드 확장 확인
    $ 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
    
    • 파드의 Running 상태 확인
    $ kubectl get pods | grep php-apache
    
  8. 부하가 중지되면 파드의 수가 줄어듭니다. 이후 Cluster Autoscaler는 노드의 리소스 사용량을 관찰하여 필요에 따라 워커 노드의 수를 줄여 클러스터의 규모를 축소합니다.

참고
  • 클러스터를 구성할 때 선택한 노드의 사양에 따라 결과가 달라질 수 있으므로, 테스트 전에 노드 사양을 적절히 고려해야 합니다.
  • 부하가 중지된 후에도, 특정 조건으로 인해 노드 감소가 즉시 발생하지 않을 수 있습니다. 예를 들어, 노드에 중요한 시스템 파드가 실행 중이거나, 로컬 스토리지를 사용하는 파드가 있을 경우 노드 감소가 제한될 수 있습니다.
  • 부하 테스트를 통한 클러스터의 확장 및 축소는 실제 운영 환경에서의 성능과 다를 수 있으므로, 테스트 결과를 토대로 실제 환경에 적용하기 전에 충분한 검토가 필요합니다.

문제 해결

Cluster Autoscaler 사용 도중 발생한 문제는 Ncloud Kubernetes Service 문제 해결 - 확장성 및 성능 문제을 참조해 주십시오.