Worker Node Reserved Resources
Worker Node Reserved Resources helps VKS protect system components on each worker node by reserving a portion of CPU and memory upfront β preventing user workloads from consuming all resources and pushing the node into a NotReady state.
Overview
Each worker node in a VKS cluster runs two groups of components alongside user workloads:
Group 1 β System processes running directly on the node OS (outside the Pod runtime):
kubelet
container runtime (containerd)
OS daemon (systemd, sshd, log agentβ¦)
Group 2 β System pods running in the kube-system namespace (including DaemonSets and Deployments):
kube-proxy
CNI agent
CoreDNS
CSI controller
Load Balancer controller
These two groups draw resources from two separate resource pools:
System processes
Reserved
System pods
Allocatable
Problem: If all node capacity is allocated to Pods, Group 1 system processes may run out of resources during a workload spike, leading to common failure modes:
Node transitions to NotReady state
kubelet / containerd is OOM killed
Node becomes unresponsive
Solution: VKS reserves a portion of CPU and memory for Group 1 at provisioning time. The remainder is allocated to:
User workload (your Pods)
Group 2 system pods
Formula: In kubectl describe node output, the Allocatable value is calculated as:
How VKS calculates reserved resources
VKS applies a tiered model with decreasing rates (progressive tiering): the larger the node, the lower the reserve ratio, because system overhead grows more slowly than total node capacity.
CPU reserved
Tiers are accumulated and added to a fixed 100m baseline:
Core 1
6%
Core 2
1%
Cores 3 β 4
0.5%
Core 5 and above
0.25%
Memory reserved
Tiers are accumulated and added to a fixed 200 MiB baseline:
0 β 4 GiB
25%
4 β 8 GiB
20%
8 β 16 GiB
10%
16 β 128 GiB
6%
Above 128 GiB
2%
How it is applied on the node
VKS injects the reserved parameters into the kubelet flag at node join time (via bootstrap config). Key behaviors:
The
kube-reservedvalue is subtracted directly from Allocatable β kube-scheduler never schedules user Pods into this portion.VKS does not configure
system-reservedseparately. Resources for OS daemons are protected indirectly through the kubelet's default eviction threshold.VKS uses
enforce-node-allocatable=pods(default upstream): kubelet only creates a cgroup hard-limit for kubepods; system processes are not bound to a dedicated cgroup.The reserved amount is calculated from the node group's Flavor at provisioning time and is immutable for the entire lifecycle of the node group. To apply a different Flavor, you need to provision a new node group with the desired Flavor, migrate workloads, then delete the old node group.
Reserved is immutable for the lifetime of the node group. To change the Flavor: provision a new node group β migrate workloads β delete the old node group.
Examples
Flavor 2 vCPU / 4 GiB
2 vCPU / 4 GiBCPU reserved:
Memory reserved:
β Kubelet flag: --kube-reserved=cpu=170m,memory=1224Mi
β Allocatable for Pods β 1830m CPU / 2872 MiB RAM
Flavor 4 vCPU / 8 GiB
4 vCPU / 8 GiBCPU:
100 + 60 + 10 + 2000Γ0.5% = 180mRAM:
200 + 4096Γ25% + 4096Γ20% = 200 + 1024 + 819.2 β 2044 MiB
β --kube-reserved=cpu=180m,memory=2044Mi
Flavor 8 vCPU / 16 GiB
8 vCPU / 16 GiBCPU:
100 + 60 + 10 + 10 + 4000Γ0.25% = 190mRAM:
200 + 1024 + 819.2 + 8192Γ10% = 2863 MiB
β --kube-reserved=cpu=190m,memory=2863Mi
Flavor 16 vCPU / 32 GiB
16 vCPU / 32 GiBCPU:
100 + 60 + 10 + 10 + 12000Γ0.25% = 210mRAM:
200 + 1024 + 819.2 + 819.2 + 16384Γ6% β 3846 MiB
β --kube-reserved=cpu=210m,memory=3846Mi
Quick reference table
2c / 4 GiB
170m
1224 MiB
~8.5%
~30%
4c / 8 GiB
180m
2044 MiB
~4.5%
~25%
8c / 16 GiB
190m
2863 MiB
~2.4%
~17%
16c / 32 GiB
210m
3846 MiB
~1.3%
~12%
32c / 64 GiB
250m
5810 MiB
~0.8%
~9%
Best practice: The larger the node, the higher the workload utilization. For production workloads that need to maximize resource efficiency, prefer fewer larger nodes over many small nodes.
Verify on your cluster
View the running kubelet configuration
Sample output on a VKS node:
Compare Capacity and Allocatable
The gap between Capacity and Allocatable equals kube-reserved + eviction-threshold.
Observe system process resource consumption
To observe the actual resource consumption of system processes protected by kube-reserved (kubelet, containerd, OS daemon), SSH into the node and inspect cgroups:
FAQ
Can I override the reserved amounts for my node? No. VKS manages the kubelet config to ensure node stability. Reserved is calculated automatically from the node group's Flavor and is not user-configurable.
Why do smaller Flavors have a higher RAM overhead ratio? Because system components have a fixed overhead (~200 MiB baseline). On a 4 GiB node, this baseline is a significant fraction of total memory, but on a 64 GiB node it is negligible. This is why production environments should use larger Flavors to optimize utilization.
Can reserved amounts change at runtime? No. Reserved is set at node join time and is immutable for the entire node lifecycle.
Can I change the Flavor of my current node group to reduce overhead? Node group Flavor is immutable for the lifetime of the node group. If you need a larger Flavor to reduce the overhead ratio, provision a new node group with the desired Flavor β migrate workloads β decommission the old node group.
Why is Allocatable slightly smaller than Capacity β kube-reserved?
Allocatable also subtracts the eviction threshold (default memory.available<100Mi) β a buffer that gives kubelet time to evict Pods before the node runs out of memory. Full formula: Allocatable = Capacity β kube-reserved β eviction-threshold.
Getting Started with Node Groups
View the list of available Flavors and specs
Create a new Node Group
Configure Auto Scaling for a Node Group
Last updated

