A memory request is a configuration that sets the guaranteed amount of memory that a
container will be able to use. It is part of the resource management functionality of
Kubernetes, which allows for the control and allocation of computational
resources to containers.

When a memory request is set for a container, Kubernetes will only schedule it on a node that can give it that resource,
thereby guaranteeing that the container can use the specified requested memory.


== Why is this an issue?

Without a memory request, a container can potentially be scheduled on a node where
there are not enough resources for it. This can lead to unpredictable behavior of the container and the node itself.


=== What is the potential impact?

==== Unpredictable Resource Allocation


Without defined requests, Kubernetes doesn't know how much of a particular resource
to allocate to a container. This can lead to unpredictable behavior, as the Kubernetes scheduler may
not make optimal decisions about pod placement and resource contention management.
For instance, a container might not get the resources it needs to function correctly, leading to
performance issues or even failure of the container.


==== System Instability

In the worst-case scenario, if a container uses more resources than a node can
handle (due to lack of defined requests), it can cause the node to run out of
resources. This can lead to system instability, and in extreme cases, the node
might crash, causing downtime for all containers running on that node.


== How to fix it

=== Code examples

To avoid potential issues, either specify a memory request for each container in a pod specification
or create a resource of a kind, `LimitRange`,
that sets a default memory request for all containers in all pod specifications belonging to the same namespace.

==== Noncompliant code example

[source,yaml,diff-id=1,diff-type=noncompliant]
----
apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
    - name: web # Noncompliant
      image: nginx
----

[source,yaml,diff-id=2,diff-type=noncompliant]
----
apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
    - name: web # Noncompliant
      image: nginx
----


==== Compliant solution

[source,yaml,diff-id=1,diff-type=compliant]
----
apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
    - name: web
      image: nginx
      resources:
        requests:
          memory: 100Mi
----

[source,yaml,diff-id=2,diff-type=compliant]
----
apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
  namespace: default-mem-example
spec:
  limits:
    - type: Container
      defaultRequest:
        memory: 100Mi
---
apiVersion: v1
kind: Pod
metadata:
  name: example
  namespace: default-mem-example
spec:
  containers:
    - name: web
      image: nginx
----


=== How does this work?

A request can be set through the property `resources.requests.memory` of a
container. Alternatively, a default request for a namespace can be set with
`LimitRange` through `spec.limits[].defaultRequest.memory`.

== Resources

=== Documentation

* Kubernetes Documentation - https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/[Configure Default Memory Requests and Limits for a Namespace]

=== Articles & blog posts
* Google Cloud Blog - https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits[Kubernetes best practices: Resource requests and limits]

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Specify a memory request for this container.


=== Highlighting

* Highlight the key of the first child of the container that does not specify a memory request.


endif::env-github,rspecator-view[]
