Trace how a memory value in a Pod spec becomes an enforced limit: from the manifest to the cgroup to the OOM killer.
Quick Answer
The API server stores the quantity; the kubelet resolves it to an exact byte count and, via the container runtime, writes it to the container's cgroup (`memory.limit_in_bytes` on v1, `memory.max` on v2). The kernel then tracks the cgroup's usage and invokes the OOM killer when usage exceeds the limit — all in binary bytes.
Detailed Answer
1. You submit limits.memory: 512Mi. Kubernetes parses it into a resource.Quantity whose canonical value is 536,870,912 bytes. 2. The scheduler uses the *request* for bin-packing onto a node with enough allocatable memory. 3. On the node, the kubelet + CRI runtime (containerd/CRI-O) create the container's cgroup and set the memory limit to that byte count. 4. The kernel accounts the cgroup's anonymous memory + unreclaimable page cache. When it can't reclaim enough to stay under the limit, the cgroup OOM killer kills a process in that cgroup — usually your main container — surfacing as OOMKilled / exit 137.
Every layer here (Quantity canonicalization, cgroup byte value, kernel accounting) is binary-exact. That is precisely why declaring Mi/Gi — the same units the kernel uses — avoids surprises, and why M/G quietly under-provisions.
Code Example
# Inspect the effective cgroup limit from inside the container (cgroup v2)
kubectl exec api-0 -- cat /sys/fs/cgroup/memory.max
# 536870912 <- matches 512Mi exactly
# Node view of the pod's QoS + limits
kubectl get pod api-0 -o jsonpath='{.spec.containers[0].resources}'Interview Tip
Name the cgroup files (memory.max / memory.limit_in_bytes) and that the OOM killer is per-cgroup — concrete internals impress.