[EKS Study 5주차] EKS AutoScaling - Karpenter
- -
CloudNet@ 팀의 가시다님께서 Leading 하시는 AEWS Study 5주차 스터디 내용 정리
이번 포스팅에서는 EKS AutoScaling 중 Node 오토스케일링 기능인 Karpenter 에 대해 알아보겠습니다.
1. Karpenter
Karpenter 는 오픈소스 노드 수명 주기 관리 솔루션으로, 몇 초 만에 컴퓨팅 리소스를 제공할 수 있습니다.
기존 CA 의 단점인 느린 동작 시간과 비효율을 보완하는 솔루션이며 현재 AWS 에서 EKS 를 사용할 때 핵심 도구가 되어 가고 있습니다.
Karpenter 공식 문서
1.1. Karpenter 동작을 위한 AWS Resource 생성
Karpenter 설치는 공식 문서에 나와있는 방식으로 설치하겠습니다.
해당 CloudFormation 배포시 IAM Role, SQS 등의 리소스가 배포됩니다.
curl -fsSL https://karpenter.sh/"${KARPENTER_VERSION}"/getting-started/getting-started-with-karpenter/cloudformation.yaml > $TEMPOUT \
&& aws cloudformation deploy \
--stack-name "Karpenter-${CLUSTER_NAME}" \
--template-file "${TEMPOUT}" \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides "ClusterName=${CLUSTER_NAME}"
1.2. EKS 배포
eksctl create cluster -f - <<EOF
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: ${CLUSTER_NAME}
region: ${AWS_DEFAULT_REGION}
version: "1.24"
tags:
karpenter.sh/discovery: ${CLUSTER_NAME}
iam:
withOIDC: true
serviceAccounts:
- metadata:
name: karpenter
namespace: karpenter
roleName: ${CLUSTER_NAME}-karpenter
attachPolicyARNs:
- arn:aws:iam::${AWS_ACCOUNT_ID}:policy/KarpenterControllerPolicy-${CLUSTER_NAME}
roleOnly: true
iamIdentityMappings:
- arn: "arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterNodeRole-${CLUSTER_NAME}"
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
managedNodeGroups:
- instanceType: m5.large
amiFamily: AmazonLinux2
name: ${CLUSTER_NAME}-ng
desiredCapacity: 2
minSize: 1
maxSize: 10
iam:
withAddonPolicies:
externalDNS: true
EOF
설치 후, IRSA 매핑을 확인해봅니다.
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
Karpenter 가 리소스를 사용하기 위한 auth 또한 적용이 되어 있습니다.
kubectl describe cm -n kube-system aws-auth
1.3. Karpenter 설치
Karpenter 설치를 위한 변수를 지정해줍니다.
export CLUSTER_ENDPOINT="$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output text)"
export KARPENTER_IAM_ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/${CLUSTER_NAME}-karpenter"
Karpenter 는 Helm 설치가 가능합니다.
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter --version ${KARPENTER_VERSION} --namespace karpenter --create-namespace \
--set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=${KARPENTER_IAM_ROLE_ARN} \
--set settings.aws.clusterName=${CLUSTER_NAME} \
--set settings.aws.defaultInstanceProfile=KarpenterNodeInstanceProfile-${CLUSTER_NAME} \
--set settings.aws.interruptionQueueName=${CLUSTER_NAME} \
--set controller.resources.requests.cpu=1 \
--set controller.resources.requests.memory=1Gi \
--set controller.resources.limits.cpu=1 \
--set controller.resources.limits.memory=1Gi \
--wait
설치가 정상적인지 배포 리소스를 확인합니다.
kubectl get all -n karpenter
kubectl get cm -n karpenter karpenter-global-settings -o jsonpath={.data} | jq
kubectl get crd | grep karpenter
2. Karpenter 사용
2.1. Karpenter Provisioner 배포
Karpenter 는 AWS AutoScaling Group 을 사용하지 않습니다.
즉, AWS ASG 를 위한 Launch Template (시작템플릿)을 필요로 하지 않습니다.
대신에, Node Scaling 을 위해 시작템플릿을 대체할 리소스가 필요한데 그것이 바로 Provisioner 입니다.
아래 Yaml 설정은 Spot 인스턴스 구성으로 서브넷과 보안그룹에 태그가 적용된 곳에 노드를 배포하겠다는 설정입니다.
또한 30초간 노드에 리소스가 없으면 삭제하는 구성이 적용되어 있습니다.
cat <<EOF | kubectl apply -f -
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: default
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"]
limits:
resources:
cpu: 1000
providerRef:
name: default
ttlSecondsAfterEmpty: 30
---
apiVersion: karpenter.k8s.aws/v1alpha1
kind: AWSNodeTemplate
metadata:
name: default
spec:
subnetSelector:
karpenter.sh/discovery: ${CLUSTER_NAME}
securityGroupSelector:
karpenter.sh/discovery: ${CLUSTER_NAME}
EOF
2.2. Test Deployment 배포
Replica 가 0인 Deployment 를 배포합니다.
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: inflate
spec:
replicas: 0
selector:
matchLabels:
app: inflate
template:
metadata:
labels:
app: inflate
spec:
terminationGracePeriodSeconds: 0
containers:
- name: inflate
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
resources:
requests:
cpu: 1
EOF
이후, Replica 개수를 5로 늘립니다.
kubectl scale deployment inflate --replicas 5
kubectl get node --label-columns=eks.amazonaws.com/capacityType,karpenter.sh/capacity-type,node.kubernetes.io/instance-type
2.3. Consolidation
노드의 리소스 사용량을 확인하고 자동으로 노드 사용량을 최적화시켜 주는 설정입니다.
우선 기존 정책이 배포되어 있다면 삭제합니다.
kubectl delete provisioners default
On-demand 노드를 배포하는 카펜터 프로비저너입니다.
cat <<EOF | kubectl apply -f -
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: default
spec:
consolidation:
enabled: true
labels:
type: karpenter
limits:
resources:
cpu: 1000
memory: 1000Gi
providerRef:
name: default
requirements:
- key: karpenter.sh/capacity-type
operator: In
values:
- on-demand
- key: node.kubernetes.io/instance-type
operator: In
values:
- c5.large
- m5.large
- m5.xlarge
EOF
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: inflate
spec:
replicas: 0
selector:
matchLabels:
app: inflate
template:
metadata:
labels:
app: inflate
spec:
terminationGracePeriodSeconds: 0
containers:
- name: inflate
image: public.ecr.aws/eks-distro/kubernetes/pause:3.7
resources:
requests:
cpu: 1
EOF
Node Scaling 을 확인해봅니다.
kubectl scale deployment inflate --replicas 12
Node 병합을 확인해봅니다.
kubectl scale deployment inflate --replicas 5
Karpenter 를 사용하면 기존에 보수적으로 운영하던 EKS 노드를 굉장히 타이트하게 사용가능합니다.
다만, 너무 타이트하게 사용하다 보니 필요할 경우 오버 프로비저닝을 해야할 때도 있습니다.
또한 특정 시간에 트래픽이 몰릴 것으로 예상될 때, 이전 포스팅의 이벤트기반의 KEDA 와 Karpenter 를 같이 사용하는 경우도 존재합니다.
참고 문서
https://www.eksworkshop.com/docs/autoscaling/compute/karpenter/consolidation/
'AWS > EKS' 카테고리의 다른 글
[AWS/EKS] IAM Group 을 통한 EKS 인증 관리 (0) | 2023.06.03 |
---|---|
[AWS/EKS] EKS 인증/인가 파헤치기 (4) | 2023.06.02 |
[EKS Study 5주차] EKS AutoScaling - CA (0) | 2023.05.28 |
[EKS Study 5주차] EKS AutoScaling - VPA (0) | 2023.05.28 |
[EKS Study 5주차] EKS AutoScaling - KEDA (0) | 2023.05.28 |