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 는 파드 재배치 및 노드 삭제를 진행하지 못합니다.
- PodDisruptionBudget이 설정되어있을때
- kubesystem namespace를 가진 pod가 있을때 ( 단 디폴트로 뜨는 kube-system 의 pod 는 예외. eg) kube-proxy )
- pod를 다른 node로 이동할 수 없을 때 (lack of resources, non-matching node selectors or affinity, matching anti-affinity, etc)
- Pod 에 "cluster-autoscaler.kubernetes.io/safe-to-evict" : "false" 어노테이션이 설정 되어있는경우.
- Pods that are not backed by a controller object (so not created by deployment, replica set, job, stateful set etc). *
- 로컬 스토리지를 사용하는 파드가 있는 경우
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 로 보내주시던가 여기 댓글에 남겨주세요.