반응형
개요
Karpenter + KEDA를 사용해서 이벤트 시간 전에 Node Scale Out 하고 일정 시간 지난 후 Scale In 되도록 테스트를 해보겠습니다. Karpenter가 Node를 프로비저닝 할 때 1~2분 정도 시간이 걸립니다. 이벤트 시간 전에 특정 개수의 노드 여유분을 확정적으로 늘려놓고 싶을 때 사용합니다. 아래 영상을 보고 내용을 정리했습니다.
https://www.youtube.com/watch?v=FPlCVVrCD64
Karpenter 사용 팁
- Karpenter는 CA와 마찬가지로 Pod Request를 기준으로 노드를 증설하기 때문에 사용량 최대치를 Request로 잡거나 Limit과 차이를 적게 하는 것을 추천한다.
- 노드 타입을 작은 것으로 정의하는 것이 항상 유리한 것은 아니다.
- 4 CPU 인스턴스를 사용한다고 정의했을 때 3 CPU를 요구하는 Pod가 스케줄링된다면 1 CPU가 잉여 공간이 된다.
- 두 개 이상의 Pod가 들어갈 수 있는 넉넉한 노드 타입을 정의하는 것을 추천.
- Karpenter Limit CPU, Memory를 설정해서 최대 인스턴스를 제한할 수 있다.
- 중간 인스턴스 타입의 CPU, 메모리 스펙 x 원하는 대수로 리소스 제한하는 것을 추천한다.
- Spot, On-demand를 함께 정의했을 때, Karpenter는 비용 절감하도록 설계되어 있기 때문에 Spot을 먼저 선택해서 노드를 프로비저닝 한다. 정의한 인스턴스 타입 중에 Spot 수량이 없을 때 On-demand를 선택해 노드를 프로비저닝 한다.
- Spot만을 정의했을 때, 최대한 다양한 인스턴스 타입을 정의해야 한다. 너무 적게 설정해 놓으면 Spot 수량이 없을 수도 있기 때문이다.
- ttlSecondsUntilExpired에 의한 Deprovisioning에 대비해서 PodDisruptionBudget(PDB) 설정을 통해 워크로드 중단 속도를 조절해야한다.
오버 프로비저닝 Pod X KEDA
CA는 ASG 설정을 통해 일정 시간에 노드를 증설하고 감소시킬 수 있으나 Karpenter는 ASG를 사용하지 않기 때문에 불가능하다.
CA(ASG): https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html
해결 방법
- KEDA 사용 (cron을 사용해서 일정 시간에 파드 증가/감소)
- Pod에 affinity.podAntiAffinity 를 사용하고 cpu request 1m으로 설정한다.
- Karpenter가 파드안티어피니티를 확인하고 Pod가 없는 새로운 노드를 증설한다 → 오버 프로비저닝 Pod의 개수만큼 노드 증설이 보장된다.
테스트
사전 조건
1. Karpenter 설치
참고: https://jenakim47.tistory.com/89
2. KEDA 설치
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda -n keda --create-namespace
Karpenter Provisioner
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: karpenter-provisioner
spec:
requirements:
- key: node.kubernetes.io/instance-type
operator: In
values: ["t3.medium", "t3.large", "t3.xlarge"]
- key: "topology.kubernetes.io/zone"
operator: In
values: ["ap-northeast-2a", "ap-northeast-2c"]
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand"]
limits:
resources:
cpu: "1000"
memory: 1000Gi
ttlSecondsAfterEmpty: 30
labels:
role: ops
provision: karpenter
provider:
securityGroupSelector:
karpenter.sh/discovery: ${CLUSTER_NAME}
subnetSelector:
karpenter.sh/discovery: ${CLUSTER_NAME}
tags:
Name: karpenter.sh/provisioner-name/karpenter-provisioner
karpenter.sh/discovery: ${CLUSTER_NAME}
오버 프로비저닝 Pod
- 오버프로비저닝 용도이기 때문에 request를 최소로 잡습니다.
- nodeAffinity, podAntiAffinity 를 사용합니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 0
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 0
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: 1m
affinity:
nodeAffinity: # karpenter node 증설을 위한 노드어피니티.
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: provision
operator: In
values:
- karpenter
podAntiAffinity: # 파드 개수만큼 node 증설하기 위한 파드안티어피니티.
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: "kubernetes.io/hostname"
KEDA ScaledObject
- Kubernetes Objects, Scaling 정의와 외부 Event Source 간의 Desired 상태에 대한 매핑 설정합니다.
- ScaledObject를 선언하면 내부적으로 HPA를 생성합니다.
- CPU, Memory, Cron, AWS SQS / Prometheus, Datadog 등 다양한 스케일러를 사용할 수 있습니다.
- 지정한 시간에 노드 5개를 증설하기 위해서 KEDA Scalers cron을 사용하겠습니다.
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: keda-over-provioning
spec:
# min / max count
minReplicaCount: 1
maxReplicaCount: 10
# target
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
triggers:
- type: cron
metadata:
timezone: Asia/Seoul
start: 00 13 * * *
end: 00 21 * * *
desiredReplicas: "5"
hpa 생성
지정시간이 되자 Pod 5개 생성됨.
Pod 5개가 pending이 되자 Karpenter가 Node 5개를 생성합니다.
5개 노드가 모두 Ready 상태가 되었고, 5개 파드가 모두 Running 상태가 되었습니다.
제일 먼저 생성되기 시작한 파드가 2분 3초가 찍혔습니다.
이를 통해 일정시간에 노드를 증설하고 다운시킬 수 있습니다.
반응형
'DevOps > Kubernetes' 카테고리의 다른 글
Kubernetes QoS(Qualitu Of Service)와 Pod Eviction의 상관 관계 (0) | 2023.03.25 |
---|---|
[K8S] 쿠버네티스를 사용해야하는 이유 (0) | 2023.02.28 |
[EKS] Karpenter - Groupless Node AutoScaling 사용법 (0) | 2022.11.17 |
K8S에서 Kong API Gateway 사용하기 (0) | 2022.10.07 |
K8S에 Kong API Gateway 설치 하는 방법 (Helm Charts) (0) | 2022.10.07 |