brunch

You can make anything
by writing

C.S.Lewis

by Master Seo May 25. 2023

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

EKS 8탄 - 5주차

본 내용은 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



오픈 소스 고성능 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






<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로 접속 하라..

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








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분)



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


감사합니다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari