Karpenter는 스케일링이 필요한 unscheduled pods를 감지하여 자동으로 노드를 확장하는 기능을 제공합니다. Kubernetes에서 새로운 Pod이 생성되면, Kubernetes 스케줄러는 해당 Pod을 클러스터 내 노드에 배치합니다. 하지만 적절한 노드가 없을 경우, 해당 Pod은 Pending 상태로 남아있게 됩니다.
Karpenter는 이러한 Pending 상태의 Pod을 감지하고, 요구 사항을 충족하는 새로운 노드를 프로비저닝하여 클러스터를 자동으로 확장합니다.
이 실습에서는 Karpenter가 애플리케이션 Pod을 스케일링할 때 새로운 노드를 생성하는 과정을 실습해 보겠습니다.
1.1 애플리케이션 배포 (Deploy Application)
① 애플리케이션 배포 (0개의 Replica)
먼저, Replica 수가 0인 상태에서 애플리케이션을 배포합니다.
아래 Deployment 스펙을 확인하면 다음과 같은 설정이 포함되어 있습니다.
컨테이너의 CPU 요청 값이 1로 설정됨
NodePool을 생성할 때 추가한 "eks-team: my-team" 레이블을 nodeSelector에 추가
→ 이렇게 설정하면, 생성된 Pod이 항상 Karpenter NodePool에서 생성한 노드에 할당됩니다.
아래 명령어를 실행하여 애플리케이션을 배포합니다.
# Karpenter 관련 작업 디렉토리로 이동
cd ~/environment/karpenter
kubectl create namespace karpenter-test
# basic-deploy.yaml 파일을 생성
cat <<EoF> ~/environment/karpenter/basic-deploy.yaml
apiVersion: apps/v1 # API 버전 (Kubernetes에서 사용되는 앱 관련 리소스 정의)
kind: Deployment # 배포(Deployment) 리소스 정의
metadata:
name: inflate # Deployment 이름 지정
namespace: karpenter-test # Deployment가 배포될 네임스페이스 지정
spec:
replicas: 0 # 초기 Pod 개수를 0으로 설정 (추후 스케일링할 예정)
selector:
matchLabels:
app: inflate # 이 Deployment가 관리할 Pod의 label 지정
template: # Pod 템플릿 정의
metadata:
labels:
app: inflate # Pod에 부여될 label (Deployment의 selector와 일치해야 함)
spec:
terminationGracePeriodSeconds: 0 # Pod 종료 대기 시간을 0으로 설정 (즉시 종료)
containers:
- name: inflate # 컨테이너 이름
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7 # 컨테이너 이미지 지정 (pause 컨테이너 사용)
resources:
requests:
cpu: 1 # 이 컨테이너가 요청하는 CPU 리소스 (1 vCPU)
nodeSelector:
eks-team: my-team # 특정 노드 그룹(eks-team: my-team)에서만 실행되도록 지정
EoF
# 위에서 생성한 Deployment를 Kubernetes 클러스터에 적용
kubectl apply -f ~/environment/karpenter/basic-deploy.yaml
실행 결과
deployment.apps/inflate created
② 현재 클러스터의 노드 확인
현재 EKS 클러스터에 존재하는 노드를 확인하기 위해 새로운 터미널을 열어 eks-node-viewer를 실행합니다.
아래 명령어를 실행하여 현재 클러스터에 몇 개의 노드가 있는지 확인합니다.
kubectl get -n nodes
앞서 생성한 eks-node-viewer, kube-ops-view, k9s 등을 활용합니다.
eks-node-viewer를 실행 중인 터미널을 보면, c6a.2xlarge 인스턴스 타입의 새로운 노드가 생성된 것을 확인할 수 있습니다.
또한 아래 명령어를 실행하여 Karpenter NodePool에서 관리하는 노드 목록을 조회할 수 있습니다.
kubectl get nodes -l eks-team=my-team
출력 예시
$ kubectl get nodes -l eks-team=my-team
NAME STATUS ROLES AGE VERSION
ip-10-11-77-170.ap-northeast-2.compute.internal Ready <none> 117s v1.29.12-eks-aeac579
이제 Karpenter가 새롭게 프로비저닝한 노드가 추가되었음을 확인할 수 있습니다.
④ 새롭게 추가된 노드에 Pod이 배치됨 확인
아래 k9s 또는 kubectl을 사용하여 새롭게 생성된 노드에 몇 개의 Pod이 배치되었는지 확인할 수 있습니다.