최근 Kubernetes 운영을 하면서 CPU usage와 throttle에 관해서 살펴보고 있습니다. 작업이 좀 필요한데 이부분에 대한 이해가 없이는 제대로 할 수 없을것 같아서 지난 2주간 팀원들과 추측과 가설을 얘기하면서 실험을 통해 확인하고 있었습니다.
그러다가 아래 글을 보고 Kubernetes의 리소스 관리에 관해서 많은 부분을 이해하게 되었습니다. 아마도 그냥 읽었으면 잘 이해못하고 넘어간 글이 되었겠지만 최근에 공부한 덕에 더 쉽게 이해할 수 있었습니다.
Kubernetes에 리소스가 많이 있지만 주로 CPU와 관련한 리소스에 관해 설명하고 있고 3편의 글이라 아주 길지만 읽어볼 가치가 있습니다.
- 리소스는 compressible과 incompressible이 있는데 리소스가 없을 때 기다릴 수 있으면 compressible이고 그렇지 않으면 incompressible입니다. CPU는 compressible이고 램과 디스크는 incompressible입니다.
- kubernetes는 comressible은 스로틀을 걸어서 관리하고 incompressible은 eviction으로 처리합니다.
- CPU는 CFS(Completely Fair Scheduler)로 스케쥴링됩니다.
- request.cpu에 250m으로 지정했다면 1024 x0.25로 256 cpu share가 할당됩니다. reqeust는 팟을 스케쥴링할 때도 쓰이지만 노드에 자원이 부족할 때 share의 비율만큼 나누어 쓰기 때문에 reqeust는 보장 받아야 할 cpu이기도 합니다.
- cfs에서 기본 cpu period는 100ms이고 1 vCPU를 설정했다면 100ms를 quota로 받습니다. 해당 period내에 사용할 수 있는 cpu time이 이 quota입니다. 이 쿼터를 period내에 다 사용한다면 스로틀링을 걸리게 됩니다.
- limit이 있으면 노드에 자원이 남는다고 하더라도 limit만큼만 사용하게 되고 리소스의 경합 상황이 발생한다면 cpu share의 비율만큼 나누어 쓰게 됩니다.
글의 마지막에서는 다음 내용을 제안합니다.
- reqeust.cpu는 예상되는 usage 보다 높게 설정합니다.
- reqeust.cpu는 애플리케이션의 스레드/프로세스의 수보다는 낮게 설정합니다.
- 성능을 원한다면 limit.cpu를 설정하지 않습니다.(일관된 성능이 필요하다면 limit.cpu를 사용합니다.)
제가 찾던 속시원한 결과라 만족스러운 결론입니다. 현실에서 적용해 보면서 엣지 케이스를 찾아봐야 겠지만요.
최근에 AWS Instance Resource의 Network Bandwidth Baseline에 대해 트윗했던 내용인데 커리어리에도 올려요.
----
AWS EC2 인스턴스 타입별로 Network Bandwidth를 표시할 때, `Burst bandwidth (Gbps)` 로 표시하는데, Burst가 모두 소진된 상황에서, bandwidth limit 으로 제한 시작되는 건 https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html 페이지 하... 더 보기