if `Static` policy is used, `--reserved-memory` is obligatory.
Also, avoid the following configurations:
1. duplicates, i.e. the same NUMA node or memory type, but with a different value;
1. setting zero limit for any of memory types;
1. NUMA node IDs that do not exist in the machine hardware;
1. memory type names different than `memory` or `hugepages-<size>`
(hugepages of particular `<size>` should also exist).
Syntax:
`--reserved-memory N:memory-type1=value1,memory-type2=value2,...`
* `N` (integer) - NUMA node index, e.g. `0`
* `memory-type` (string) - represents memory type:
* `memory` - conventional memory
* `hugepages-2Mi` or `hugepages-1Gi` - hugepages
* `value` (string) - the quantity of reserved memory, e.g. `1Gi`
Example usage:
`--reserved-memory 0:memory=1Gi,hugepages-1Gi=2Gi`
or
`--reserved-memory 0:memory=1Gi --reserved-memory 1:memory=2Gi`
or
`--reserved-memory '0:memory=1Gi;1:memory=2Gi'`
When you specify values for `--reserved-memory` flag, you must comply with the setting that
you prior provided via Node Allocatable Feature flags.
That is, the following rule must be obeyed for each memory type:
`sum(reserved-memory(i)) = kube-reserved + system-reserved + eviction-threshold`,
where `i` is an index of a NUMA node.
If you do not follow the formula above, the Memory Manager will show an error on startup.
In other words, the example above illustrates that for the conventional memory (`type=memory`),
we reserve `3Gi` in total, i.e.:
`sum(reserved-memory(i)) = reserved-memory(0) + reserved-memory(1) = 1Gi + 2Gi = 3Gi`
An example of kubelet command-line arguments relevant to the node Allocatable configuration:
* `--kube-reserved=cpu=500m,memory=50Mi`
* `--system-reserved=cpu=123m,memory=333Mi`
* `--eviction-hard=memory.available<500Mi`
{{< note >}}
The default hard eviction threshold is 100MiB, and **not** zero.
Remember to increase the quantity of memory that you reserve by setting `--reserved-memory`
by that hard eviction threshold. Otherwise, the kubelet will not start Memory Manager and
display an error.
{{< /note >}}
Here is an example of a correct configuration:
```shell
--kube-reserved=cpu=4,memory=4Gi
--system-reserved=cpu=1,memory=1Gi
--memory-manager-policy=Static
--reserved-memory '0:memory=3Gi;1:memory=2148Mi'
```
Prior to Kubernetes 1.32, you also need to add
```shell
--feature-gates=MemoryManager=true
```
Let us validate the configuration above:
1. `kube-reserved + system-reserved + eviction-hard(default) = reserved-memory(0) + reserved-memory(1)`
1. `4GiB + 1GiB + 100MiB = 3GiB + 2148MiB`
1. `5120MiB + 100MiB = 3072MiB + 2148MiB`
1. `5220MiB = 5220MiB` (which is correct)
## Placing a Pod in the Guaranteed QoS class
If the selected policy is anything other than `None`, the Memory Manager identifies pods
that are in the `Guaranteed` QoS class.
The Memory Manager provides specific topology hints to the Topology Manager for each `Guaranteed` pod.
For pods in a QoS class other than `Guaranteed`, the Memory Manager provides default topology hints
to the Topology Manager.
The following excerpts from pod manifests assign a pod to the `Guaranteed` QoS class.
Pod with integer CPU(s) runs in the `Guaranteed` QoS class, when `requests` are equal to `limits`:
```yaml
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
requests:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
```
Also, a pod sharing CPU(s) runs in the `Guaranteed` QoS class, when `requests` are equal to `limits`.
```yaml
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "300m"
example.com/device: "1"
requests:
memory: "200Mi"
cpu: "300m"
example.com/device: "1"
```
Notice that both CPU and memory requests must be specified for a Pod to lend it to Guaranteed QoS class.
## Troubleshooting