PCA — 프로메테우스 인증 어소시에이트 · 익스포터가 실제로 내보내는 숫자 — cAdvisor 와 node exporter · 이론
숫자를 만드는 쪽에서 보기 — cAdvisor 와 node exporter
한 줄 요약
PromQL 은 이미 있는 숫자를 고르고 계산할 뿐이다. 그 숫자가 무엇을 센 것인지는
익스포터가 정한다. cAdvisor 의 CPU 는 왜 누적이고, working set 은 왜 RSS 와 다르며,
한도(limit)는 왜 cAdvisor 에 없는지 — 여기서부터가 익스포터 쪽 이야기다.
왜 이게 필요했나
"CPU 사용량이 658855 인데 이게 많은 건가요?" 라는 질문을 받은 적이 있다면, 그 사람은
쿼리를 틀린 게 아니라 지표의 종류를 몰랐던 것이다.container_cpu_usage_seconds_total 은 컨테이너가 태어난 뒤 쓴 CPU 시간을 계속
더해 온 값이라, 오래 산 컨테이너가 언제나 이긴다. 크기는 아무것도 말해 주지 않고
기울기가 답이다.
같은 이유로 _total 로 끝나는 것은 언제나 rate·increase 를 거쳐 읽고, 메모리
같은 게이지는 그대로 읽는다. 접미사는 관례가 아니라 읽는 방법의 선언이다.
어떻게 동작하나
cAdvisor 는 kubelet 안에 있다. 노드의 /metrics/cadvisor 를 긁으면 그 노드에서
도는 모든 컨테이너의 cgroup 통계가 나온다. 라벨의 id 가 cgroup 경로 그대로이고,
거기에 QoS 클래스와 파드 UID, 컨테이너 ID 가 들어 있다.
메모리는 세 가지가 다 다른 것을 센다.
| 지표 | 뜻 |
| --- | --- |
| container_memory_usage_bytes | 이 cgroup 이 쓰고 있다고 커널이 세는 전부 |
| container_memory_working_set_bytes | usage 에서 회수 가능한 비활성 파일 캐시를 뺀 값 |
| container_memory_rss | 익명 메모리(파일이 없는 메모리) |
cAdvisor 소스의 계산은 usage - total_inactive_file(cgroup v1) 또는usage - inactive_file(cgroup v2)이고, 음수면 0 으로 바닥친다. 쿠버네티스가
축출을 판정할 때 쓰는 값도 이 working set 이다 — 공식 문서는
"kubelet 은 inactive_file 을 계산에서 제외한다. 압박이 오면 회수할 수 있다고
보기 때문이다" 라고 적고 있다. **OOM 을 걱정한다면 usage 가 아니라 working set 을
봐야 하는 이유**가 그것이다.
한도는 cAdvisor 에 없을 수 있다. cAdvisor 원문에는 container_spec_cpu_quota
가 분명히 있는데, kube-prometheus-stack 은 기본 metric_relabel_configs 로 그 계열
대부분을 버린다. 그래서 "사용량 대비 한도" 를 보려면 kube-state-metrics 의kube_pod_container_resource_limits 와 namespace·pod·container 로 이어
붙여야 한다. 이건 이 클러스터만의 사정이 아니라 대부분의 스택이 그렇다.
node exporter 의 CPU 는 모드별 누적 시간이다. node_cpu_seconds_total 은
코어 하나 × 모드 하나마다 계열 하나다. 사용률은 "쉬지 않은 비율" 로 구한다 —1 - avg(rate(...{mode="idle"}[5m])). sum 을 쓰면 코어 수만큼 커진다.
MemFree 와 MemAvailable 은 다른 질문의 답이다. free 는 아무도 안 쓰는 메모리고,
available 은 "새 작업에 내어 줄 수 있는 양" 이다. 페이지 캐시 대부분은 회수할 수
있으므로 available 이 훨씬 크다. 이 클러스터의 cubi01 은 free 1.5 GiB 에
available 9.0 GiB 였다 — free 만 보고 경보를 걸면 멀쩡한 노드가 매일 운다.
현장에서 만나는 모습
CPU throttling 을 "0 보다 크면 사고" 로 보는 알림이 흔한데, 실제로 재 보면 한도가
걸린 컨테이너 대부분이 0.0x% 수준의 throttle 을 항상 겪는다. 이 클러스터의 실측도
가장 높은 컨테이너가 0.19%, 나머지는 0 이었다. 그래서 판정은 비율로 한다 —rate(throttled_periods) / rate(periods). 그리고 한도가 없는 컨테이너에는 CFS
지표가 아예 없다. 없는 것과 0 인 것은 다르다.
다음 실습에서 할 것
이 사이트를 돌리는 7노드 클러스터에서 뜬 3시간치 실측 자료가 실습 파드의
프로메테우스에 들어 있다. 계열 674개 — 진짜 노드, 진짜 컨테이너, 진짜 GPU 다.
그 자료로 컨테이너 CPU 의 기울기를 재고, throttle 비율로 한도 초과를 판정하고,
usage 와 working set 의 차이가 어느 지표와 같은지 확인하고, cgroup 경로에서
QoS 클래스를 읽고, kube-state-metrics 와 이어 붙여 한도 대비 사용률을 낸다.