쿠버네티스 일반

EKS Burstable 설정과 KRR을 활용한 비용 절감 내역 공유

Jerry_이정훈 2024. 6. 24. 18:04
728x90

현재 저는 CPU는 Limit을 지정하지 않는 Burstable 설정을 사용하고, CPU와 메모리 Request, Limit의 구체적인 설정값은 KRR을 사용하여 실제 사용량 기반으로 지정합니다. 이러한 구성은 시스템 안정성에 큰 영향을 미치지 않으면서 비용을 절감할 수 있는 효과적인 방법 같아서 공유합니다.

 

QoS 설정과 Burstable

 

운영 환경의 안정성을 위해 많은 분들이 파드의 QoS 설정을 Guaranteed로 지정합니다. Guaranteed 설정은 Burstable 및 Best Effort 설정에 비해 노드의 자원이 부족할 때 파드가 Evict(추출) 당하지 않기 때문에 당연한 선택처럼 보입니다. 

 

그러나 메모리와 달리 CPU는 Node Pressure가 없습니다. 즉, CPU를 과도하게 사용한다고 노드가 파드를 추출하지 않습니다. 물론, 노드의 CPU 사용량이 계속 100%를 유지하면 노드에 실행 중인 Kubelet이 제대로 동작하지 못하는 문제가 발생할 수 있지만, 이는 해당 애플리케이션의 문제라 애플리케이션 단에서 해결해야 합니다.

 

아래와 같이 CPU Pressure는 항목에 없습니다.

 

Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Mon, 10 Jun 2024 17:20:55 +0900   Mon, 10 Jun 2024 17:20:55 +0900   CalicoIsUp                   Calico is running on this node
  MemoryPressure       False   Mon, 24 Jun 2024 10:03:28 +0900   Sat, 01 Jun 2024 03:20:01 +0900   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Mon, 24 Jun 2024 10:03:28 +0900   Sat, 01 Jun 2024 03:20:01 +0900   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Mon, 24 Jun 2024 10:03:28 +0900   Sat, 01 Jun 2024 03:20:01 +0900   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Mon, 24 Jun 2024 10:03:28 +0900   Sat, 01 Jun 2024 03:20:01 +0900   KubeletReady                 kubelet is posting ready status. AppArmor enabled

 

그리고 CPU는 메모리와 다르게 Limit 설정을 하지 않아도 Request 설정만큼 사용을 보장 받을 수 있습니다. 즉, 다른 파드가 CPU를 많이 사용해도 영향이 제한적입니다. 그리고 필요한 경우 노드의 가용 CPU 범위에서 자유롭게 사용할 수 있으므로 성능 향상에도 도움이 됩니다.

필자는 자바 기반의 어플리케이션을 주로 운영중인데,  파드가 처음 기동 시 CPU를 많이 사용하고 이 후 사용량이 떨어지는 파드가 대부분입니다. 

 

CPU Limit을 설정을 제거하고, 초기 기동 시 CPU Limit에 걸려서 Readiness, Liveness Probe 실패하는 문제를 해결할 수 있었습니다.

 

그리고 파드 설정에 같은 노드에 같은 파드가 실행하지 않도록 podAntiAffinity 설정을 하면 특정 노드에 파드가 동시에 실행하여 해당 노드의 CPU를 과도하게 사용하는 문제를 어느정도 방지할 수 있습니다. CPU Request 설정값을 적절하게 잘 지정하는 것이 중요하며 이를 KRR을 사용해서 비교적 편리하게 설정하였습니다.

 

CPU Request 설정과 사용량

 

CPU Request 설정을 실제 사용량만큼 적절하게 지정하면 노드의 CPU 사용량은 일반적으로 높지 않습니다. 특정 파드가 Peak 사용 시 2~4배 정도로 증가하더라도 노드 전체의 평균 CPU 사용량이 20~40% 정도를 유지하면 해당 파드로 인하여 노드의 문제가 발생하는 경우는 거의 발생하지 않았습니다. 물론 필요하면 CPU 사용량에 따른 HPA 설정으로 노드의 수량을 적절하게 증가할 수 있습니다.

 

클러스터 CPU, 메모리 사용량은 Grafana 등을 이용하여 확인할 수 있습니다.

 

 

KRR을 통한 최적의 자원 설정

 

따라서 실제 사용량만큼 Request와 Limit을 설정하는 것이 중요합니다. CPU Request와 Limit을 1Core 혹은 2Core로 지정하면, xlarge EC2(4 vCPU)에 3개의 파드만 실행 가능하여 노드 자원을 효과적으로 사용하지 못하는 경우가 많습니다. 1Core, 2Core는 실제로는 굉장히 큰 리소스인데, 숫자 자체의 느낌이 작아서 설정하는 경향이 있는 것 같습니다.

 

KRR(Kubernetes Resource Recommender)을 사용하면 실제 사용량 기준으로 Request와 Limit 사용량을 추천받을 수 있습니다. CLI 기반으로 설치 및 사용이 매우 편리하며, 히스토리 데이터 기간, CPU Percentile, 메모리 버퍼 등을 커스터마이징하여 실제 상황에 맞게 수정할 수 있어 사용성이 높습니다.

 

$ krr simple --help
$ krr simple --history_duration 720 --cpu_percentile 90 --memory_buffer_percentage 10

 

이 설정은 1달 데이터 기준으로 CPU Peak 사용량의 90%와 메모리 Peak 사용량의 10% 여유를 설정하는 예시입니다. 물론 KRR만 실행하여 Request와 Limit 설정을 그대로 적용할 수는 없으며, 실제 사용량 그래프를 참조하여 적용하면 더욱 정확하게 설정할 수 있습니다.

 

참고 링크

 

- [QoS 관련 공식 문서](https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/)

- [CPU Request, Limit 설정](https://home.robusta.dev/blog/stop-using-cpu-limits)

- [KRR, Kubernetes Resources Recommender](https://github.com/robusta-dev/krr)



반응형