[Kubernetes] Pod CPU / Memory resource 최적화하기

메린·2023년 6월 7일
0

Kubernetes

목록 보기
7/8
post-thumbnail

앞서 실습을 진행하면서 Requests와 Limits 값을 정해 Pod 를 배포했고, 이에 대한 더 자세한 설명을 하고자 생각해두고 있었다. 어떠한 형식으로 진행되기에 이 값들을 지정해 주어야 하는지에 대해 정확한 이해가 필요하다고 생각한다.

그래서 대체 어디에 쓰이는 건데?

대표적으로, Kubernetes의 Node의 개수는 Pod가 요청하는 CPU,Memory의 크기에 따라 결정된다.
Podr가 많은 CPU, Memory를 요청할수록 불필요하게 많은 Node가 필요하며, 너무 적을 경우 안정적인 서비스 운영이 어렵다. 바로 이 안정적인 운영을 가능하게끔하는 것이 Pod의 리소스 요청값인 'requests' 이다.

Requests 와 Limits

  • spec.containers[].resources.requests.cpu
  • spec.containers[].resources.requests.memory
  • spec.containers[].resources.limits.cpu
  • spec.containers[].resources.limits.memory

Requests는, Pod가 Node에 스케줄링 될 때 필요한 공간이다.
Node에 requests 만큼의 CPU, Memory가 남아있을 경우 Pod가 스케줄링 된다.
만약 Requests 값이 남아 있는 리소스보다 큰 경우, 해당 노드에는 충분한 리소스가 없으므로 Pod는 스케줄링 되지 않는다. 이 경우, Kubernetes는 다른 노드에 스케줄링 될 수 있는지 확인하고, Cluster Autoscaler와 같은 동적 확장 메커니즘을 사용하여 새로운 노드를 생성하고 Pod를 스케줄링 한다.
만약 가능한 Node가 없다면 Pod는 Pending 상태가 된다.

Limits은 Pod가 실제 사용할 수 있는 최대 리소스이다.
예를 들어, requests.cpu=100m, limits.cpu= 200m 인 경우 Pod는 100m 이상의 CPU를 요청하며, 스케줄링될 때는 최소 100m의 여유가 있는 노드에 배치된다. 그러나 실제로 Pod가 동작할 때는 최대 200m의 CPU를 사용할 수 있다.

  • 특정 노드에 배치된 여러 개의 Pod의 limits.cpu 값의 합이 노드의 실제 CPU 용량을 초과할 수 있다. 이 경우, 동시에 requests 이상의 CPU를 사용하는 다수의 Pod가 있으면 노드의 CPU가 부족해지고, 성능 저하가 발생할 수 있다. 이는 throttling으로 인해 Pod의 동작 속도가 느려지거나 응답 시간이 증가할 수 있는 상황을 의미한다.

  • Memory도 마찬가지이다. 만약 Memory가 부족한 상황이라면 Pod는 Out of Memory(OOM) 상태가 될 수 있다. OOMKilled는 Pod가 할당된 메모리 양을 초과하여 메모리 부족으로 인해 종료되는 상황을 의미한다. 이는 Pod의 안정성과 신뢰성을 저하시킬 수 있으며, 중요한 데이터나 작업에 영향을 미칠 수 있다.

따라서, 적절한 requests와 limits 값을 설정하여 리소스 사용을 관리하고, 노드의 실제 용량과의 균형을 유지하는 것이 중요하다. 리소스 사용량을 모니터링하고 조정하여 효율적인 운영을 지속적으로 수행해야 한다.

사용량 기반의 Requests 최적화 방법

  1. VPA (Vertical Pod Autoscaler) : VPA는 Kubernetes에서 제공하는 기능 중 하나로, 실제 리소스 사용량을 모니터링하고 Pod의 Requests 값을 자동으로 조정한다. VPA는 metric server를 통해 Pod의 실사용량을 수집하고, 이를 기반으로 Requests 값을 추천하며 자동으로 업데이트할 수 있다.
  2. Kubecost : Kubecost는 리소스 비용 및 사용량을 관리하기 위한 툴로, Pod의 실사용량을 수집하고 비용 및 성능에 대한 분석 및 추천을 제공한다. Kubecost를 사용하여 리소스 사용량을 모니터링하고 비용 효율적인 Requests 값을 결정할 수 있다.

그럼 Requests 계산은 어떻게 이루어 지는걸까?

  • '기준값'과 'margin'으로 계산된다.

  • 기준값 설정: Pod가 동작하는 데 필요한 최소한의 리소스 값을 결정한다. 기준값은 Pod의 실제 사용량을 분석하여 결정할 수 있다. CPU의 경우, 대부분의 시간에 평균적으로 사용되는 양(avg) 또는 일부 시간 동안 최대로 사용되는 양(max)을 고려할 수 있다.
    예를 들어, 대부분의 CPU 사용률이 2 core 정도이고, 가끔씩 4 core까지 사용한다면 기준값을 2 core로 설정할 수 있다. 만약 최대 사용량이 빈번하게 발생한다면 4 core로 설정하는 것이 적절할 수 있다. 또한, 프로덕션 환경인 경우 안정성을 위해 max 값을 기준값으로 선택할 수 있고, 개발 또는 스테이징 환경인 경우 비용 절감을 위해 avg 값을 기준값으로 선택할 수 있다. 서비스의 특성과 SLA를 고려하여 적절한 기준값을 설정해야 한다.

  • margin 추가: mar은 실제 사용량이 기준값을 초과할 때 발생할 수 있는 문제를 방지하기 위해 추가하는 버퍼이다. 예를 들어, 메모리의 경우 max 값으로 기준값을 설정하더라도 실제 사용량이 더 큰 경우 OOMKilled와 같은 문제가 발생할 수 있다. 이를 방지하기 위해 마진을 추가한다. margin의 크기는 안정성을 위해 크게 가져갈 수도 있고, 개발 또는 스테이징 환경에서는 비용 절감을 위해 작게 가져갈 수도 있다. 서비스의 특성과 요구 사항을 고려하여 적절한 마진을 설정해야 한다.

최종적으로, 추천되는 requests 값은 (기준값) x (마진)으로 계산된다. 이를 통해 실제 사용량과 안정성 또는 비용 절감을 고려하여 적절한 리소스 요청 값을 설정할 수 있다.

여기서 VPA와 Kubecost의 requests 값을 구하는 방식에 차이가 있다.

VPA vs Kubecost 의 비교

  • 둘 간의 계산방식은 기본적으로는 동일 하다. percentile 또는 max 값을 통해 기준값을 정하고, margin 을 더하는 방식이다.

사전 정의된 profile 을 비교해보면, VPA는 기준값(percentile) 을 변경하고, kubecost는 margin 을 변경하는 방식이다.

차이점은 VPA는 histogram-decay 를 통해 최신의 데이터를 중요하게 반영한다는 것입니다.

VPA는 현재 상황을 고려하여 Pod의 리소스 요청 값을 조정하는데 사용된다.
VPA는 histogram-decay 알고리즘을 사용하여 최신의 데이터를 중요하게 반영한다. 이 알고리즘은 과거와 현재의 리소스 사용량 데이터를 이용하여 요청 값의 추천을 결정한다. 최신의 데이터가 더 중요하다고 가중치를 주어 현재 상황에 맞게 리소스 요청 값을 조정한다. 이를 통해 VPA는 실제 사용량에 따라 Pod의 리소스 요청 값을 동적으로 조정하여 자원의 효율성과 성능을 개선한다.

VPA의 목적은 자동 스케일링이 아니라 리소스 요청 값을 최적화하는 것이지만, 이를 위해 최신의 데이터를 중요하게 반영하는 로직이 추가되어 있다. 이는 VPA가 현재 상황을 고려하여 정확한 추천을 할 수 있도록 돕는 역할을 한다.

profile
I can do it ! 苦盡甘來

0개의 댓글