k9s
k9s copied to clipboard
QUESTION: How are the Pulses Cpu and Mem totals being calculated?
I am wondering how the Pulses' Cpu
and Mem
totals and percentages are calcuated? They don't seem to match what's described in kubectl describe nodes
and Azure Monitor.
k9s Pulses: CPU
k9s Pulses: Mem
Kubectl describe nodes
Hi @FilBot3,
I had the same doubt as you. I am not a developer of k9s and I'm not familiar with its codebase at all, so I ventured a bit into the source code to answer this. Here's what I concluded (it'd be nice to have this confirmed by someone more acquainted with the code):
These values are calculated from the "current" and "allocatable" metrics associated to the nodes.
The "current" metric seems to always be the same as output by the kubectl top
command.
The "allocatable" metric can be cross-checked in the kubectl describe
on each of the Kubernetes nodes.
So, for CPU:
- "Current CPU" is what is output by
kubectl top nodes | awk '{print $2}'
- "Allocatable CPU" is what is output by
kubectl describe nodes | grep -A10 Allocatable | grep cpu
If you add up all values output from each of these commands and divide those sums, you get the percentage shown in the Pulses CPU display.
For memory, it seems like the metrics are calculated similarly:
- "Current Memory" is what is output by
kubectl top nodes | awk '{print $3}'
- "Allocatable Memory" is what is output by
kubectl describe nodes | grep -A10 Allocatable | grep memory
Note that for allocatable memory, kubectl prints its output as Kibibytes, and K9s prints it in Mebibytes (multiples of 1024).
How I got this:
I followed the code by looking at pulse.go: https://github.com/derailed/k9s/blob/v0.25.18/internal/view/pulse.go#L162
The percentage is calculated from the S1 and S2 fields of the health
var. These seem to be set from the values in ccpu
an acpu
(CurrentCPU and AllocatableCPU, respectively), as defined in https://github.com/derailed/k9s/blob/v0.25.18/internal/model/pulse_health.go#L79.
The memory fields are treated similarly.
All the original values are set in NodesMetrics, in metrics.go: https://github.com/derailed/k9s/blob/v0.25.18/internal/client/metrics.go#L102. These seem to come from the NodeStatus in the Kubernetes v1 API: https://pkg.go.dev/k8s.io/api/core/v1#NodeStatus
Then, looking at the output from kubectl top and describe, the values always matched. Cross-checking in the kubectl codebase:
- for current CPU, it seems to use the v1.Node API as well: https://github.com/kubernetes/kubectl/blob/v0.24.1/pkg/cmd/top/top_node.go#L176
- for allocatable CPU, it also comes from NodeStatus: https://github.com/kubernetes/kubectl/blob/v0.24.1/pkg/describe/describe.go#L4057