관리형 서비스가 아닌 직접 구축한 Kubernetes 에서도 EKS 처럼 노드가 자동으로 늘고 주는지가 흔한 질문이다. 된다. 다만 Kubernetes 자체에는 서버를 만드는 기능이 없다. 자동 확장은 "노드를 만들어 줄 수 있는 아래 계층" 이 있을 때만 성립하며, 그 계층이 무엇이냐에 따라 도구 선택이 갈린다.
| 층 | 대상 | 도구 |
|---|---|---|
| 파드 자동 확장 | 복제본 수 · 리소스 요청량 | HPA · VPA · KEDA |
| 노드 자동 확장 | 노드(머신) 수 | Cluster Autoscaler · Karpenter · Cluster API |
파드 확장만으로는 노드 용량이 모자라면 파드가 Pending 에서 멈춘다. 노드 확장만 있으면 파드가 늘지 않아 노드가 늘 이유가 생기지 않는다. 둘을 함께 둔다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
autoscaling/v2 는 CPU · 메모리뿐 아니라 사용자 지표와 외부 지표를 함께 쓸 수 있다. 큐 길이 같은 이벤트 기반 지표로 0 까지 줄이려면 KEDA 를 얹는다. CPU 지표를 쓰려면 metrics-server 가 먼저 떠 있어야 한다.
Cluster Autoscaler 가 표준이다. 전제는 워커 노드가 오토스케일링 그룹(AWS ASG · GCP MIG · Azure VMSS)으로 관리되고 있어야 한다는 것이다. Cluster Autoscaler 는 그룹의 min/max 범위 안에서만 대수를 조절하며, 그룹 자체를 만들지는 않는다.
helm repo add autoscaler https://kubernetes.github.io/autoscaler
helm install cluster-autoscaler autoscaler/cluster-autoscaler \
--namespace kube-system \
--set autoDiscovery.clusterName=my-cluster \
--set awsRegion=ap-northeast-2 \
--set extraArgs.balance-similar-node-groups=true \
--set extraArgs.expander=least-waste \
--set extraArgs.scale-down-unneeded-time=10m \
--set extraArgs.scale-down-utilization-threshold=0.6
매니페스트로 직접 배포하면 핵심 인자는 --cloud-provider=aws 와 --nodes=<min>:<max>:<asg-name> 이다. ASG 와 시작 템플릿을 조작할 IAM 권한이 필요하다.
AWS 라면 Karpenter 도 선택지다. ASG 없이 인스턴스를 직접 띄우므로 용량 확보가 빠르고, 파드 요구사항에 맞는 인스턴스 타입을 그때그때 고른다. EKS 전용은 아니어서 AWS 위에 직접 구축한 클러스터에서도 쓸 수 있다.
vSphere · OpenStack · Proxmox 같은 환경에서는 Cluster API(CAPI) 로 머신 생애주기를 맡기고, 그 위에 Cluster Autoscaler 를 clusterapi 프로바이더로 얹는다. Cluster Autoscaler 는 clusterapi 를 포함해 수십 개 프로바이더를 지원한다.
clusterctl init --infrastructure vsphere
워커 그룹은 MachineDeployment 로 정의하고, 대수 증감은 Cluster Autoscaler 가 판단한다.
물리 서버를 자동으로 켜고 프로비저닝하는 계층이 없으면 노드 자동 확장은 성립하지 않는다. Metal³(Ironic) 같은 프로비저닝 레이어를 먼저 갖추거나, 노드 증감은 포기하고 파드 확장만 쓴다.
Cluster Autoscaler 는 Pending 파드를 보고 늘리고, 비어 가는 노드를 보고 줄인다. 줄이는 쪽이 막히는 조건이 훨씬 많다.
kube-system 파드cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 애너테이션이 붙은 파드requests 가 없으면 Cluster Autoscaler 도 Karpenter 도 부족함을 감지하지 못한다. 자동 확장의 전제 조건은 모든 워크로드에 requests 가 있는 것이다.
그 밖에 확인할 것은 다음과 같다. DaemonSet 이 노드마다 차지하는 고정 오버헤드, 축소 시 안전한 배수를 위한 PDB 와 우선순위, 워크로드 격리를 쓸 때 새 노드에도 같은 레이블과 테인트가 붙는지, 새 노드에서 CNI 와 스토리지 클래스가 자동으로 준비되는지. 스팟 인스턴스를 섞는다면 중단 신호 처리와 재스케줄링 전략을 같이 마련한다.