cpu 사용량 쿼리

김형진·2023년 6월 22일
0

cpu는 memory나 disk처럼 현재의 사용량을 직접적으로 나타내기 어렵다.

단일 CPU 코어는 1초 동안 다양한 애플리케이션에서 오는 요청을 처리할 수 있다. 이는 운영 체제의 스케줄러(scheduler) 덕분인데, 스케줄러는 CPU 시간을 여러 프로세스 또는 스레드 간에 공평하게 분배하는 역할을 한다.

운영 체제는 각 애플리케이션을 실행하는데 필요한 작업을 작은 '시간 조각(time slice)'으로 나눈다. 이 시간 조각은 보통 밀리세컨드(ms) 단위로, 운영 체제의 스케줄러는 이러한 시간 조각을 사용하여 각 애플리케이션에 CPU의 사용 시간을 할당한다.

이 과정을 통해 CPU 코어는 동시에 여러 애플리케이션을 처리하는 것처럼 보이게 된다. 그러나 실제로는 CPU 코어가 매우 빠른 속도로 각 애플리케이션의 작업을 전환하면서 이루어지고, 이를 컨텍스트 스위칭이라 한다. 이러한 방식으로, 단일 CPU 코어는 1초 동안 수천 개의 작업을 처리할 수 있다.

이 때문에 cpu의 사용량은 초 단위로 구해진다.
예를 들어 한 시간(3600초) 동안 cpu가 실제로 사용된 시간은(!=idle mode) 100초인 경우 실제 사용량은 100 / 3600 것이다.

프로메테우스에서 cpu 사용량을 알 수 있는 쿼리는 다음과 같다. (노드 기준)

node_cpu_seconds_total


instance는 각 노드이며 mode는 cpu사용 mode인데, idle이 유휴시간이며 나머지는 실제 사용되는 시간이다. 가장 오른쪽에 보이는 값은 노드가 실행된 이후부터 지금까지의 cpu사용량을 초단위로 나타낸 것이다.

'k8s-master' 노드의 경우 약 172일전에 생성되었으며
그 중 1460만 초 동안 사용되지 않고,
약 17만 초 동안 system에 의해 사용되었으며
약 22만 초 동안 user에 의해 사용된 것이다.

그리고 모든 mode의 숫자를 합하면 약 1510만 초가 나오는데 이를 일수로 환산하면 약 172일이 된다.

그러나 이런 데이터는 직관적이지 않기 때문에 해당 쿼리를 정제해야 한다.
우선 'rate'와 범위 시간을 지정한다.

rate(node_cpu_seconds_total[1h])

이는 한 시간동안 사용된 평균 cpu 코어 수를 보여준다.
'k8s-master'는 한 시간 평균 약 0.927 코어를 사용하였으며
user나 system에 의해 사용된 코어는 한 시간 평균 약 0.05밖에 되지 않는다.

rate는 어떻게 계산되는 것일까?

약 30초 이전 생성된 노드가 있다고 가정하자.
t는 구동시간(초), 오른쪽의 값은 생성 이후 누적 코어 사용량(초)이다.

t=0: 0
t=5: 1
t=10: 6
t=15: 8
t=20: 9
t=25: 13
t=30: 18

rate(node_cpu_seconds_total[15s])

현재는 노드가 생성된지 30초된 시점이며, 해당 쿼리를 날리면 최근 15초동안의 cpu사용량을 가지고 rate를 도출하게 되는데

최근 15초는 t=15의 데이터까지 포함되며 t=15이후 지금까지의 cpu사용량은 10초(18 - 8)이다.

그런데 이를 초당 사용률로 나타내야 하므로 (10 / 15) = 0.6666666666....
즉 약 0.67코어를 사용했음을 알 수 있다.

여기서 끝이 아니다.
cpu는 보통 단일코어가 아닌 멀티코어로 구동된다.


데이터를 다시 보면 cpu="0"이 있는데, 이는 0번째 코어에 대한 데이터라는 뜻이다. node사용할 수 있는 코어는 이보다 더 많고 캡쳐에 다 담기지 않았기 때문에

실제로 node가 한 시간동안 사용한 총 core 수를 계산하려면 sum을 붙여줘야 한다.

sum(rate(node_cpu_seconds_total[1h]))


엥? 난데없이 95라는 값이 나온다. 이는 node별로 구분하지 않고 모든 값을 다 합쳐버렸기 때문에 이와 같은 값이 발생한 값이다. 그래서 node(instance)끼리 분리하기 위해

sum(rate(node_cpu_seconds_total[1h]))by(instance)

쿼리를 보내면

노드별로 데이터가 잘 나오는 것을 확인할 수 있다.

그런데 한 가지 빠진 것이 있다. mode를 구분하지 않은 것이다.

idle모드느느 유휴시간이며 실제 cpu를 사용한 시간을 구하기 위해선 idle시간이 빠진 데이터로 결과를 도출해야 한다.
(idle포함 총 사용한 cpu 코어값이 약 15.8으로 나온 것을 보면 해당 클러스터는 16코어 cpu로 구성되어있음을 알 수 있다.)

sum(rate(node_cpu_seconds_total[1h]{mode!='idle'}))by(instance)

이제는 유휴시간을 빼고 1시간 평균 실제 사용된 core수를 확인할 수 있다.

profile
히히

0개의 댓글