Denial of Service and Resource Controls
Availability is the third of the three properties, and the one Kubernetes gives away by default: a container with no resources block may take the whole node. This guide measures that, then works outward through the container, the namespace, the apiserver and the node - reading each control off a live cluster.
Kubernetes Threat Model Guide 31 of 42 Intermediate
- Kubernetesapiserver v1.36.4, kubelet v1.36.3
- Runtimecontainerd 2.2.6
- CNICilium 1.18.1
- Built withkubeadm v1.36.3
- TimeAbout 18 min
Memory limits are enforced by the kernel's cgroup v2 controller, so exceeding one is an OOM kill at exit 137 rather than a Kubernetes decision. API Priority and Fairness has been on by default since 1.20.
- Host kernel7.0.0-29
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| CKA5001 | 192.168.0.41 | Ubuntu 26.04 LTS | Control Plane Node (tainted NoSchedule) | 2 Core | 4 GB | 50 GB |
| CKA5001-NODE01 | 192.168.0.42 | Ubuntu 26.04 LTS | Worker Node | 2 Core | 4 GB | 50 GB |
| CKA5001-NODE02 | 192.168.0.43 | Ubuntu 26.04 LTS | Worker Node | 2 Core | 4 GB | 50 GB |
| CKA5001-NODE03 | 192.168.0.44 | Ubuntu 26.04 LTS | Worker Node | 2 Core | 4 GB | 50 GB |
This guide includes
Use this when availability is part of the review. This matters because Kubernetes gives resources away by default - a Pod with no limits can take a node down - and the controls that stop it sit at three different levels.
- confirming the default really is no ceiling at all, across the entire cluster
- reading the cgroup interface from inside a container, then setting one memory limit and watching the kernel enforce it
- comparing the three QoS classes, including the one people consistently get wrong
- adding a LimitRange that fixes it for everyone in the namespace at once
- finding the two defences already in place - the API server's own, and what the node reserved for itself
Before you start
- guide 24 - quotas, which bound the namespace total.
- guide 10 - where the apiserver's own limits live.
-
The default, which is no ceiling at all
-
What the container can see of the node
-
One limit, and the kernel enforcing it
-
The three classes, and the one everybody gets wrong
-
The namespace control that fixes it for everyone
-
The apiserver defends itself, and always has
-
And the node keeps something back for itself