우리는 최근 프로덕션 환경을 Kubernetes로 전환했습니다. 컨테이너에 CPU 제한을 적용하고 싶습니다. 서로 맞지 않는 충돌하는 CPU 메트릭이 나타납니다. 내 설정은 다음과 같습니다.
- 로 실행중인 DataDog 에이전트
Daemonset
- CPU 제한없이 실행중인 기존 응용 프로그램
- 문제의 컨테이너는 멀티 스레드 Ruby 애플리케이션입니다
- 두 가지 측정 항목 :
kubernetes.cpu.usage.{avg,max}
및docker.cpu.usage
c4.xlarge
클러스터 노드 (쿠 버네 티스 용어로 vCPU 4 개 또는 4000m)
kubernetes.cpu.usage.max
해당 컨테이너에 대해 ~ 600m를보고합니다. docker.cpu.usage
~ 60 %를보고합니다. 정상 작동시 1000m CPU 제한은 충분한 용량보다 클 것입니다.
나는 한계를 1000m로 설정했다. 그런 docker.container.throttles
동안 크게 상승 kubernetes.cpu.usage.max
과 docker.cpu.usage
동일하게 유지. 이 기간 동안 시스템은 모두 무릎을 꿇었습니다. 이것은 나에게 이해가되지 않습니다.
Docker 통계를 조사했습니다. CPU 코어에 따라 docker stats
(및 기본 API) 로드를 정규화 하는 것으로 보입니다 . 제 경우 docker.cpu.usage
에는 Kubernetes 용어로 60 % (4000m * 0.60)에서 2400m가됩니다. 그러나 이것은 Kubernetes 번호와 관련이 없습니다. Kubernetes 숫자가 잘못되었다는 가설을 테스트하기 위해 다른 실험을 수행했습니다. 한도를 2600m로 설정했습니다 (추가 헤드 룸의 경우). 이로 인해 스로틀이 발생하지 않았습니다. 그러나 Kubernetes는 CPU 사용량이 변경되지 않았 음을 관찰했습니다. 이것은 나를 혼란스럽게합니다.
그래서 내 질문은 :
- Kubernetes (또는 스택의 무언가)에서 버그처럼 느껴 집니까?
- 이해가 정확합니까?
내 후속 질문은 Ruby 응용 프로그램의 CPU를 올바르게 결정하는 방법과 관련이 있습니다. 하나의 컨테이너는 푸마를 사용합니다. 구성 가능한 스레드 수를 가진 다중 스레드 웹 서버입니다. HTTP 요청은 스레드 중 하나에 의해 처리됩니다. 두 번째 응용 프로그램은 스레드 서버를 사용하는 중고 서버입니다. 들어오는 각 TCP 연결은 자체 스레드에 의해 처리됩니다. 연결이 닫히면 스레드가 종료됩니다. Ruby는 GIL (Global Interpreter Lock)이므로 한 번에 하나의 스레드 만 Ruby 코드를 실행할 수 있습니다. 이를 통해 IO를 실행하는 여러 스레드와 그와 같은 것들이 가능합니다.
가장 좋은 방법은 각 응용 프로그램에서 실행되는 스레드 수를 제한하고 스레드 수에 따라 Kubernetes CPU 제한을 근사하는 것입니다. 프로세스가 중단되지 않으므로 총 CPU 사용량을 예측하기가 어렵습니다.
여기서 문제는 : 이러한 응용 프로그램에 대한 CPU 사용량과 한계를 올바르게 예측하는 방법은 무엇입니까?