Scaling Application
Update : 2025.01.30
1. 애플리케이션 확장 (Scaling Application)
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이 항상 KarpenterNodePool에서 생성한 노드에 할당됩니다.
아래 명령어를 실행하여 애플리케이션을 배포합니다.
# 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
실행 결과
② 현재 클러스터의 노드 확인
현재 EKS 클러스터에 존재하는 노드를 확인하기 위해 새로운 터미널을 열어 eks-node-viewer를 실행합니다.
아래 명령어를 실행하여 현재 클러스터에 몇 개의 노드가 있는지 확인합니다.
앞서 생성한 eks-node-viewer, kube-ops-view, k9s 등을 활용합니다.
1.2 애플리케이션 확장 (Scale Application)
① Deployment 스케일링 (0 → 5 Replicas)
이제 Deployment를 5개의 Replica로 확장합니다.
실행 결과
② Karpenter 로그 확인
이제 Karpenter가 새로운 노드를 프로비저닝하는지 확인하기 위해 로그를 조회합니다.
아래 명령어를 실행하여 karpenter controller Pod의 로그에서 launched nodeclaim 메시지를 확인합니다.
로그 예시 (출력 결과)
③ 새로운 노드 생성 확인
eks-node-viewer를 실행 중인 터미널을 보면, 5세대 이상의 c6a.2xlarge 인스턴스 타입의 새로운 노드가 생성된 것을 확인할 수 있습니다.
또한 아래 명령어를 실행하여 Karpenter NodePool에서 관리하는 노드 목록을 조회할 수 있습니다.
출력 예시
이제 Karpenter가 새롭게 프로비저닝한 노드가 추가되었음을 확인할 수 있습니다.
④ 새롭게 추가된 노드에 Pod이 배치됨 확인
아래 k9s 또는 kubectl을 사용하여 새롭게 생성된 노드에 몇 개의 Pod이 배치되었는지 확인할 수 있습니다.
새롭게 생성된 노드에는 5개의 Pod이 배치된 것을 확인할 수 있습니다.
⑤ Karpenter가 생성한 노드의 메타데이터 확인
아래 명령어를 실행하여 Karpenter가 생성한 노드에 추가된 메타데이터(레이블)를 조회할 수 있습니다.
출력 예시
1.4 Node 축출
생성된 Pod를 replica를 0으로 축소합니다.
① Node 축출 확인
위의 로그를 통해 Karpenter에 의해 생성된 Node가 축출 되었는지 확인합니다. 아래는 예시입니다.
② 왜 노드는 삭제 되었는가?
아래에서 처럼 Node 삭제 만료기간이 "Never" 이므로 삭제 되지 않도록 설정되어 있습니다.
하지만 consolidationPolicy가 설정되어 있습니다.
📌 현재 설정
consolidationPolicy: WhenEmptyOrUnderutilized→ 노드가 비어있거나 활용률이 낮으면 자동 축소consolidateAfter: 30s→ 30초 후 즉시 축소
📌 동작 방식
Pod이 제거됨 → 해당 노드에 실행 중인 Pod이 없거나, 활용률이 낮아짐.
Karpenter가 자동 축소 실행 (
consolidationPolicy: WhenEmptyOrUnderutilized)30초 후 노드 삭제됨 (
consolidateAfter: 30s)로그에서 확인되는 이벤트
disrupting nodeclaim(s) via delete→ Karpenter가 노드 삭제 결정deleted node→ 노드 삭제 완료deleted nodeclaim→ NodeClaim 삭제 완료
🚀 즉, consolidationPolicy가 활성화되어 있기 때문에, Pod이 없어지면 자동으로 노드를 삭제하는 것입니다.
③ 노드 축출 방법은 아래에서 처럼 Karpenter 에서 활용 가능합니다.
자동 축출 (expireAfter)
expireAfter: 30s (30초 후 자동 제거)
비활성 노드 자동 제거 (consolidation)
consolidation: enabled: true
즉시 특정 노드 제거
kubectl delete node <NODE_NAME>
Pod이 없는 노드 자동 삭제 (ttlSecondsAfterEmpty)
ttlSecondsAfterEmpty: 60 (비어있으면 60초 후 제거)
위 설정을 적용하면 Karpenter가 더 빠르게 노드를 축출할 수 있습니다. 🚀
1.5 정리
이번 실습을 통해 Karpenter가 Pending 상태의 Pod을 감지하여 새로운 노드를 자동으로 생성하는 과정을 확인하였습니다.
이를 통해 Karpenter를 활용한 Kubernetes 클러스터의 자동 확장 기능을 효과적으로 운영할 수 있습니다. 🚀
Last updated
Was this helpful?