DevOps

[ k8s ] Kubernetes Cluster AutoScaler VS Karpenter

궁금한게 많은 개발자 2024. 4. 19. 13:01

안녕하세요. 오늘 포스팅에서는 Kubernetest에서 Node Auto Scaling방식에 대해 알아보고,

대표적인 방식인 Cluster AutoScaler(CAS)Karpenter에 대해 비교를 해보려 합니다 😎✔

 

 

우선 , 비교적 오래전부터 사용되고 있었던 Cluster AutoScaler(이하 CAS)에 대해 알아보고, 동작 방식에 대해서도 정리해보겠습니다.

기본적으로 해당 포스팅에서 설명하는 Cloud Service Provisioner(CSP)는 AWS를 기준으로 작성됨을 참고 부탁드립니다!!

AWS EKS(Elastic Kubernetes Service)의 경우에는 Kubernetes의 기본 CAS와 EC2 Auto Scaling Group(ASG)의 기능을 활용하여 Node Auto Scaling을 지원합니다.

 

 

[ Cluster AutoScaler 동작 원리 ]

 

기본적인 시나리오는 아래와 같습니다.

  1. Horizontal Pod AutoScaler(HPA) 에 의한 pod의 수평적 확장이 한계에 다다르면, pod는 적절한 Node 를 배정받지 못하고 pending 상태에 빠집니다.
  2. 이때 CA 는 Pod 의 상태를 관찰하다가 지속해서 할당에 실패하면 Node Group 의 ASG Desired Capacity 값을 수정하여 Worker Node 개수를 증가하도록 설정합니다.
  3. 이를 인지한 ASG 가 새로운 Node를 추가합니다.
  4. 여유 공간이 생기면 kube-scheduler 가 Pod를 새 Node에 할당합니다.

 

이러한 과정에서 CAS는 AWS 리소스인 ASG에 의존도가 높기 때문에, CA의 ASG업데이트 ->  Node추가 생성, Cluster Join -> Pod 할당에 생각보다 오랜 시간이 걸리게 됩니다.

또한, ASG는 Worker Node들을 그룹핑하여 관리하고, 새로 생성될 노드를 Launch Template로 관리합니다. 이러한 작업은 Kubernetes와 무관하게 AWS의 기능에 따른 작업입니다.

노드 생성될 때 별다른 작업이 필요하지 않다면 문제가 되지 않지만, Custom userdata를 추가해야 한다면 AWS Launch Template을 따로 관리해야 하고, 여러 Node Group이 생긴다면

이러한 작업들이 모두 운영 부담으로 다가올 수 있습니다.

 

위 부담에 이어 CAS에는 치명적일 수 있는 단점들이 존재합니다.

  • EKS Node Group을 설정하고, Node Group중에 생성할 Node를 설정하는 과정들이 Pod 배포와 별개로 느껴질 수 있습니다.
  • Auto Scaling을 위한 ASG설정, 노드 그룹 관리 및 Node Template설정이 어려울 수 있습니다.
  • 또한 Node생성 방식을 On-demand와 Spot 비율 조정이 불가능하며, Spot이 가능할 때에도 On-demand Group을 사용하는 경우가 많다고 합니다.
  • Spot으로 생성된 노드에서도 모든 노드에 생성되는 daemonset pod만 존재하더라도 노드를 삭제하지 않기에, 운영 비용 측면에서도 단점이 될 수 있습니다.

 

 

 

 

이러한 문제점들을 해결할 수 있는 OpenSource인 Karpenter를 AWS가 출시하였습니다.

(ASG를 계속 사용하게 하면 AWS가 더 좋을 것 같은데, 기술 발전을 위해 이런 오픈소스 개발은 소비자에게도 좋은 것 같습니다🤗)

https://aws.amazon.com/ko/blogs/aws/introducing-karpenter-an-open-source-high-performance-kubernetes-cluster-autoscaler/

 

 

Karpenter는 AWS로 구축된 유연한 오픈 소스의 고성능 Kubernetes 클러스터 오토스케일러입니다. https://karpenter.sh/
애플리케이션 로드의 변화에 대응하여 적절한 크기의 컴퓨팅 리소스를 신속하게 실행함으로써 애플리케이션 가용성과 클러스터 효율성을 개선할 수 있습니다. 
또한 Karpenter는 애플리케이션의 요구 사항을 충족하는 컴퓨팅 리소스를 적시에 제공하며, 
앞으로 클러스터의 컴퓨팅 리소스 공간을 자동으로 최적화하여 비용을 절감하고 성능을 개선하게 됩니다.

즉, Karpenter는 Provisioning(Pod/Node Scheduling)과 Deprovisioning(비용 효율화를 위해 노드를 통/폐합)의 기능을 수행합니다.

 

Karpenter가 동작하는 원리는 다음과 같습니다.

 

 

  1. Horizontal Pod AutoScaler(HPA) 에 의한 Pod의 수평적 확장이 한계에 다다르면, Pod 는 적절한 Node 를 배정받지 못하고 pending 상태에 빠집니다.
  2. 이때 Karpenter 는 지속해서 unscheduled Pod 를 관찰하고 있다가, 새로운 Node 추가를 결정하고 직접 배포합니다.
  3. 추가된 Node가 Ready 상태가 되면 Karpenter 는 kube-scheduler 를 대신하여 pod 의 Node binding 요청도 수행합니다.

이렇게 Karpenter는 CAS에 비해 단순한 구조를 갖고 있으며, Node확장 시 일어나는 많은 부분들을 직접 처리함으로써, (ASG, kube-scheduler의 기능 대체)

좀 더 빠른 확장을 처리할 수 있도록 설계되었다고 합니다. Karpenter에 의해 생성되는 모든 Worker Node들은 Karpenter에 의해 Lifecycle이 결정됩니다.

 

이러한 Karpenter를 적용했을 때 CAS와 비교해서 얻을 수 있는 장점들을 나열해 보려 합니다.

  1. CA를 위하여 Launch Template을 어렵게 구성할 필요가 없습니다.
    Karpenter는 Groupless Auto Scaling입니다. 더 이상 ASG 나 Launch Template을 관리하지 않고 그룹 정의와는 상관없이
    EC2의 타입, 구매 유형(on-demand/Spot), 가용 영역 등을 자유롭게 선택할 수 있습니다.
  2. 유연하고 빠르게 노드를 확장/제거할 수 있습니다.
    ASG를 사용해서 노드를 확장하는 CA와 달리 Karpenter는 자체 구현된 오픈소스 JIT(Just-In-Time)으로 빠르게 Node를 확장하고 Pod를 할당하기 때문에 프로비저닝 속도가 훨씬 빠릅니다.
  3. 자동으로 Node가 롤링 업데이트 되기 때문에 운영 관리가 간편화됩니다.
    Karpenter Provisioner에 ttlSecondsUntilExpired를 정의하면 Node를 최신 버전의 AMI로 주기적으로 롤링 업데이트하여 Node를 최신화합니다.
    이를 통해 EKS를 업그레이드할 때는 컨트롤 플레인과 Karpenter를 사용하지 않는 노드그룹 업그레이만 신경 쓰면 됩니다. (잦은 노드 베이스 보안 패치에 대응 가능)
  4. 크게 상승한 노드의 활용도
    • 기본적으로 Groupless의 콘셉트를 가지지만 활용에 따라 NodeGroup을 보다 효율적으로 관리할 수 있었습니다.
      특정한 NodeGroup을 3개씩 같은 인스턴스 유형으로 묶는다거나, 스팟 인스턴스를 우선적으로 할당받도록 할 수 있고
      노드의 자원을 최대한 효율적으로 사용할 수 있었고, 자연스럽게 비용 절감이라는 큰 효과도 얻을 수 있었습니다.
    • 애플리케이션의 리소스 요구 사항의 변화에 신속하게 대응 가능해졌습니다.
      기존 NodeGroup에서는 하나의 인스턴스 유형, 타입만 사용할 수 있어 리소스가 증가할 경우 유연하게 대응하기가 어려웠는데요. Karpenter를 적용하면서 인스턴스 선택이 자유로워졌습니다.
      Provisioner 에서는 다양한 인스턴스 타입을 정의할 수 있습니다. 이렇게 되면 사용 리전 내 인스턴스 가용성을 걱정해야 할 일도 줄어들고,
      신규 Node 추가 시 Karpenter 가 요청 Pod 에 가장 적절한 인스턴스 타입을 골라 기동하므로 Kubernetes 클러스터 운영 효율을 논할 때 늘 나오는 bin packing 문제도 개선할 수 있습니다.
  5. 빠른 버전 업그레이드에 따른 기대
  6. Karpenter 는 2021년 11월 처음 GA되어 2022년 09월까지 60여 번의 버전 릴리즈가 있었을 만큼 빠르게 업데이트되고 있습니다.
    처음에는 Launch Template을 활용하였지만, 얼마 안 가 userdata를 정의할 수 있는 AWSNodeTemplate CRD가 출시되어 최신 AMI를 유지하면서도 userdata를 적용할 수 있게 되었습니다.

 

 

설치 방법으로는 Helm을 사용할 수도 있고, 아래와 같이 CAS에서 Migration하는 방법도 있습니다. 🙌

다음은 CAS를 Karpenter로 전환할 때 주의해야할 점들에 대한 가이드입니다.

This guide will show you how to switch from the Kubernetes Cluster Autoscaler to Karpenter for automatic node provisioning.
  • We will make the following assumptions in this guide.
  • You will use an existing EKS cluster.
  • You will use existing VPC and subnets.
  • You will use existing security groups.
  • Your nodes are part of one or more node groups.
  • Your workloads have pod disruption budgets that adhere to EKS best practices.
  • Your cluster has an OIDC provider for service accounts.
    This guide will also assume you have the aws CLI installed.
    You can also perform many of these steps in the console, but we will use the command line for simplicity. Migrating from Cluster Autoscaler

설치 후 환경 구성이나 활용 방법에 대해서는 karpenter.sh를 참고해주시면 감사하겠습니다.

 

 

실제로 Karpenter를 적용할 때는 모든 Node Auto Scaling을 Karpenter에만 맡기지 않고, 

Core service들(ArgoCD, Kibana, Elasticsearch, ..)에 대해서는 AWS Managed Node Group인 CAS를 사용하여 Core node group으로 관리하고,

3rd Party Application이나 직접 개발한 Service들을 띄우기 위해 Karpenter CPU/GPU NodePool/EC2NodeClass를 정의하여 사용하였습니다.

기본적으로 Karpenter는 GroupLess이지만 활용에 따라 NodeGroup보다 더 효율적으로 Grouping할 수 있기에,

크게보면 3가지 NodeGroup(CAS, Karpenter CPU, Karpenter GPU)으로 운영 환경을 구축하여 사용 중에 있습니다.

 

이상으로 Kubernetes Cluster AutoScaler와 Karpenter에 대해 정리해봤습니다.

피드백이나 조언은 언제든지 환영합니다. 감사합니다 😊☕🙌