brunch

EKS 8탄-11. EKS Karpenter-11/17

EKS 8탄 - 5주차

by Master Seo

본 내용은 CloudNet 주말 스터디 내용을 참고로 작성되었습니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863

계속 테스트하며 내용과 설명이 업데이트됩니다.


목표

카펜터 이해

EKS Node Viewer 설치 - 커맨드 라인에서 리소스 보기



카펜터

오픈 소스 고성능 Kubernetes 클러스터 오토스케일러(CA)


무신사 사례 )

https://youtu.be/FPlCVVrCD64




<1> 카펜터란?

<2> 실습 환경 배포 - 작업용 EC2 - 실습1

<3> EKS Node Viewer 설치 - 커맨드 라인에서 리소스 보기

<4> 환경 변수 확인 - 필수

<5> 옵션 : ExternalDNS, kube-ops-view 유틸

<6> Create Provisioner 제공자 =정책

<7> Add optional monitoring with Grafana (선택)- 파드오류,재정리 필요

<8> Consolidation 강화하다.통합하다.

<9> 실습 리소스 삭제




<1> 카펜터란?


1

K8S Native AutoScaler


오픈소스 노드 수명 주기 관리 솔루션

몇 초 만에 컴퓨팅 리소스 제공


https://ec2spotworkshops.com/karpenter.html

100 카펜터.png



오픈 소스 고성능 Kubernetes 클러스터 오토스케일러

https://aws.amazon.com/ko/blogs/korea/introducing-karpenter-an-open-source-high-performance-kubernetes-cluster-autoscaler/





2

Cluster Autoscaler 문제점 ?

AWS를 사용하는 Kubernetes 고객 중 거의 절반이 Kubernetes Cluster Autoscaler를 사용하여 클러스터 Auto Scaling을 구성하기가 어렵고 구성할 수 있는 범위가 제한적

스케일링 속도가 매우 느림


그러면 카펜터는 ?

빠르다.



3

카펜터 특징 ?

AMI를 지정안하면 가종 최신의 AMI로 증설된다.

Pod에 적합한 인스턴스 중 가장 저렴한 인스턴스로 증설 됩니다.

자동으로 PV가 존재하는 서브넷에 노드를 만든다. 스토리지와 같은 서브넷에 노드를 증설.

노드를 줄여도 다른 노드에 충분한 여유가 있다면 옵션을 통해 자동으로 정리해준다. ttlSecondsAfterEmpty

큰 노드 하나가 작은 노드 여러개 보다 비용이 저렴하다면 큰 노드 하나로 자동으로 합쳐준다.

노드 최적화를 통한 비용 절감이 된다.



4

카펜터(목수) 구성과 작동 방식


구성



5

작동 방식 ?

모니터링 → 스케줄링 안된 Pod 발견 → 어떤 노드에 할당되어야 할지 스펙 평가 → 생성 ⇒ 노드를 증설하는것을 Provisioning


모니터링 → 비어있는 노드 발견 → 자동으로 제거한다. ⇒ 노드를 제거하는것을 Deprovisioning



6

참고 자료


Karpenter is an open-source node provisioning project built for Kubernetes.

https://karpenter.sh/v0.27.5/



https://aws.amazon.com/ko/blogs/aws/introducing-karpenter-an-open-source-high-performance-kubernetes-cluster-autoscaler/


Running efficient Kubernetes clusters on Amazon EC2 with Karpenter


https://file.notion.so/f/s/dc43285b-5aed-4cf3-bfc2-509b2a67fbb4/CON405_How-to-monitor-and-reduce-your-compute-costs.pdf?id=2ea72faa-7248-4feb-8710-d143db7607a8&table=block&spaceId=a6af158e-5b0f-4e31-9d12-0d0b2805956a&expirationTimestamp=1685067748232&signature=N5l3XS4XhXaL2ZhKmbfJSedzJDWzLNclHzoAp9mCZak&downloadName=CON405_How-to-monitor-and-reduce-your-compute-costs.pdf






<2> 실습 환경 배포 - 작업용 EC2 - 실습1



1

aws console login

https://console.aws.amazon.com/



서울리전으로 변경한다.


ec2-key pair 필요

access-key/secret key 필요

도메인 하나 준비



2

# YAML 파일 다운로드

EKS를 만들진 않는다. 작업용 EC2만 만들어지는 yaml 파일이다.


Stack name :

myeks2


curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/karpenter-preconfig.yaml



(1분 걸림)


AWSTemplateFormatVersion: '2010-09-09'


Metadata:

AWS::CloudFormation::Interface:

ParameterGroups:

- Label:

default: "<<<<< Deploy EC2 >>>>>"

Parameters:

- KeyName

- MyIamUserAccessKeyID

- MyIamUserSecretAccessKey

- SgIngressSshCidr

- MyInstanceType

- LatestAmiId

- ClusterBaseName


Parameters:

KeyName:

Description: Name of an existing EC2 KeyPair to enable SSH access to the instances. Linked to AWS Parameter

Type: AWS::EC2::KeyPair::KeyName

ConstraintDescription: must be the name of an existing EC2 KeyPair.

MyIamUserAccessKeyID:

Description: IAM User - AWS Access Key ID (won't be echoed)

Type: String

NoEcho: true

MyIamUserSecretAccessKey:

Description: IAM User - AWS Secret Access Key (won't be echoed)

Type: String

NoEcho: trueResources:

# VPC

EksVPC:

Type: AWS::EC2::VPC

Properties:

CidrBlock: 172.30.0.0/16

EnableDnsSupport: true

EnableDnsHostnames: true

Tags:

- Key: Name

Value: !Sub ${ClusterBaseName}-VPC


# PublicSubnets

PublicSubnet1:

Type: AWS::EC2::Subnet

Properties:

AvailabilityZone: ap-northeast-2a

CidrBlock: 172.30.1.0/24

VpcId: !Ref EksVPC

MapPublicIpOnLaunch: true

Tags:

UserData:

Fn::Base64:

!Sub |

#!/bin/bash

hostnamectl --static set-hostname "${ClusterBaseName}-bastion-EC2"


# Config convenience

echo 'alias vi=vim' >> /etc/profile

echo "sudo su -" >> /home/ec2-user/.bashrc


# Change Timezone

sed -i "s/UTC/Asia\/Seoul/g" /etc/sysconfig/clock

ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime


# Install Packages

cd /root

yum -y install tree jq git htop go


# Install kubectl & helm

#curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.26.2/2023-03-17/bin/linux/amd64/kubectl

curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.25.7/2023-03-17/bin/linux/amd64/kubectl

install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash


# Install eksctl

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp

mv /tmp/eksctl /usr/local/bin


# Install aws cli v2

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

unzip awscliv2.zip >/dev/null 2>&1

sudo ./aws/install

complete -C '/usr/local/bin/aws_completer' aws

echo 'export AWS_PAGER=""' >>/etc/profile

export AWS_DEFAULT_REGION=${AWS::Region}

echo "export AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION" >> /etc/profile


# Install YAML Highlighter


# IAM User Credentials

export AWS_ACCESS_KEY_ID=${MyIamUserAccessKeyID}

export AWS_SECRET_ACCESS_KEY=${MyIamUserSecretAccessKey}

export AWS_DEFAULT_REGION=${AWS::Region}

export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)

echo "export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" >> /etc/profile

echo "export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" >> /etc/profile

echo "export AWS_REGION=$AWS_DEFAULT_REGION" >> /etc/profile

echo "export AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION" >> /etc/profile

echo "export ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)" >> /etc/profile

echo "export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)" >> /etc/profile




3

(선택)

CLI로 생성시

# CloudFormation 스택 배포

myeks2 로 변경되었다.


예시) aws cloudformation deploy --template-file karpenter-preconfig.yaml --stack-name myeks2 --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 MyIamUserAccessKeyID=AKIA5... MyIamUserSecretAccessKey='CVNa2...' ClusterBaseName=myeks2 --region ap-northeast-2



4

EC2로 로그인







<3> eks-node-viewer 설치 - 커맨드 라인에서 리소스 보기



1

노드 할당 가능 용량과 요청 request 리소스 표시이다.

실제 파드 리소스 사용량이 보이는건 아니다.


https://github.com/awslabs/eks-node-viewer



2

eks-node-viewer 설치


https://brunch.co.kr/@topasvga/3296





<4> 환경 변수 확인 - 필수


설치 메뉴얼

https://karpenter.sh/v0.27/getting-started/getting-started-with-karpenter/



1

# 환경변수 정보 확인

export CLUSTER_NAME=myeks2

export | egrep 'ACCOUNT|AWS_|CLUSTER' | egrep -v 'SECRET|KEY'



# 환경변수 설정

export KARPENTER_VERSION=v0.27.5

export TEMPOUT=$(mktemp)

AWS_ACCOUNT_ID=451032684083


echo $KARPENTER_VERSION $CLUSTER_NAME $AWS_DEFAULT_REGION $AWS_ACCOUNT_ID $TEMPOUT

--------------------------------------------------------------------

v0.27.5 myeks2 ap-northeast-2 476286675138 /tmp/tmp.QOU73aDEKI

// 5개가 다 나와야 함.



3

파게이트에서 사용할 IAM 정책 등 생성이 필요하다.


# CloudFormation 스택으로 IAM Policy, Role, EC2 Instance Profile 생성 :


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}"


-------------------------------------------------

Waiting for changeset to be created..

Waiting for stack create/update to complete

Successfully created/updated stack - Karpenter-myeks2


(5분 정도 소요)

// 여러번 테스트 할때 role이 남아 있어 롤백이 된다.

// 이경우, 다음 과정으로 넘어가면 된다.



확인



CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`

echo $CERT_ARN


echo $MyDomain


MyDomain=masterseo0.link



3

# 클러스터 생성

: myeks2 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


## Optionally run on fargate

# fargateProfiles:

# - name: karpenter

# selectors:

# - namespace: karpenter

EOF


(20분 걸림)



설명 ?

// auto 디스커버리를 위해 태그가 필요하다.

tags:

karpenter.sh/discovery: ${CLUSTER_NAME}


// irsa 세팅

// iam 매핑



// IRSA

serviceAccounts:

- metadata:

name: karpenter

namespace: karpenter

roleName: ${CLUSTER_NAME}-karpenter

attachPolicyARNs:

- arn:aws:iam::${AWS_ACCOUNT_ID}:policy/KarpenterControllerPolicy-${CLUSTER_NAME}

roleOnly: true



managedNodeGroups:

관리형 노드 그룹 사용함.

desiredCapacity: 2


https://vclock.kr/timer/#countdown=00:02:00&enabled=0&seconds=108&sound=xylophone&loop=1



4

# EC2 인스턴스 모니터링

while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --output text | sort; echo "------------------------------" ;date; sleep 1; done



(노드 서버 생성 1분후 노드로 kubectl 명령어로 조회가 가능하다.)

while true ; do kubectl get nodes ;echo "-----------";date; sleep 2 ;done



5

eksctl get cluster

----------------------------

NAME REGION EKSCTL CREATED

myeks2 ap-northeast-2 True


eksctl get nodegroup --cluster $CLUSTER_NAME

eksctl get iamidentitymapping --cluster $CLUSTER_NAME

eksctl get iamserviceaccount --cluster $CLUSTER_NAME

eksctl get addon --cluster $CLUSTER_NAME





6

# [터미널1] 새로 띠운다.

eks-node-viewer


cd ~/go/bin && ./eks-node-viewer



7

# k8s 확인

kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone


kubectl get pod -n kube-system -owide


kubectl describe cm -n kube-system aws-auth




8

k ns default


# 카펜터 설치를 위한 환경 변수 설정 및 확인


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"



확인


echo $CLUSTER_ENDPOINT $KARPENTER_IAM_ROLE_ARN

-----------------------------------------------

https://327E394DA22584FD032EBB751DEEFBAA.gr7.ap-northeast-2.eks.amazonaws.com arn:aws:iam::476286675138:role/myeks2-karpenter

// 클러스터 엔드포인트과 IAM Role ARN 정보 2개가 보이는게 정상이다.




9

# EC2 Spot Fleet 사용을 위한 service-linked-role 생성 확인

: 만들어있는것을 확인하는 거라 아래 에러 출력이 정상!


aws iam create-service-linked-role --aws-service-name spot.amazonaws.com || true


# role이 만들어졌으므로 아래 결과로 나오면 정상이다.

# If the role has already been successfully created, you will see:

An error occurred (InvalidInput) when calling the CreateServiceLinkedRole operation: Service role name AWSServiceRoleForEC2Spot has been taken in this account, please try a different suffix.



10

# docker logout : Logout of docker to perform an unauthenticated pull against the public ECR

docker logout public.ecr.aws



11

# karpenter 설치


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


(1분)



12

# 확인

kubectl get-all -n karpenter

kubectl get all -n karpenter

kubectl get cm -n karpenter karpenter-global-settings -o jsonpath={.data} | jq

kubectl get crd | grep karpenter




<5> 옵션 : ExternalDNS, kube-ops-view 유틸



1

watch로 모니터링하자.

watch -d kubectl get deploy,svc,pods -A




2

# ExternalDNS

MyDomain=<자신의 도메인>

echo "export MyDomain=<자신의 도메인>" >> /etc/profile


MyDomain=masterseo1.link

echo "export MyDomain=masterseo1.link" >> /etc/profile


MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)


echo $MyDomain, $MyDnzHostedZoneId


curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml


MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -



3

# kube-ops-view


helm repo add geek-cookbook https://geek-cookbook.github.io/charts/


helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system


kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'


kubectl annotate service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=kubeopsview.$MyDomain"


echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=1.5"


(2분 걸림)



4

8080 포트로 접속 하세요


http://kubeopsview.masterseo1.link:8080


50 8080.png





<6> Create Provisioner 제공자 =정책


Provisioner라는 K8S 커스텀 리소스가 ASG 를 대체한다.

오토스케일링 그룹을 대체한다.

kind Provisioner

시작 템플릿이 없다.

보안 그룹과 서브넷은 필수이다.

태그를 기반으로 적용하는 방식이 있다.



1

# 프로비저너를 하나 만들어보자. = 정책

내용은 ?

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

# 확인

kubectl get awsnodetemplates,provisioners

----------------------------------------------------

NAME AGE

awsnodetemplate.karpenter.k8s.aws/default 52s


NAME AGE

provisioner.karpenter.sh/default 52s




<7> Add optional monitoring with Grafana (선택)- 파드오류,재정리 필요


1

https://grafana.com/grafana/dashboards/?search=karpenter



2

#

helm repo add grafana-charts https://grafana.github.io/helm-charts


helm repo add prometheus-community https://prometheus-community.github.io/helm-charts


helm repo update


kubectl create namespace monitoring



3

# 프로메테우스 설치


curl -fsSL https://karpenter.sh/"${KARPENTER_VERSION}"/getting-started/getting-started-with-karpenter/prometheus-values.yaml | tee prometheus-values.yaml


helm install --namespace monitoring prometheus prometheus-community/prometheus --values prometheus-values.yaml --set alertmanager.enabled=false



4

# 그라파나 설치


curl -fsSL https://karpenter.sh/"${KARPENTER_VERSION}"/getting-started/getting-started-with-karpenter/grafana-values.yaml | tee grafana-values.yaml


helm install --namespace monitoring grafana grafana-charts/grafana --values grafana-values.yaml --set service.type=LoadBalancer



5

# admin 암호

kubectl get secret --namespace monitoring grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo



# 그라파나 접속

kubectl annotate service grafana -n monitoring "external-dns.alpha.kubernetes.io/hostname=grafana.$MyDomain"


echo -e "grafana URL = http://grafana.$MyDomain"



k get svc -A

로드 밸런서 URL로 접속 하라..

// 그라파나로 집속이 안된다.!!! 확인 요망.



100 gra.png






admin

추출한 암호



대시보드 추천 3개

15757

17900

15172




6

# pause 파드 1개에 CPU 1개 최소 보장 할당.

리플리카가 0인 pause pod 배포


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

kubectl scale deployment inflate --replicas 5


kubectl logs -f -n karpenter -l app.kubernetes.io/name=karpenter -c controller



7

Spot으로 생김




7

# 스팟 인스턴스 확인!


aws ec2 describe-spot-instance-requests --filters "Name=state,Values=active" --output table



kubectl get node -l karpenter.sh/capacity-type=spot -o jsonpath='{.items[0].metadata.labels}' | jq



kubectl get node --label-columns=eks.amazonaws.com/capacityType,karpenter.sh/capacity-type,node.kubernetes.io/instance-type

----------------------------------------------------------------------------

ip-192-168-165-220.ap-northeast-2.compute.internal Ready <none> 2m37s v1.24.13-eks-0a21954 spot c5a.2xlarge

ip-192-168-57-91.ap-northeast-2.compute.internal Ready <none> 13m v1.24.13-eks-0a21954 ON_DEMAND m5.large

ip-192-168-75-253.ap-northeast-2.compute.internal Ready <none> 13m v1.24.13-eks-0a21954 ON_DEMAND m5.large




8

Scale down deployment :

ttlSecondsAfterEmpty 30초


# Now, delete the deployment.

// After 30 seconds (ttlSecondsAfterEmpty), Karpenter should terminate the now empty nodes.


kubectl delete deployment inflate

kubectl logs -f -n karpenter -l app.kubernetes.io/name=karpenter -c controller


30초 기다리다, 아무일도 안하네.. 삭제 함.






<8> Consolidation 강화하다.통합하다.


노드의 리소스 사용량을 확인하고 자동으로 노드 사용량을 최적화 해준다.


1

https://www.eksworkshop.com/docs/autoscaling/compute/karpenter/consolidation/


https://aws.amazon.com/ko/blogs/containers/optimizing-your-kubernetes-compute-costs-with-karpenter-consolidation/


https://ec2spotworkshops.com/karpenter/050_karpenter/consolidation.html




2

# 기존의 정책은 삭제한다.

kubectl delete provisioners default


//정책을 삭제하면 노드 1개도 사라진다.

// SPOT이 사라진다.


3

// 새 정책 생성


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


kubectl scale deployment inflate --replicas 12



kubectl logs -f -n karpenter -l app.kubernetes.io/name=karpenter -c controller


노드가 빠르게 증설된다!!


5

# 인스턴스 확인

# This changes the total memory request for this deployment to around 12Gi,

# which when adjusted to account for the roughly 600Mi reserved for the kubelet on each node means that this will fit on 2 instances of type m5.large:



kubectl get node -l type=karpenter

NAME STATUS ROLES AGE VERSION

ip-192-168-178-84.ap-northeast-2.compute.internal Ready <none> 97s v1.24.13-eks-

ip-192-168-191-216.ap-northeast-2.compute.internal Ready <none> 97s v1.24.13-eks-

ip-192-168-79-228.ap-northeast-2.compute.internal Ready <none> 97s v1.24.13-eks-

ip-192-168-81-155.ap-northeast-2.compute.internal Ready <none> 97s v1.24.13-eks-



kubectl get node --label-columns=eks.amazonaws.com/capacityType,karpenter.sh/capacity-type


kubectl get node --label-columns=node.kubernetes.io/instance-type,topology.kubernetes.io/zone



node가 빠르게 증설된다 !!



6

Pod 줄여보자

12개인데 5개로 줄이면?


consolidation:

enabled: true

관리해주는 옵션.


# Next, scale the number of replicas back down to 5:

kubectl scale deployment inflate --replicas 5


node 를 최적화 한다.


# The output will show Karpenter identifying specific nodes to cordon, drain and then terminate:

kubectl logs -f -n karpenter -l app.kubernetes.io/name=karpenter -c controller



7

1개로 줄이면???

불필요한거 줄이고, 합친다.

스펙도 자동 조정한다.

2개 뜨는거보다 1개로 성능 좋은 pod로 뜨게 한다.

자동 조정한다.

비용 효율적으로 운영하는데 도움을 준다.


# Next, scale the number of replicas back down to 1


kubectl scale deployment inflate --replicas 1


kubectl logs -f -n karpenter -l app.kubernetes.io/name=karpenter -c controller





8

# 인스턴스 확인

kubectl get node -l type=karpenter


kubectl get node --label-columns=eks.amazonaws.com/capacityType,karpenter.sh/capacity-type


kubectl get node --label-columns=node.kubernetes.io/instance-type,topology.kubernetes.io/zone




9

# 삭제

kubectl delete deployment inflate


kubectl logs -f -n karpenter -l app.kubernetes.io/name=karpenter -c controller


빠르게 다운된다.






<9> 실습 리소스 삭제


1

#

kubectl delete svc -n monitoring grafana


helm uninstall -n kube-system kube-ops-view


helm uninstall karpenter --namespace karpenter



2

# 위 삭제 완료 후 아래 삭제

aws ec2 describe-launch-templates --filters Name=tag:karpenter.k8s.aws/cluster,Values=${CLUSTER_NAME} |

jq -r ".LaunchTemplates[].LaunchTemplateName" |

xargs -I{} aws ec2 delete-launch-template --launch-template-name {}



3

# 클러스터 삭제

export CLUSTER_NAME=myeks2


eksctl delete cluster --name "${CLUSTER_NAME}"


(10분)

400 del.png



https://vclock.kr/timer/#countdown=00:02:00&enabled=0&seconds=0&sound=xylophone&loop=1


4

#

aws cloudformation delete-stack --stack-name "Karpenter-${CLUSTER_NAME}"


# 위 삭제 완료 후 아래 삭제

aws cloudformation delete-stack --stack-name ${CLUSTER_NAME}






다음보기

https://brunch.co.kr/@topasvga/3301



전체 보기


https://brunch.co.kr/@topasvga/3217


감사합니다.

매거진의 이전글EKS8탄-10.EKS Autoscaling-10/17