# Node

> Nodes are the only Kubernetes objects with a direct hourly cost: each is a cloud VM priced by the instance type in its node.kubernetes.io/instance-type label, and 20 half-empty nodes bill exactly like 20 full ones. ZopNight converts spec.providerID into the cloud VM record, parents every node to its EKS, GKE, or AKS pool, and captures capacity.

Source: https://zop.dev/integrations/kubernetes/node
Updated: 2026-08-19

---

A Kubernetes node is a worker machine registered with the API server. On EKS, GKE, and AKS it is a real cloud VM with an hourly rate. It is the one object in this Kubernetes section where the invoice is direct rather than implied.

## The one Kubernetes object the invoice meters

Every pod request in the cluster eventually lands on a node, and the node bills by instance type per hour regardless of how full it is. ZopNight reads the instance type from the `node.kubernetes.io/instance-type` label, falling back to the deprecated `beta.kubernetes.io` variant, and uses it to look up hourly pricing from the pricing cache. Packing density, not pod count, decides how much of that price is doing useful work: a half-empty node costs exactly what a full one does.

## From spec.providerID to a billable VM record

Kubernetes stamps each node with a `spec.providerID`, and discovery converts it into the native compute identifier so utilization for the underlying VM can be fetched. An `aws:///us-east-1a/i-0abc...` value becomes the bare `i-0abc...` instance ID, a `gce://project/zone/name` value becomes the full `//compute.googleapis.com/...` path, and `azure:///` values are kept as ARM resource IDs. Alongside that, the record carries status (Ready, NotReady, or Unknown), roles, kubelet version, architecture, CPU capacity in millicores, memory capacity in GB, pod capacity, taints, and node conditions.

## Pools own capacity; nodes only report it

Each node's parent in the inventory is its pool, resolved from provider labels: `eks.amazonaws.com/nodegroup`, `cloud.google.com/gke-nodepool`, or `kubernetes.azure.com/agentpool`. That mirrors how capacity is actually managed, since you resize a node group or agent pool and never an individual machine, so cost rollups happen at the pool level too.

```bash
kubectl get nodes -L node.kubernetes.io/instance-type,topology.kubernetes.io/zone
```

## Why the node-rightsizing rule stays switched off

A node CPU-underutilization rule exists in the recommender (30 percent average threshold with a 50 percent peak guard) but is deliberately not registered. Kubernetes metrics-server returns point-in-time snapshots in which average, maximum, and minimum are the same single value, which makes any average-versus-peak comparison dead code. Rather than ship unreliable downsize advice, node savings are left to workload rightsizing and scheduling until a real time-series source is available.
