k9s icon indicating copy to clipboard operation
k9s copied to clipboard

QUESTION: How are the Pulses Cpu and Mem totals being calculated?

Open FilBot3 opened this issue 3 years ago • 1 comments

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_cpu

k9s Pulses: Mem

k9s_pulses_memory

Kubectl describe nodes

kubectl_describe_notes_allocation

FilBot3 avatar Feb 11 '22 22:02 FilBot3

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

Pitxyoki avatar Jun 08 '22 16:06 Pitxyoki