최근 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를 사용합니다.)
제가 찾던 속시원한 결과라 만족스러운 결론입니다. 현실에서 적용해 보면서 엣지 케이스를 찾아봐야 겠지만요.