Study_note
[kubernetes] karpenter vs ca 본문
기본적으로 쿠버네티스는 오토스케일 즉 자동 확장 기능을 제공했는데 크게 두가지로 나뉜다
파드 기반 오토스케일링
HPA (Horizontal Pod Autoscaler) - 임계값에 맞게 파드를 추가 및 제거
VPA (Vertical Pod Autoscaler) - 임계값에 맞게 파드의 cpu 및 메모리 요청 및 제한 크기를 조정\
노드 기반 오토스케일링
CA (Cluster Autoscailing) - 임계값에 맞게 노드를 추가 및 제거
여기서 최근에 새롭게 출시된 노드 기반 오토스케일링인 karpenter가 새롭게 생겼다.
우선 CA에 단점을 말하면서 카펜더와 ca의 차이를 찾아보자
CA 단점
- Auto Scaling을 구성하기가 어렵고 구성할 수 있는 범위가 제한적이다
- 노드를 확장하기 전에 노드가 확장될 때까지 기다려야 하므로 배포 대기 시간에 큰 영향 발생 -> Overprovisioning
- 번거로운 ASG 노드 그룹 관리
반면에 카펜터는
Karpenter는 다음과 같이 세 가지 컴포넌트로 구성되어 있다.
- Controller: K8S controller 형태로 구현되어 pod 상태를 감시하고 노드 확장 및 축소
- Webhook: Provisioner CRD에 대한 유효성 검사 및 기본값을 지정
- Provisioner: Karpenter에 의해 생성되는 노드와 Pod에 대한 제약조건을 지정
Karpenter Helm Chart를 통해 설치하면 controller와 webhook pod가 생성됩니다. 이후에 provisioner CRD를 정의하고 클러스터에 배포하면 사용할 수 있습니다. provisioner는 ASG 노드 그룹과 유사한 개념입니다. 따라서 default를 사용하는게 아니라 기존에 사용하던 설정에 맞게 새로 만들어야 합니다. Scale In/Out 관련된 내용은 다음과 같습니다.
장점
- Provisioner API를 통해 간편한 노드 관리
- 수 많은 인스턴스 유형에 대해 유연하게 처리
- 노드 프로비저닝 시간 단축
즉
CA는 스케일링에 걸리는 시간도 상당할뿐더러, 제한적인 스케일링으로 인해 리소스가 낭비되거나 운영환경에서 다운타임을 최소화하기 위해 오버프로비저닝 되는 경우도 많았지만
karpenter의 빠른 프로비저닝과 유연한 스케일링 덕분에 이러한 문제들을 해결할 수 있다.
카펜더 생성
생성은 카펜더 공식 문서를 보면 자세히 설명되어있다.
우선 생성하기 편하기 하기와 같이 리전, 이름, id 등을 환경변수로 지정해준다.
export KARPENTER_VERSION=v0.17.0
export CLUSTER_NAME="${USER}-karpenter-demo"
export AWS_DEFAULT_REGION="ap-northeast-2"
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
생성할 eks 클러스터 야믈 파일 생성 후 apply
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: ${CLUSTER_NAME}
region: ${AWS_DEFAULT_REGION}
version: "1.23"
tags:
karpenter.sh/discovery: ${CLUSTER_NAME}
managedNodeGroups:
- instanceType: m5.large
amiFamily: AmazonLinux2
name: ${CLUSTER_NAME}-ng
desiredCapacity: 1
minSize: 1
maxSize: 10
iam:
withOIDC: true
카펜터노드 역할생성 해준다.
먼저 AWS CloudFormation을 사용하여 IAM 리소스를 생성합니다.
다음으로 인스턴스에 대한 액세스 권한을 부여하여 역할을 가진 노드가 클러스터에 연결할 수 있도록 한다
TEMPOUT=$(mktemp)
curl -fsSL https://karpenter.sh/"${KARPENTER_VERSION}"/getting-started/getting-started-with-eksctl/cloudformation.yaml > $TEMPOUT \
&& aws cloudformation deploy \
--stack-name "Karpenter-${CLUSTER_NAME}" \
--template-file "${TEMPOUT}" \
--capabilities CAPABILITY_NAMED_IAM \
--parameter-overrides "ClusterName=${CLUSTER_NAME}"
eksctl create iamidentitymapping \
--username system:node:{{EC2PrivateDNSName}} \
--cluster "${CLUSTER_NAME}" \
--arn "arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterNodeRole-${CLUSTER_NAME}" \
--group system:bootstrappers \
--group system:nodes
카팬더컨트롤러 역할 생성
eksctl create iamserviceaccount \
--cluster "${CLUSTER_NAME}" --name karpenter --namespace karpenter \
--role-name "${CLUSTER_NAME}-karpenter" \
--attach-policy-arn "arn:aws:iam::${AWS_ACCOUNT_ID}:policy/KarpenterControllerPolicy-${CLUSTER_NAME}" \
--role-only \
--approve
export KARPENTER_IAM_ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/${CLUSTER_NAME}-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 clusterName=${CLUSTER_NAME} \
--set clusterEndpoint=${CLUSTER_ENDPOINT} \
--set aws.defaultInstanceProfile=KarpenterNodeInstanceProfile-${CLUSTER_NAME} \
--wait # for the defaulting webhook to install before creating a Provisioner
프로비저널 생성
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}
자동 노듯 프로비저닝 설치
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.2
resources:
requests:
cpu: 1
카펜터는 이해했는데 헬름 버전이 안맞는건지 아래 에러 발생 후 찾아봐도 안나와서 일단 보류했다
클러스터 버전 업도 다해봤는데 안된다...... istio할때도 똑같은 에러 발생하고 버전들 바꿔주니 됐는데 쩝ㅋㅋㅋ
Kubernetes cluster unreachable: exec plugin: invalid apiVersion "client.authentication.k8s.io/v1alpha1
원인이 헬름 버전이 맞았다...
나와 똑같은 에러를 가진 사람에 블로그를 보니 헬름에 각 버전마다 어떤 Kubernetes를 지원하는지 파악해야 하고 eks를 설치해야했었다...
참고해서 수정하면 자동대로 작동 가능했다.
https://nemne.tistory.com/m/33
참조
https://swalloow.github.io/eks-karpenter-groupless-autoscaling/ ( 해당 글을 토대로 글을 썼다. 따로 읽는거 추천)
https://karpenter.sh/v0.6.3/getting-started/
'Kubernetes' 카테고리의 다른 글
[kubernetes] Helm Override 및 Upgrade (0) | 2022.11.17 |
---|---|
[kubernetes] Helm 및 chart 커스텀 (0) | 2022.11.16 |
[EKS] POD 자원관리 (QoS) 및 OOM 킬러 우선 순위 (0) | 2022.11.08 |
Ingress의 Target Type 및 externalTrafficPolicy: Local 설정 (0) | 2022.11.01 |
AWS EKS Load Balancer Controller 및 IAM OIDC Provider (0) | 2022.10.27 |