DevOps/k8s

[K8s] AWS Karpenter를 통해 EKS 클러스터 효율적으로 관리하기 1편_기본 구성

Sophie소피 2024. 6. 14. 14:30

Introduction 

AWS Karpenter는 resource 할당을 최적화하고 비용을 절감할 수 있는 방법을 제공하는 매우 유연하고 확장 가능한 Auto Scaling 솔루션으로, 쿠버네티스 기본 기능인 Auto Scaler 와 비교해 뛰어난 장점을 지니고 있습니다. 오늘은 AWS Karpenter를 소개하고, 쿠버네티스 기본 기능인 Auto Scaler와 비교한 장점들을 설명하고, Kubernetes 클러스터 내에서 실제 설정 과정을 알아보겠습니다. 

 

What is AWS Karpenter ?

AWS Karpenter는 현재의 워크로드를 기반으로 클러스터 내 컴퓨팅 자원의 수량과 종류를 자동으로 조정하도록 설계되었습니다. 단순한 Node Scaling을 넘어, 필요에 따라  Application에 Resource를 제공하고 과도한 Provisioning을 방지하기 위해   node provisioning과 강제 종료 같은 기능을 제공합니다.

 

 

AWS Karpenter를 고려해야하는 이유 

- 빠른 Scaling : Karpenter는 몇 초 안에 노드를 프로비저닝하여 워크로드가 신속하게 필요한 자원을 확보할 수 있게 합니다.

 

- 비용 절감 및 최적화 : Karpenter는 올바른 유형과 수의 인스턴스를 프로비저닝함으로써 전체 클라우드 비용을 줄이는 데 도움을 줍니다. 유연한 스케줄링: Karpenter의 스케줄링 결정은 실시간 워크로드 요구, 자원 가용성 및 비용을 기반으로 하여 더 효율적인 자원 활용을 가능하게 합니다. AWS Karpenter를 사용할 시기 AWS Karpenter는 동적인 워크로드가 전통적인 스케일링 방법에 도전 과제를 제기하는 시나리오에서 특히 유용합니다. 고급 기능 덕분에 여러 상황에서 우수한 선택이 됩니다. 클라우드 지출을 최적화하려는 조직은 Karpenter로부터 큰 이점을 얻습니다. 인스턴스 유형과 크기의 지능형 선택을 통해 낭비를 최소화하고 과도한 프로비저닝이나 자원 비효율적 사용과 관련된 비용을 줄일 수 있습니다.

 

- 유연한 Workload : 예측할 수 없는 트래픽 급증이나 변동하는 처리 요구 사항이 있는 애플리케이션의 경우, Karpenter의 빠른 프로비저닝 기능이 자원을 실시간으로 효율적으로 스케일링하여 수요에 맞출 수 있습니다.

 

- 복잡한 Scheduling 요구: 특정 기능을 갖춘 인스턴스나 특정 가용 영역 내 인스턴스를 필요로 하는 워크로드의 경우, Karpenter의 유연한 스케줄링 및 프로비저닝 전략이 맞춤형 접근 방식을 제공합니다.

 

- Multi-Tenant 클러스터 :  여러 애플리케이션이나 팀이 클러스터를 공유하는 환경에서 Karpenter는 각 Tenant 의 요구를 충족하기 위해 동적으로 할당을 조정하여 공정한 Resorce 분배를 보장합니다.

 

 

AWS Karpenter 튜토리얼 

요구사항1  활성화 된 AWS 계정 

요구사항2  Karpenter가 배포 될EKS 클러스터 혹은 AWS 환경의 Self Managed Kubernetes 

 

 

1단계 : AWS CLI 설치 

AWS CLI가 아직 설치되지 않은 경우, 공식 AWS 문서에서 AWS CLI를 다운로드하고 설치합니다. 운영 체제에 맞는 설치 가이드를 따르세요.

AWS CLI를 액세스 자격 증명과 계정에 대한 기본 설정으로 구성합니다:

aws configure

프롬프트에 따라 AWS 액세스 키 ID, 시크릿 액세스 키, 기본 리전 이름 및 출력 형식을 입력합니다.

 

 

 

2단계: Karpenter Helm 차트 설치

Karpenter Helm 저장소 추가: Karpenter Helm 저장소를 Helm 클라이언트에 등록하고 Karpenter Helm 차트를 설치합니다

helm repo add karpenter https://charts.karpenter.sh/
helm repo update
helm install karpenter karpenter/karpenter --namespace karpenter --create-namespace --version <latest_version>

<latest_version>을 원하는 Karpenter 버전으로 대체합니다.

 

 

 

3단계: Karpenter를 위한 IAM 역할 구성

AWS Karpenter가 EC2 인스턴스를 관리하고 AWS 서비스와 효과적으로 상호 작용할 수 있도록 하기 위해 특정 IAM 역할을 구성하는 것이 중요합니다. 이 역할은 Karpenter가 Kubernetes 클러스터 요구 사항에 따라 인스턴스를 프로비저닝하고 종료하는 등의 작업을 수행할 수 있도록 합니다.

 

IAM 역할 생성

3-1 IAM 관리 콘솔 접속

AWS 관리 콘솔에 로그인한 후 IAM(Identity and Access Management) 서비스로 이동합니다. IAM에서 AWS 리소스에 대한 액세스를 안전하게 관리할 수 있습니다

 

3-2 역할 생성 시작

역할 생성: 사이드바에서 “Roles” 옵션을 선택한 다음 “Create Role”을 클릭하여 새 IAM 역할을 정의하는 프로세스를 시작합니다

 

3-3 신뢰 정책 정의

신뢰 엔터티로 AWS 서비스 선택: 이 역할을 맡을 엔터티 유형을 선택하라는 메시지가 표시됩니다. Karpenter의 경우, 엔터티 유형으로 “AWS service”를 선택합니다. 서비스 지정: "Elastic Kubernetes Service"와 "EC2"를 이 역할을 사용할 서비스로 선택하여 클러스터 관리에 필요한 작업을 허용합니다.

 

3-4 권한을 위한 정책 연결

Karpenter가 다른 AWS 서비스와 상호 작용하고 EC2 인스턴스를 관리하려면 특정 권한이 필요합니다:

AmazonEKSKarpenterPolicy: AWS는 인스턴스 시작 및 종료와 같은 기본 작업을 위한 Karpenter의 관리 정책인 AmazonEKSKarpenterPolicy를 제공합니다.

aws iam attach-role-policy --role-name KarpenterNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSKarpenterControllerPolicy

사용자 정의 정책 : Karpenter가 S3와 같은 다른 서비스와 상호 작용해야 하는 경우, 이러한 권한을 부여하는 추가 정책을 연결합니다.

 

aws iam create-policy --policy-name KarpenterAdditionalPermissions --policy-document file://karpenter-policy.json

karpenter-policy.json 파일이 필요한 정책 정의로 준비되어 있는지 확인하십시오.

 

3-5 역할 생성 완료 

필요한 정책을 연결한 후, 역할의 이름을 KarpenterNodeRole과 같이 의미 있는 이름으로 지정하고, 역할의 목적을 기억하기 위한 설명을 추가한 후 역할을 생성합니다.

 

IAM 역할을 Karpenter와 연결하기 IAM 역할을 구성한 후, 이 역할을 Kubernetes 클러스터에서 실행 중인 Karpenter와 연결하는 것이 중요합니다. 이 단계는 Karpenter가 필요한 권한으로 운영될 수 있도록 합니다.

 

3- 6 역할 ARN 가져오기

aws iam get-role --role-name KarpenterNodeRole --query 'Role.Arn' --output text

이 명령어는 역할의 ARN(Amazon Resource Name)을 가져오며, 이는 Karpenter 구성에 필요합니다. 

 

3-7 Karpenter 구성 업데이트

IAM 역할을 Karpenter와 연결하려면 역할의 ARN을 Karpenter의 프로비저너 설정에 포함시킵니다. 이를 통해 Karpenter가 클러스터의 리소스를 효과적으로 관리하는 데 필요한 권한을 갖추게 됩니다.

apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: default
spec:
  provider:
    instanceProfile: KARPENTER_NODE_INSTANCE_PROFILE
    clusterName: your-cluster-name
  requirements:
    - key: "kubernetes.io/arch"
      operator: In
      values: ["amd64"]

 

KARPENTER_NODE_INSTANCE_PROFILE을 KarpenterNodeRole과 연결된 실제 인스턴스 프로파일로 바꾸고 클러스터 이름을 정확히 지정합니다.

 

3-8 업데이트된 provisioner 배포

kubectl apply -f provisioner.yaml

 

 

 

4단계: Instance Type Provisioning 

AWS Karpenter는 워크로드 요구 사항에 동적으로 맞춰 Kubernetes 클러스터에서 인스턴스를 프로비저닝하는 과정을 간소화합니다. 이 단계에서는 이러한 요구 사항을 지정하는 Provisioner 리소스를 정의하여 Karpenter가 어떤 인스턴스를 프로비저닝할지 결정하도록 하는 방법을 안내합니다. 다음은 Provisioner 구성을 효과적으로 생성하고 배포하는 방법입니다.

 

Provisioner 리소스 정의 먼저 provisioner.yaml 파일을 만듭니다. 이 파일에는 Karpenter의 프로비저닝 작업을 안내하는 클러스터의 인스턴스 요구 사항 사양이 포함되어 있습니다. 아래는 이러한 구성이 어떻게 생겼는지에 대한 예시입니다.

apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
  name: default
spec:
  requirements:
    - key: "kubernetes.io/arch"
      operator: In
      values: ["amd64"]
  provider:
    instanceProfile: KARPENTER_NODE_INSTANCE_PROFILE
    subnetSelector:
      environment: production
    securityGroupSelector:
      karpenter: managed
  ttlSecondsAfterEmpty: 300

이 구성은 Karpenter가 amd64 아키텍처를 가진 인스턴스를 선택하고, 지정된 인스턴스 프로파일을 사용하도록 지시합니다. 또한 프로비저닝된 인스턴스에 사용할 서브넷 및 보안 그룹을 지정합니다.

 

4-1 필요에 따른 맞춤 설정 

- 아키텍처 조정

요구 사항에 따라 요구사항 섹션의 값을 ["arm64"]와 같이 변경하여 ARM 기반 인스턴스를 사용할 수 있습니다. 네트워크 매개변수 정의: subnetSelector 및 securityGroupSelector는 AWS 설정과 일치해야 하며, 인스턴스가 올바른 네트워크에서 시작되도록 합니다.

 

- TTL 설정 

ttlSecondsAfterEmpty 값은 노드가 더 이상 필요하지 않을 때 활성 상태를 유지하는 시간을 제어합니다. 비용 관리와 워크로드 요구에 따라 이 값을 조정합니다.

 

- 클러스터에 Provisioner 배포

kubectl apply -f provisioner.yaml

 

4-2 고급 설정 

 

- 인스턴스 프로비저닝에 대한 더 세부적인 제어를 위해

    - 다중 아키텍처 지원 애플리케이션이 둘 이상의 아키텍처와 호환되는 경우, 요구사항에 이를 나열하여 Karpenter가 가장 효율적인 옵션을 선택할 수 있게 합니다.

requirements:
  - key: "kubernetes.io/arch"
    operator: In
    values: ["amd64", "arm64"]

 

       - 스팟 인스턴스 활용  스팟 인스턴스를 포함하면 비용을 크게 줄일 수 있습니다. 최대 스팟 가격을 지정하여 가격이 적절할 때 Karpenter가 스팟 인스턴스를 사용하도록 합니다.

spec:
  provider:
    spotPrice: "0.067"

 

       - 인스턴스 유형 지정

특정 인스턴스 유형을 명시적으로 허용하거나 허용하지 않도록 설정하여 Karpenter가 요구 사항에 가장 적합한 인스턴스를 프로비저닝하도록 합니다.

 

 

       - 특정 인스턴스 유형 허용 방법 

spec:
  requirements:
    - key: "node.kubernetes.io/instance-type"
      operator: In
      values: ["m5.large", "m5.xlarge"]

 

 

       - 특정 인스턴스 유형 허용 안하는 상태 방법 

spec:
  requirements:
    - key: "node.kubernetes.io/instance-type"
      operator: NotIn
      values: ["t2.micro", "t2.small"]

 

 

마무리

이제 AWS Karpenter를 통해 Kubernetes 클러스터에서 인스턴스를 자동으로 확장하고 최적화하는 방법을 설정했습니다. 다음 단계는 다음과 같습니다. 이 단계를 통해 Karpenter를 효과적으로 설정하여 Kubernetes 클러스터에서 유연하고 비용 효율적인 인스턴스 관리가 가능해졌습니다. Karpenter의 설정이 완료되었으니 이제 실제로 워크로드를 배포할 차례입니다.  다음 글에서는 Karpenter를 활용하여 Kubernetes 클러스터에 워크로드를 배포하는 방법을 다룰 예정입니다!  다음 글을 통해 Karpenter가 어떻게 워크로드 요구 사항에 맞춰 클러스터의 리소스를 동적으로 확장하고 최적화하는지 확인해보세요. 

 

 

 

Referance : 

https://aws.amazon.com/ko/blogs/korea/how-to-use-trust-policies-with-iam-roles-html/