Cluster Autoscaler 비교(k8s Autoscaler vs Karpenter)

2022. 7. 25. 13:56카테고리 없음

Cloud 의 장점은 여러 가지가 있지만 그 중 탄력성 및 유연성에 관련된 주제를 다뤄보고자 합니다. 바로 Autoscaling 입니다. 

Kubernetes 환경에서 Autosclaing 은 VPA(Vertical Pod Autoscaler), HPA(Horizontal Pod Autoscaler) 그리고 CA(Cluster Autoscaler) 로 구분해서 볼 수 있으며 본 포스트에서는 CA 솔루션을 분석하였습니다. 

 

CA 는 크게 두가지 솔루션이 있습니다. 

기존 쿠버네티스 공식 서브  프로젝트 중 하나인 Autoscaler 를 이용하는 것이 첫번째 이고, 

AWS 에서 오픈소스 프로젝트로 얼마전 GA 한 Karpenter 가 두번째입니다. 

 

k8s Cluster Autoscaler 

k8s Cluster Autoscaler (on AWS) 의 동작 로직입니다. 

참고로 k8s Cluster Autoscaler 를 이용한 노드 오토스캐일링은 각 CSP 별로 구현 방식에 차이가 있으니 kubernetes 구성 환경에 맞춰 확인하시길 바랍니다. 

간단히 정리하면 Node 리소스 부족으로 Pending 중인 Pod 를 감지하면 ASG(autoscaling group) 에 desired capacity 늘려서 요청하게 되고 그렇게 추가된 신규 노드에 kube-scheduler 가 Pending 중인 Pod 를 배치하게 됩니다. 

워크로드가 줄어들어 불필요 노드가 발생한 경우 노드 삭제(Scale-In) 도 가능합니다.  

기본적으로 Scan interval 이 10초이며 이때마다 삭제 가능한 노드가 있는지 확인합니다. 만약 지정된 utilization-threshold(defaul : 50%) 보다 수치가 떨어지게 되면 Autoscaler 는 Pod 재배치를 통해 노드를 비우고 삭제하게 됩니다. 참고로 기준값은 Pod 의 Request 값입니다. (실제 리소스 사용률은 관계 없음) 

 

<주요 파라미터>

Parameter Description Default
scan-interval How often cluster is reevaluated for scale up or down 10초
scale-down-delay-after-add How long after scale up that scale down evaluation resumes 10분
scale-down-unneeded-time How long a node should be unneeded before it is eligible for scale down 10분
scale-down-utilization-threshold Node utilization level, defined as sum of requested resources divided by capacity, below which a node can be considered for scale down 0.5

다만 아래 조건이 있다면 Autoscaler 는 파드 재배치 및 노드 삭제를 진행하지 못합니다. 

  1. PodDisruptionBudget이 설정되어있을때
  2. kubesystem namespace를 가진 pod가 있을때 ( 단 디폴트로 뜨는 kube-system 의 pod 는 예외. eg) kube-proxy )
  3. pod를 다른 node로 이동할 수 없을 때 (lack of resources, non-matching node selectors or affinity, matching anti-affinity, etc)
  4. Pod 에 "cluster-autoscaler.kubernetes.io/safe-to-evict" : "false" 어노테이션이 설정 되어있는경우.
  5. Pods that are not backed by a controller object (so not created by deployment, replica set, job, stateful set etc). *
  6. 로컬 스토리지를 사용하는 파드가 있는 경우 

 

 

Karpenter

다음은 Karpenter 입니다. 

카펜터는 스케줄링 되지 못하는 파드에 대응해 노드를 자동으로 추가해주는 AWS 의 오토스케일링 오픈소스 툴입니다. 물론 불필요한 노드를 줄이는 기능도 포함됩니다. 카펜터는 Pending 된 파드 resoure request의 합을 기반으로 적절한 인스턴스 타입을 결정하는 것이 특징입니다. re:Invent 2021 에서 Karpenter 를 공식 발표하였으며 v0.5 의 정식 버전 오픈했다(GA). 즉 프로덕션 환경에서 사용할 정도의 안정성을 지녔음을 의미하며 또한 구조상 AWS 외 다른 CSP 에서도 동작 가능합니다. (다만 현재 버전에서는 EKS 외 다른 클러스터에서는 지원이 불가)

 

동작 로직입니다. 

  • 가용 노드가 없어 Pod 가 배치되지 못하면 Karpenter 가 해당 사실 인지

  • Custom Resource 인 Provisioner 가 어떤 instance type 으로 배포할 지 (Spot 사용 여부 등) 결정

  • 노드가 배포 되면 karpenter 가 직접 해당 노드로 바인딩

 

Karpenter 가 노드 Provisiong 및 Pod scheduling 에 직접 관여하면서 성능(속도)가 많이 개선되었습니다. 

Pod pending 후 creating 까지 소요시간을 보면 아래와 같이 3배 정도 빨라진 것을 확인할 수 있습니다. 

 

노드 삭제(deprovisioned) 의 경우 아래와 같은 방법으로 수행됩니다. 

  • Provisioner Deletion : provisiner 가 삭제될 시
  • Node empty : 노드에 daemonset 을 제외한 파드가 없을 시 ttlSecondsAfterEmpty 값에 따라 삭제
  • Node expired : 노드가 생성된 후 업데이트 등의 목적으로 ttlSecondsUntilExpired 값에 따라 삭제
  • manual deleted : kubectl 로 사용자가 임의 삭제

만약 Scale-in 을 원하지 않는 파드(노드) 가 있다면 아래와 같은 조건으로 회피 가능합니다. 

  • Disruption budgets 가 설정된 파드가 있고 해당 노드에서 삭제할 수 없는 상황인 경우
  • 파드에 do-not-evict 어노테이션이 설정된 경우 (karpenter.sh/do-not-evict: true) : 해당 노드 유지

 

기존 솔루션(k8s autoscaler) 과 신규 솔루션(Karpenter) 를 간단히 비교하면 다음과 같습니다. 

 

운영 환경에 맞춰 솔루션을 선택하는 것은 사용자의 몫입니다. 

다만, Karpenter 가 신규 프로젝트이고 계속 버전 업데이트가 되면서 기능이 추가 되는 상황을 생각하면 Autoscaler 첫 도입시 Karpenter 를 고려해볼 만도 합니다. 

 

문의 사항은 fernweh@sk.com 로 보내주시던가 여기 댓글에 남겨주세요.