NodePool 설정을 하기 전에 Karpenter Controller Pod의 배치 설정을 알아야한다.
Karpenter Controller Pod는 Karpenter가 스스로 생성한 워커노드에 배치되면 안된다.
운 나쁘게 자기 자신이 위치한 EC2 노드를 스스로 Terminate 하게 될 경우, 클러스터 전체의 노드 프로비저닝이 멈출 수 있기 때문이다.
이러한 이유로 Karpenter Controller Pod는 기존 ASG 기반에서 운영되는 노드 그룹에 배치되어야 한다.
클러스터에 Karpenter를 설치해서 사용하더라도 최소 1개의 노드 그룹은 반드시 필요하다.
적절한 파드 분배 (선택 사항) : 운영 및 유지에 필요한 핵심 파드들은 nodeAffinity를 사용해 기존 ASG로 운영되는 노드 그룹에 배치하는 걸 권장한다.
기존 노드 그룹 ASG에 배치 : Karpenter, coredns, metrics-server, prometheus, grafana
Karpenter 노드 그룹에 배치 : Application node, Application pod
5. Karpenter.yaml 설정
헬름으로 설치 후 생긴 karpenter.yaml에서 nodeSelector 부분을 수정해야 한다.
위 설명한 배치 원칙에 따라 기존 ASG에 배치될 수 있도록 수정할 것이다.
수정 전
nodeSelector:
kubernetes.io/os: linux
# The template below patches the .Values.affinity to add a default label selector where not specificed
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: karpenter.sh/nodepool
operator: DoesNotExist
수정 후
nodeSelector:
kubernetes.io/os: linux
alpha.eksctl.io/nodegroup-name: autoscaler-ng
# The template below patches the .Values.affinity to add a default label selector where not specificed
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: karpenter.sh/nodepool
operator: DoesNotExist
기존 ASG의 레이블을 지정해주면 된다.
6. NodePool 생성
쿠버네티스 클러스터의 워크로드 요구 사항에 따라 EC2 인스턴스(노드)를 동적으로 프로비저닝하고 관리하는 방식을 설정하는 개념이다.
Karpenter가 만든 노드에서 실행할 수 있는 Pod를 제한하기 위해 taint를 정의한다.
NodePool은 노드를 시작하는 데 사용되는 리소스를 검색하기 위해 securityGroupSelectorTerms
를 사용한다.
NodeGroup(노드 그룹) 대신 Provisioner라는 추상화 계층을 사용한다.
AWS의 EKS Managed NodeGroup처럼 고정된 노드 풀 대신, Karpenter는 필요한 노드만 생성하고 필요 없을 때 제거하는 방식으로 동작한다.
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: nodepool
namespace: karpenter
spec:
cluster:
name: eks
template:
metadata:
labels:
nodegroup: karpenter # 노드에 추가할 레이블
alpha.eksctl.io/nodegroup-name: karpenter-ng
name: nodepool
namespace: karpenter
spec:
template:
spec:
requirements:
- key: kubernetes.io/arch
operator: In
values: ["amd64"]
- key: kubernetes.io/os
operator: In
values: ["linux"]
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand"]
- key: karpenter.k8s.aws/instance-family
operator: In
values: ["t2"]
- key: karpenter.k8s.aws/instance-size
operator: In
values: ["small", "medium"]
- key: topology.kubernetes.io/zone
operator: In
values: ["ap-northeast-2a", "ap-northeast-2b"]
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: ec2nodeclass
expireAfter: 720h
limits:
cpu: 5
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 1m
spec.template.metadata.lables
은 Karpenter가 생성한 노드에 추가할 레이블을 지정할 수 있다.
kubernetes.io/arch
: 아키텍처. amd64(x86 기반 CPU) 요구
kubernetes.io/os
: 운영 체제. linux 요구
karpenter.sh/capacity-type
: EC2 용량 유형. on-demand(온디멘드 인스턴스) 요구
karpenter.k8s.aws/instance-family
: EC2 인스턴스의 패밀리. t2 시리즈 인스턴스 허용
karpenter.k8s.aws/instance-size
: EC2 인스턴스의 사이즈. small, medium 허용
topology.kubernetes.io/zone
: 가용영역. 서울 리전 허용
nodeClassRef
: 이 NodePool을 사용할 EC2NodeClass를 참조한다.
group
: 이 리소스가 속한 API 그룹
kind
: 참조할 리소스의 종류
name
: 참조할 EC2NodeClass의 이름
expireAfter
: 720h : 생성된 노드의 최대 생존 기간 (30days * 24hours → 30일이 지나면 노드가 만료되어 카펜터가 제거 가능)
disruption
: 노드 통합(Consolidation) 정책 설정
consolidationPolicy: WhenEmptyOrUnderutilized
: 카펜터가 언제 노드를 통합할지 결정. 노드가 비어 있거나 과소 사용될 떄 통합
consolidateAfter: 1m
: 통합 작업을 시작하기 전에 대기할 시간
7. NodeClass 생성
karpenter가 EC2 인스턴스를 자동으로 프로비저닝할 때 사용할 노드 그룹의 속성을 정의한다.
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: ec2nodeclass
namespace: karpenter
spec:
amiFamily: AL2
role: "KarpenterNodeRole-eks"
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: "eks"
securityGroupSelectorTerms:
- tags:
karpenter.sh/discovery: "eks"
amiSelectorTerms:
- id: "<ami images>"
tags:
nodegroup: karpenter
alpha.eksctl.io/nodegroup-name: karpenter-ng
amiFamily: AL2
: Karpenter가 생성한 인스턴스가 사용할 AMI 계열 지정
role: "KarpenterNodeRole-eks"
: Karpenter가 프로비저닝한 EC2 인스턴스에 부여할 IAM 역할, 노드를 생성하고 관리하는 데 필요한 권한이 포함되어야 한다.
subnetSelectorTerms
: 노드를 프로비저닝할 서브넷을 선택하기 위해 사용할 태그, 지정 태그가 붙은 서브넷에서만 노드를 생성한다.
securityGroupSelectorTerms
: EC2 인스턴스에 연결할 보안 그룹을 선택하는 태그, 지정 태그가 붙은 보안 그룹을 사용한다.
amiSelectorTerms
: 노드에 사용할 AMI을 지정한다.
8. CRD 설치
nodepool, nodeclass 설치
k create -f \
"https://raw.githubusercontent.com/aws/karpenter-provider-aws/v${KARPENTER_VERSION}/pkg/apis/crds/karpenter.sh_nodepools.yaml"
k create -f \
"https://raw.githubusercontent.com/aws/karpenter-provider-aws/v${KARPENTER_VERSION}/pkg/apis/crds/karpenter.k8s.aws_ec2nodeclasses.yaml"
k get crds | grep -E "nodepools|nodeclasses"
배포 및 확인
k apply -f karpenter.yml
k get pods -n karpenter
k describe pod <POD_NAME> -n karpenter
'Kubernetes' 카테고리의 다른 글
[k8s] EKS에서 Karpenter 사용하기 (1) (0) | 2025.01.05 |
---|---|
[k8s] karpenter란? (2) | 2025.01.04 |