Ssoon

[5주차] EKS Autoscaling - KARPENTER - AUTOMATIC NODE PROVISIONING 본문

AWS EKS Workshop Study

[5주차] EKS Autoscaling - KARPENTER - AUTOMATIC NODE PROVISIONING

구구달스 2023. 5. 25. 08:01
CloudNet@ 팀의 AWS EKS Workshop Study 5주차 정리입니다.
# Karpenter Workshop 의 내용입니다.

  • Karpenter 프로비저닝 노드에 대한 응답으로 배치를 사용하여 일부 포드를 생성합니다.
cat <<EOF > inflate.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inflate
spec:
  replicas: 0
  selector:
    matchLabels:
      app: inflate
  template:
    metadata:
      labels:
        app: inflate
    spec:
      nodeSelector:
        intent: apps
      containers:
        - name: inflate
          image: public.ecr.aws/eks-distro/kubernetes/pause:3.2
          resources:
            requests:
              cpu: 1
              memory: 1.5Gi
EOF
kubectl apply -f inflate.yaml

Karpenter가 초기 배포 후 클러스터를 확장하지 않은 이유는 무엇입니까?

배포는 복제본: 0으로 생성되었습니다. 두 가지 이유로 이 작업을 수행했습니다. 이 섹션에서는 첫 번째 이유를 언급할 것입니다. 귀하의 편의를 위해 복제본을 0으로 설정했으므로 배치에서 복제본 수를 늘리면 Karpenter 로그를 확인할 수 있습니다.


replicas 을 1로 변경합니다.

kubectl scale deployment inflate --replicas 1

다음 명령을 실행하여 복제본의 상태를 확인할 수 있습니다. Karpenter가 새 인스턴스를 프로비저닝하면 포드가 새 노드에 배치됩니다.


Karpenter는 인스턴스를 늘릴 때 어떤 인스턴스 유형을 사용했습니까? 

다음 명령을 실행하여 어떤 인스턴스 유형이 사용되었는지 확인할 수 있습니다.

노드가 프로비저닝된 방법에 대해 배울 수 있는 훨씬 더 흥미로운 것이 있습니다. Karpenter 로그를 확인하고 새로 생성된 Karpenter를 살펴보십시오. 라인은 아래 라인과 비슷해야 합니다.

이전에 group-less 클러스터 스케일러와 이것이 운영 및 유지 관리를 간소화하는 방법에 대해 설명했습니다. 잠시 이 개념에 대해 자세히 살펴보겠습니다. Karpenter가 다양한 인스턴스 선택에서 인스턴스를 선택하는 방법에 주목하십시오. 이 경우 다음 인스턴스를 선택했습니다.

controller.provisioner  launching machine with 1 pods requesting {"cpu":"1125m","memory":"1536Mi","pods":"3"} from types c5a.4xlarge, r5dn.8xlarge, r5a.xlarge, r5a.2xlarge, m5zn.6xlarge and 158 other(s)  {"commit": "982c35f", "provisioner": "default"}

 

이 선택에 대해 필터링되는 'nano', 'micro', 'small', 'medium', 'large' 유형에 유의하십시오. 가능한 한 많은 인스턴스에서 다양화하는 것이 권장 사항이지만 프로비저너가 더 작은(또는 특정) 인스턴스 유형을 필터링하려는 경우가 있습니다.

 

인스턴스 유형은 선택한 지역에 따라 다를 수 있습니다.

이 모든 인스턴스는 제출된 포드에 대한 리소스(메모리 및 CPU) 낭비를 줄이는 데 적합한 인스턴스입니다. 

 

EC2 Spot 인스턴스를 사용하도록 Karpenter Provisioner를 설정했으며, 인스턴스 유형을 필터링하기 위한 Provisioner에 instance-types 요구 사항 섹션이 없었습니다. 이것은 Karpenter가 사용할 인스턴스 유형의 기본값을 사용할 것임을 의미합니다. 기본값에는 metal(non-virtualized), non-HVM 및 GPU 인스턴스를 제외한 모든 인스턴스 유형이 포함됩니다. 내부적으로 Karpenter는 Instant 모드에서 EC2 플릿을 사용하여 인스턴스를 프로비저닝했습니다.

 

다음은 Karpenter의 핵심인 EC2 플릿 인스턴트 모드에 대해 언급할 몇 가지 속성입니다.

  • EC2 플릿 인스턴트 모드는 EC2 스팟을 포함하여 인스턴스를 조달하기 위한 동기식 호출을 제공하여 인스턴스를 프로비저닝할 때 오류를 단순화하고 방지합니다.  
  • 인스턴트 모드에서 EC2 플릿에 대한 호출은 매우 큰 인스턴스를 프로비저닝할 가능성을 줄이는 가격 용량 최적화 인스턴스 선택을 사용하여 수행됩니다. 용량 최적화 할당 전략은 시작된 인스턴스 수에 대해 최적의 용량을 가진 스팟 용량 풀에서 인스턴스를 선택하므로 선택한 인스턴스의 스팟 종료 빈도가 줄어듭니다.  
  • 인스턴트 모드에서 EC2 집합에 대한 호출은 스팟 집합으로 간주되지 않습니다. 스팟 집합 제한에 포함되지 않습니다. 이는 Karpenter가 시간이 지남에 따라 필요한 만큼 이 API를 호출할 수 있다는 것을 의미합니다.

Karpenter는 First Fit Decreasing 알고리즘을 사용하여 여러 가상 머신 인스턴스를 최적으로 배치하는 기술입니다. 이 기술은 Bin-packing 문제를 해결하고, EC2 Fleet 인스턴스 플릿을 사용하여 인스턴스 다양화와 가격 용량 최적화를 수행합니다.
기존에는 고객이 용량 제약에 따라 여러 Auto Scaling 그룹을 정의해야 했습니다. 그러나 Karpenter를 사용하면 이러한 번거로움을 제거할 수 있습니다. Karpenter는 모든 애플리케이션이 적합하도록 설계되었습니다.
Kubernetes 클러스터의 운영을 단순화합니다. Karpenter는 자동으로 인스턴스 배치와 관리를 처리하므로, 고객은 자원 할당과 관련된 복잡한 작업을 직접 수행할 필요가 없습니다. 이를 통해 운영 효율성을 향상시키고, Kubernetes 클러스터를 더 쉽게 관리할 수 있습니다.


새 인스턴스 속성 및 레이블은 무엇입니까?

kubectl describe node --selector=intent=apps

  • 프로비저너 구성에서 명시한 대로 node는 intent=apps 로 생성되었습니다.
  • 스팟 구성에도 동일하게 적용됩니다. karpenter.sh/capacity-type 레이블 확인
  • Karpenter AWS 구현은 region  zone에 대한 Labels 인 topology.kubernetes.io 도 추가합니다.
  • Karpenter는 여러 프로비저너를 지원합니다. karpenter.sh/provisioner-name 이 인스턴스 수명 주기 관리를 담당하는 프로비저너로 default 을 사용하는 방법에 유의하십시오.

  • 선택한 인스턴스는 kubernetes.io/arch 아키텍처에 대한 프로비저너 CRD 요구 사항이 제공되지 않은 경우 Karpenter가 사용할 기본 아키텍처로 생성되었습니다.
  • Karpenter 노드에 사용되는 컨테이너 런타임은 containerd 입니다.

새로 생성된 inflate Pod가 managed node group 에 예약되지 않은 이유

  • On-Demand Managed Node group 은 control-apps 로 설정된 레이블 intent 로 프로비저닝되었습니다.
  • deployment 는 intent 가 apps 로 정의했습니다.

  • Karpenter 기본 프로비저너도 생성되었습니다.

  • NodeSelector, Taints 및 Tolerations를 사용하여 클러스터의 토폴로지를 분할하고 Pods 및 Jobs 을 배치할 위치를 Karpenter에 지정할 수 있습니다.
  • Karpenter와 Cluster Autoscaler는 모두 NodeSelector, Taints 및 Tolerations를 고려합니다. 동일한 클러스터에서 Auto Scaling 관리 솔루션을 혼합하면 Cluster Autoscaler 및 Karpenter와 같은 Auto Scaler 시스템이 모두 예약할 수 없는 Pod에 대한 응답으로 노드를 확장하므로 부작용이 발생할 수 있습니다. 경합 상태를 방지하려면 NodeSelector, Taints 및 Tolerations를 사용하여 리소스를 명확하게 구분해야 합니다. 

replicas 을 10으로 확장한 후 어떤 일이 일어나며 어떤 인스턴스 유형이 선택되었습니까?

kubectl scale deployment inflate --replicas 10
  • pending 상태의 pod가 트리거가 되어 새로운 인스턴스를 선택하고 node를 생성합니다.

  • 이번에는 용량이 약간 다른 특성 세트로 프로비저닝됩니다. 
  • Karpenter가 팟 요구 사항의 크기를 고려하여 어떤 유형의 인스턴스 다양화를 사용할지 확인합니다.

controller.provisioner.cloudprovider    launched new instance   {"commit": "982c35f", "provisioner": "default", "id": "i-032037afb39077a46", "hostname": "ip-192-168-93-89.ap-northeast-2.compute.internal", "instance-type": "c4.2xlarge", "zone": "ap-northeast-2a", "capacity-type": "spot"}

  • 이번에 선택한 인스턴스는 "c4.2xlarge" 로 전에 생성된 인스턴스보다 더 큽니다!

replicas을 0으로 변경 후 어떤 일이 발생하나요?

kubectl scale deployment inflate --replicas 0

  • 이전 섹션에서는 ttlSecondsAfterEmpty를 30초로 설정하여 기본 제공자를 구성했습니다.
  • 노드에 예약된 포드가 없으면 Karpenter는 cordon 및 drain 모범 사례를 사용하여 빈 노드를 종료합니다.

Karpenter는 0으로의 스케일링을 지원합니다. Karpenter는 총 pod 리소스 요청에 따라 필요한 경우에만 노드를 시작하거나 종료합니다. Karpenter는 노드를 사용하는 pod 가 있는 한 클러스터에 노드만 유지합니다.


  • Karpenter는 group-less 접근 방식으로 노드를 확장합니다. Karpenter는 보류 중인 pod 수와 프로비저닝 구성에 따라 확장할 노드를 선택합니다. 워크로드에 가장 적합한 인스턴스의 모양을 선택한 다음 해당 인스턴스를 프로비저닝합니다. 이것은 Cluster Autoscaler가 수행하는 것과는 다릅니다. Cluster Autoscaler의 경우 먼저 모든 기존 노드 그룹을 평가하고 Pod 제약 조건에 따라 확장하기에 가장 적합한 노드 그룹을 찾습니다.
  • Karpenter는 애플리케이션에 사용 가능한 작업 pod 가 있는 경우 0에서 확장하고 실행 중인 작업 또는 pod 가 없으면 0으로 축소할 수 있습니다.
  • 프로비저너는 클러스터 파티션 내에서 노드가 프로비저닝되는 방식을 정의하는 거버넌스와 규칙을 정의하도록 설정할 수 있습니다. karpenter.sh/capacity-type과 같은 요구 사항을 설정하여 온디맨드 및 스팟 인스턴스를 허용하거나 karpenter.k8s.aws/instance-size를 사용하여 더 작은 크기를 필터링할 수 있습니다.
  • Karpenter는 cordon 및 drain 모범 사례를 사용하여 노드를 종료합니다. 노드가 종료되는 시기의 구성은 ttlSecondsAfterEmpty로 제어할 수 있습니다.

노드가 완전히 유휴 상태일 때만 노드를 종료하는 기능은 batch 워크로드에서 사용하는 클러스터 또는 프로비저너에 이상적입니다. 이는 ttlSecondsAfterEmpty 설정으로 제어됩니다. batch 워크로드에서는 이상적으로 모든 kubernetes 작업을 완료하고 노드를 제거하기 전에 노드를 유휴 상태로 두려고 합니다. 이 동작은 워크로드가 상태 비저장 마이크로 서비스를 장기간 실행하는 시나리오에서는 적합하지 않습니다. 이 조건에서 가장 좋은 방법은 Karpenter consolidation 기능을 사용하는 것입니다.

Comments