VPC 환경에서 이용 가능합니다.
Kubernetes는 클러스터 자동 스케일링과 리소스 관리를 위해 Cluster Autoscaler와 Vertical 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 기능이 비활성화 된 상태로 제공됩니다. 사용자는 콘솔의 노드풀 설정을 통해 이 기능을 간편하게 활성화할 수 있으며, 이를 통해 자동으로 클러스터의 크기를 조절하고 리소스 사용을 최적화할 수 있습니다.
- 네이버 클라우드 플랫폼의 콘솔에서 Services > Containers > Ncloud Kubernetes Service > Clusters 메뉴를 차례대로 클릭해 주십시오.
- Cluster Autoscaler를 활성화하고 싶은 노드풀을 선택합니다.
- 상단의 [수정] 버튼을 클릭합니다.
- [설정] 버튼을 클릭한 다음 최소 노드 수, 최대 노드 수를 기입합니다.
- 클러스터의 워커 노드 총 개수는 Cluster Autoscaler의 최대 노드 수를 포함하여 계산됩니다. 클러스터 운영 시 해당 요소를 고려하여 적절한 관리가 필요합니다.
- 최초 설정 시 현재 노드 수가 설정된 최소 노드 수보다 적을 경우에도 자동으로 노드 수를 증가시키지 않습니다. 필요한 경우 노드 수를 수동으로 조정한 다음 설정해야 합니다.
- [수정] 버튼을 클릭해 Cluster Autoscaler를 활성화합니다.
- 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에서 상세히 확인할 수 있습니다.
-
Cluster Autoscaler를 테스트 할 클러스터를 준비합니다.
-
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 ...
-
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
-
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
-
부하를 일으켜 파드의 증가를 확인합니다.
- 별도의 터미널에서 부하 증가
$ 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
-
신규로 생성된 파드의 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 ...
-
워커 노드의 확장 및 파드의 스케줄링을 확인합니다.
- 워커 노드 확장 확인
$ 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
-
부하가 중지되면 파드의 수가 줄어듭니다. 이후 Cluster Autoscaler는 노드의 리소스 사용량을 관찰하여 필요에 따라 워커 노드의 수를 줄여 클러스터의 규모를 축소합니다.
- 클러스터를 구성할 때 선택한 노드의 사양에 따라 결과가 달라질 수 있으므로, 테스트 전에 노드 사양을 적절히 고려해야 합니다.
- 부하가 중지된 후에도, 특정 조건으로 인해 노드 감소가 즉시 발생하지 않을 수 있습니다. 예를 들어, 노드에 중요한 시스템 파드가 실행 중이거나, 로컬 스토리지를 사용하는 파드가 있을 경우 노드 감소가 제한될 수 있습니다.
- 부하 테스트를 통한 클러스터의 확장 및 축소는 실제 운영 환경에서의 성능과 다를 수 있으므로, 테스트 결과를 토대로 실제 환경에 적용하기 전에 충분한 검토가 필요합니다.
문제 해결
Cluster Autoscaler 사용 도중 발생한 문제는 Ncloud Kubernetes Service 문제 해결 - 확장성 및 성능 문제을 참조해 주십시오.