A CPU request is a configuration that sets the guaranteed amount of CPU cores 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 CPU 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 CPU cores.


== Why is this an issue?

Without a CPU 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. In this case, Kubernetes may throttle its CPU usage.
By setting a CPU request, Kubernetes will make sure that the container will get the requested CPU.


== How to fix it

=== Code examples

To avoid potential issues, either specify a CPU request for each container with `resources.requests.cpu` or create a resource of a kind `LimitRange` that sets a default CPU request for all containers in all pod specifications in a 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:
          cpu: 0.5
----

[source,yaml,diff-id=2,diff-type=compliant]
----
apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-request-range
  namespace: default-cpu-example
spec:
  limits:
  - defaultRequest:
      cpu: 0.5
    type: Container
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx-ns-compliant
  namespace: default-cpu-example
spec:
  containers:
  - name: nginx-ns-compliant
    image: nginx
----

=== How does this work?

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

== Resources

=== Documentation

* Kubernetes Documentation - https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/[Configure Default CPU 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 CPU request for this container.


=== Highlighting

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


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