Tweak advice about managing resources for containers

Co-authored-by: Shannon Kularathna <ax3shannonkularathna@gmail.com>
This commit is contained in:
Tim Bannister
2021-08-04 22:20:41 +01:00
parent 532affacb0
commit 367faca49f
@@ -1,22 +1,24 @@
--- ---
title: Managing Resources for Containers title: Resource Management for Pods and Containers
content_type: concept content_type: concept
weight: 40 weight: 40
feature: feature:
title: Automatic bin packing title: Automatic bin packing
description: > description: >
Automatically places containers based on their resource requirements and other constraints, while not sacrificing availability. Mix critical and best-effort workloads in order to drive up utilization and save even more resources. Automatically places containers based on their resource requirements and other constraints, while not sacrificing availability.
Mix critical and best-effort workloads in order to drive up utilization and save even more resources.
--- ---
<!-- overview --> <!-- overview -->
When you specify a {{< glossary_tooltip term_id="pod" >}}, you can optionally specify how When you specify a {{< glossary_tooltip term_id="pod" >}}, you can optionally specify how
much of each resource a {{< glossary_tooltip text="Container" term_id="container" >}} needs. much of each resource a {{< glossary_tooltip text="container" term_id="container" >}} needs.
The most common resources to specify are CPU and memory (RAM); there are others. The most common resources to specify are CPU and memory (RAM); there are others.
When you specify the resource _request_ for Containers in a Pod, the scheduler uses this When you specify the resource _request_ for containers in a Pod, the
{{< glossary_tooltip text="kube-scheduler" term_id="kube-scheduler" >}} uses this
information to decide which node to place the Pod on. When you specify a resource _limit_ information to decide which node to place the Pod on. When you specify a resource _limit_
for a Container, the kubelet enforces those limits so that the running container is not for a container, the kubelet enforces those limits so that the running container is not
allowed to use more of that resource than the limit you set. The kubelet also reserves allowed to use more of that resource than the limit you set. The kubelet also reserves
at least the _request_ amount of that system resource specifically for that container at least the _request_ amount of that system resource specifically for that container
to use. to use.
@@ -33,7 +35,7 @@ For example, if you set a `memory` request of 256 MiB for a container, and that
a Pod scheduled to a Node with 8GiB of memory and no other Pods, then the container can try to use a Pod scheduled to a Node with 8GiB of memory and no other Pods, then the container can try to use
more RAM. more RAM.
If you set a `memory` limit of 4GiB for that Container, the kubelet (and If you set a `memory` limit of 4GiB for that container, the kubelet (and
{{< glossary_tooltip text="container runtime" term_id="container-runtime" >}}) enforce the limit. {{< glossary_tooltip text="container runtime" term_id="container-runtime" >}}) enforce the limit.
The runtime prevents the container from using more than the configured resource limit. For example: The runtime prevents the container from using more than the configured resource limit. For example:
when a process in the container tries to consume more than the allowed amount of memory, when a process in the container tries to consume more than the allowed amount of memory,
@@ -45,8 +47,8 @@ or by enforcement (the system prevents the container from ever exceeding the lim
runtimes can have different ways to implement the same restrictions. runtimes can have different ways to implement the same restrictions.
{{< note >}} {{< note >}}
If a Container specifies its own memory limit, but does not specify a memory request, Kubernetes If a container specifies its own memory limit, but does not specify a memory request, Kubernetes
automatically assigns a memory request that matches the limit. Similarly, if a Container specifies its own automatically assigns a memory request that matches the limit. Similarly, if a container specifies its own
CPU limit, but does not specify a CPU request, Kubernetes automatically assigns a CPU request that matches CPU limit, but does not specify a CPU request, Kubernetes automatically assigns a CPU request that matches
the limit. the limit.
{{< /note >}} {{< /note >}}
@@ -56,7 +58,7 @@ the limit.
*CPU* and *memory* are each a *resource type*. A resource type has a base unit. *CPU* and *memory* are each a *resource type*. A resource type has a base unit.
CPU represents compute processing and is specified in units of [Kubernetes CPUs](#meaning-of-cpu). CPU represents compute processing and is specified in units of [Kubernetes CPUs](#meaning-of-cpu).
Memory is specified in units of bytes. Memory is specified in units of bytes.
If you're using Kubernetes v1.14 or newer, you can specify _huge page_ resources. For Linux workloads, you can specify _huge page_ resources.
Huge pages are a Linux-specific feature where the node kernel allocates blocks of memory Huge pages are a Linux-specific feature where the node kernel allocates blocks of memory
that are much larger than the default page size. that are much larger than the default page size.
@@ -76,9 +78,10 @@ consumed. They are distinct from
[Services](/docs/concepts/services-networking/service/) are objects that can be read and modified [Services](/docs/concepts/services-networking/service/) are objects that can be read and modified
through the Kubernetes API server. through the Kubernetes API server.
## Resource requests and limits of Pod and Container ## Resource requests and limits of Pod and container
Each Container of a Pod can specify one or more of the following: For each container, you can specify resource limits and requests,
including the following:
* `spec.containers[].resources.limits.cpu` * `spec.containers[].resources.limits.cpu`
* `spec.containers[].resources.limits.memory` * `spec.containers[].resources.limits.memory`
@@ -87,49 +90,64 @@ Each Container of a Pod can specify one or more of the following:
* `spec.containers[].resources.requests.memory` * `spec.containers[].resources.requests.memory`
* `spec.containers[].resources.requests.hugepages-<size>` * `spec.containers[].resources.requests.hugepages-<size>`
Although requests and limits can only be specified on individual Containers, it Although you can only specify requests and limits for individual containers,
is convenient to talk about Pod resource requests and limits. A it is also useful to think about the overall resource requests and limits for
*Pod resource request/limit* for a particular resource type is the sum of the a Pod.
resource requests/limits of that type for each Container in the Pod. For a particular resource, a *Pod resource request/limit* is the sum of the
resource requests/limits of that type for each container in the Pod.
## Resource units in Kubernetes ## Resource units in Kubernetes
### Meaning of CPU ### CPU resource units {#meaning-of-cpu}
Limits and requests for CPU resources are measured in *cpu* units. Limits and requests for CPU resources are measured in *cpu* units.
One cpu, in Kubernetes, is equivalent to **1 vCPU/Core** for cloud providers and **1 hyperthread** on bare-metal Intel processors. In Kubernetes, 1 CPU unit is equivalent to **1 physical CPU core**,
or **1 virtual core**, depending on whether the node is a physical host
or a virtual machine running inside a physical machine.
Fractional requests are allowed. When you define a container with Fractional requests are allowed. When you define a container with
`spec.containers[].resources.requests.cpu` set to `0.5`, you are requesting half `spec.containers[].resources.requests.cpu` set to `0.5`, you are requesting half
as much CPU time compared to if you asked for `1.0` CPU. as much CPU time compared to if you asked for `1.0` CPU.
For CPU resource units, the expression `0.1` is equivalent to the For CPU resource units, the [quantity](/docs/reference/kubernetes-api/common-definitions/quantity/) expression `0.1` is equivalent to the
expression `100m`, which can be read as "one hundred millicpu". Some people say expression `100m`, which can be read as "one hundred millicpu". Some people say
"one hundred millicores", and this is understood to mean the same thing. A "one hundred millicores", and this is understood to mean the same thing.
request with a decimal point, like `0.1`, is converted to `100m` by the API, and
precision finer than `1m` is not allowed. For this reason, the form `100m` might
be preferred.
CPU is always requested as an absolute quantity, never as a relative quantity; CPU resource is always specified as an absolute amount of resource, never as a relative amount. For example,
0.1 is the same amount of CPU on a single-core, dual-core, or 48-core machine. `500m` CPU represents the roughly same amount of computing power whether that container
runs on a single-core, dual-core, or 48-core machine.
### Meaning of memory {{< note >}}
Kubernetes doesn't allow you to specify CPU resources with a precision finer than
`1m`. Because of this, it's useful to specify CPU units less than `1.0` or `1000m` using
the milliCPU form; for example, `5m` rather than `0.005`.
{{< /note >}}
### Memory resource units {#meaning-of-memory}
Limits and requests for `memory` are measured in bytes. You can express memory as Limits and requests for `memory` are measured in bytes. You can express memory as
a plain integer or as a fixed-point number using one of these suffixes: a plain integer or as a fixed-point number using one of these
E, P, T, G, M, k, m (millis). You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, [quantity](/docs/reference/kubernetes-api/common-definitions/quantity/) suffixes:
E, P, T, G, M, k. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi,
Mi, Ki. For example, the following represent roughly the same value: Mi, Ki. For example, the following represent roughly the same value:
```shell ```shell
128974848, 129e6, 129M, 128974848000m, 123Mi 128974848, 129e6, 129M, 128974848000m, 123Mi
``` ```
Here's an example. Take care about case for suffixes. If you request `400m` of memory, this is a request
The following Pod has two Containers. Each Container has a request of 0.25 cpu for 0.4 bytes. Someone who types that probably meant to ask for 400 mebibytes (`400Mi`)
and 64MiB (2<sup>26</sup> bytes) of memory. Each Container has a limit of 0.5 or 400 megabytes (`400M`).
cpu and 128MiB of memory. You can say the Pod has a request of 0.5 cpu and 128
MiB of memory, and a limit of 1 cpu and 256MiB of memory. ## Container resources example {#example-1}
The following Pod has two containers. Both containers are defined with a request for
0.25 CPU
and 64MiB (2<sup>26</sup> bytes) of memory. Each container has a limit of 0.5
CPU and 128MiB of memory. You can say the Pod has a request of 0.5 CPU and 128
MiB of memory, and a limit of 1 CPU and 256MiB of memory.
```yaml ```yaml
---
apiVersion: v1 apiVersion: v1
kind: Pod kind: Pod
metadata: metadata:
@@ -162,56 +180,54 @@ When you create a Pod, the Kubernetes scheduler selects a node for the Pod to
run on. Each node has a maximum capacity for each of the resource types: the run on. Each node has a maximum capacity for each of the resource types: the
amount of CPU and memory it can provide for Pods. The scheduler ensures that, amount of CPU and memory it can provide for Pods. The scheduler ensures that,
for each resource type, the sum of the resource requests of the scheduled for each resource type, the sum of the resource requests of the scheduled
Containers is less than the capacity of the node. Note that although actual memory containers is less than the capacity of the node.
Note that although actual memory
or CPU resource usage on nodes is very low, the scheduler still refuses to place or CPU resource usage on nodes is very low, the scheduler still refuses to place
a Pod on a node if the capacity check fails. This protects against a resource a Pod on a node if the capacity check fails. This protects against a resource
shortage on a node when resource usage later increases, for example, during a shortage on a node when resource usage later increases, for example, during a
daily peak in request rate. daily peak in request rate.
## How Pods with resource limits are run ## How Kubernetes applies resource requests and limits {#how-pods-with-resource-limits-are-run}
When the kubelet starts a Container of a Pod, it passes the CPU and memory limits When the kubelet starts a container as part of a Pod, the kubelet passes that container's
to the container runtime. requests and limits for memory and CPU to the container runtime.
When using Docker: On Linux, the container runtime typically configures
kernel {{< glossary_tooltip text="cgroups" term_id="cgroup" >}} that apply and enforce the
limits you defined.
- The `spec.containers[].resources.requests.cpu` is converted to its core value, - The CPU limit defines a hard ceiling on how much CPU time that the container can use.
which is potentially fractional, and multiplied by 1024. The greater of this number During each scheduling interval (time slice), the Linux kernel checks to see if this
or 2 is used as the value of the limit is exceeded; if so, the kernel waits before allowing that cgroup to resume execution.
[`--cpu-shares`](https://docs.docker.com/engine/reference/run/#cpu-share-constraint) - The CPU request typically defines a weighting. If several different containers (cgroups)
flag in the `docker run` command. want to run on a contended system, workloads with larger CPU requests are allocated more
CPU time than workloads with small requests.
- The memory request is mainly used during (Kubernetes) Pod scheduling. On a node that uses
cgroups v2, the container runtime might use the memory request as a hint to set
`memory.min` and `memory.low`.
- The memory limit defines a memory limit for that cgroup. If the container tries to
allocate more memory than this limit, the Linux kernel out-of-memory subsystem activates
and, typically, intervenes by stopping one of the processes in the container that tried
to allocate memory. If that process is the container's PID 1, and the container is marked
as restartable, Kubernetes restarts the container.
- The memory limit for the Pod or container can also apply to pages in memory backed
volumes, such as an `emptyDir`. The kubelet tracks `tmpfs` emptyDir volumes as container
memory use, rather than as local ephemeral storage.
- The `spec.containers[].resources.limits.cpu` is converted to its millicore value and If a container exceeds its memory request and the node that it runs on becomes short of
multiplied by 100. The resulting value is the total amount of CPU time in microseconds memory overall, it is likely that the Pod the container belongs to will be
that a container can use every 100ms. A container cannot use more than its share of {{< glossary_tooltip text="evicted" term_id="eviction" >}}.
CPU time during this interval.
{{< note >}} A container might or might not be allowed to exceed its CPU limit for extended periods of time.
The default quota period is 100ms. The minimum resolution of CPU quota is 1ms. However, container runtimes don't terminate Pods or containers for excessive CPU usage.
{{</ note >}}
- The `spec.containers[].resources.limits.memory` is converted to an integer, and To determine whether a container cannot be scheduled or is being killed due to resource limits,
used as the value of the see the [Troubleshooting](#troubleshooting) section.
[`--memory`](https://docs.docker.com/engine/reference/run/#/user-memory-constraints)
flag in the `docker run` command.
If a Container exceeds its memory limit, it might be terminated. If it is
restartable, the kubelet will restart it, as with any other type of runtime
failure.
If a Container exceeds its memory request, it is likely that its Pod will
be evicted whenever the node runs out of memory.
A Container might or might not be allowed to exceed its CPU limit for extended
periods of time. However, it will not be killed for excessive CPU usage.
To determine whether a Container cannot be scheduled or is being killed due to
resource limits, see the
[Troubleshooting](#troubleshooting) section.
### Monitoring compute & memory resource usage ### Monitoring compute & memory resource usage
The resource usage of a Pod is reported as part of the Pod status. The kubelet reports the resource usage of a Pod as part of the Pod
[`status`](/docs/concepts/overview/working-with-objects/kubernetes-objects/#object-spec-and-status).
If optional [tools for monitoring](/docs/tasks/debug-application-cluster/resource-usage-monitoring/) If optional [tools for monitoring](/docs/tasks/debug-application-cluster/resource-usage-monitoring/)
are available in your cluster, then Pod resource usage can be retrieved either are available in your cluster, then Pod resource usage can be retrieved either
@@ -309,21 +325,26 @@ than as local ephemeral storage.
### Setting requests and limits for local ephemeral storage ### Setting requests and limits for local ephemeral storage
You can use _ephemeral-storage_ for managing local ephemeral storage. Each Container of a Pod can specify one or more of the following: You can specify `ephemeral-storage` for managing local ephemeral storage. Each
container of a Pod can specify either or both of the following:
* `spec.containers[].resources.limits.ephemeral-storage` * `spec.containers[].resources.limits.ephemeral-storage`
* `spec.containers[].resources.requests.ephemeral-storage` * `spec.containers[].resources.requests.ephemeral-storage`
Limits and requests for `ephemeral-storage` are measured in bytes. You can express storage as Limits and requests for `ephemeral-storage` are measured in byte quantities.
a plain integer or as a fixed-point number using one of these suffixes: You can express storage as a plain integer or as a fixed-point number using one of these suffixes:
E, P, T, G, M, K. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, E, P, T, G, M, K. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi,
Mi, Ki. For example, the following represent roughly the same value: Mi, Ki. For example, the following quantities all represent roughly the same value:
```shell - `128974848`
128974848, 129e6, 129M, 123Mi - `129e6`
``` - `129M`
- `123Mi`
In the following example, the Pod has two Containers. Each Container has a request of 2GiB of local ephemeral storage. Each Container has a limit of 4GiB of local ephemeral storage. Therefore, the Pod has a request of 4GiB of local ephemeral storage, and a limit of 8GiB of local ephemeral storage. In the following example, the Pod has two containers. Each container has a request of
2GiB of local ephemeral storage. Each container has a limit of 4GiB of local ephemeral
storage. Therefore, the Pod has a request of 4GiB of local ephemeral storage, and
a limit of 8GiB of local ephemeral storage.
```yaml ```yaml
apiVersion: v1 apiVersion: v1
@@ -360,9 +381,11 @@ spec:
### How Pods with ephemeral-storage requests are scheduled ### How Pods with ephemeral-storage requests are scheduled
When you create a Pod, the Kubernetes scheduler selects a node for the Pod to When you create a Pod, the Kubernetes scheduler selects a node for the Pod to
run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods. For more information, see [Node Allocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable). run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods.
For more information, see
[Node Allocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
The scheduler ensures that the sum of the resource requests of the scheduled Containers is less than the capacity of the node. The scheduler ensures that the sum of the resource requests of the scheduled containers is less than the capacity of the node.
### Ephemeral storage consumption management {#resource-emphemeralstorage-consumption} ### Ephemeral storage consumption management {#resource-emphemeralstorage-consumption}
@@ -376,7 +399,7 @@ kubelet measures storage use in:
If a Pod is using more ephemeral storage than you allow it to, the kubelet If a Pod is using more ephemeral storage than you allow it to, the kubelet
sets an eviction signal that triggers Pod eviction. sets an eviction signal that triggers Pod eviction.
For container-level isolation, if a Container's writable layer and log For container-level isolation, if a container's writable layer and log
usage exceeds its storage limit, the kubelet marks the Pod for eviction. usage exceeds its storage limit, the kubelet marks the Pod for eviction.
For pod-level isolation the kubelet works out an overall Pod storage limit by For pod-level isolation the kubelet works out an overall Pod storage limit by
@@ -493,15 +516,19 @@ Plugin](/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)
for how to advertise device plugin managed resources on each node. for how to advertise device plugin managed resources on each node.
##### Other resources ##### Other resources
To advertise a new node-level extended resource, the cluster operator can To advertise a new node-level extended resource, the cluster operator can
submit a `PATCH` HTTP request to the API server to specify the available submit a `PATCH` HTTP request to the API server to specify the available
quantity in the `status.capacity` for a node in the cluster. After this quantity in the `status.capacity` for a node in the cluster. After this
operation, the node's `status.capacity` will include a new resource. The operation, the node's `status.capacity` will include a new resource. The
`status.allocatable` field is updated automatically with the new resource `status.allocatable` field is updated automatically with the new resource
asynchronously by the kubelet. Note that because the scheduler uses the node asynchronously by the kubelet.
`status.allocatable` value when evaluating Pod fitness, there may be a short
delay between patching the node capacity with a new resource and the first Pod Because the scheduler uses the node's `status.allocatable` value when
that requests the resource to be scheduled on that node. evaluating Pod fitness, the scheduler only takes account of the new value after
that asynchronous update. There may be a short delay between patching the
node capacity with a new resource and the time when the first Pod that requests
the resource can be scheduled on that node.
**Example:** **Example:**
@@ -611,27 +638,32 @@ spec:
## PID limiting ## PID limiting
Process ID (PID) limits allow for the configuration of a kubelet to limit the number of PIDs that a given Pod can consume. See [Pid Limiting](/docs/concepts/policy/pid-limiting/) for information. Process ID (PID) limits allow for the configuration of a kubelet
to limit the number of PIDs that a given Pod can consume. See
[PID Limiting](/docs/concepts/policy/pid-limiting/) for information.
## Troubleshooting ## Troubleshooting
### My Pods are pending with event message failedScheduling ### My Pods are pending with event message `FailedScheduling`
If the scheduler cannot find any node where a Pod can fit, the Pod remains If the scheduler cannot find any node where a Pod can fit, the Pod remains
unscheduled until a place can be found. An event is produced each time the unscheduled until a place can be found. An
scheduler fails to find a place for the Pod, like this: [Event](/docs/reference/kubernetes-api/cluster-resources/event-v1/) is produced
each time the scheduler fails to find a place for the Pod. You can use `kubectl`
to view the events for a Pod; for example:
```shell ```shell
kubectl describe pod frontend | grep -A 3 Events kubectl describe pod frontend | grep -A 9999999999 Events
``` ```
``` ```
Events: Events:
FirstSeen LastSeen Count From Subobject PathReason Message Type Reason Age From Message
36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others ---- ------ ---- ---- -------
Warning FailedScheduling 23s default-scheduler 0/42 nodes available: insufficient cpu
``` ```
In the preceding example, the Pod named "frontend" fails to be scheduled due to In the preceding example, the Pod named "frontend" fails to be scheduled due to
insufficient CPU resource on the node. Similar error messages can also suggest insufficient CPU resource on any node. Similar error messages can also suggest
failure due to insufficient memory (PodExceedsFreeMemory). In general, if a Pod failure due to insufficient memory (PodExceedsFreeMemory). In general, if a Pod
is pending with a message of this type, there are several things to try: is pending with a message of this type, there are several things to try:
@@ -640,6 +672,9 @@ is pending with a message of this type, there are several things to try:
- Check that the Pod is not larger than all the nodes. For example, if all the - Check that the Pod is not larger than all the nodes. For example, if all the
nodes have a capacity of `cpu: 1`, then a Pod with a request of `cpu: 1.1` will nodes have a capacity of `cpu: 1`, then a Pod with a request of `cpu: 1.1` will
never be scheduled. never be scheduled.
- Check for node taints. If most of your nodes are tainted, and the new Pod does
not tolerate that taint, the scheduler only considers placements onto the
remaining nodes that don't have that taint.
You can check node capacities and amounts allocated with the You can check node capacities and amounts allocated with the
`kubectl describe nodes` command. For example: `kubectl describe nodes` command. For example:
@@ -674,31 +709,46 @@ Allocated resources:
680m (34%) 400m (20%) 920Mi (11%) 1070Mi (13%) 680m (34%) 400m (20%) 920Mi (11%) 1070Mi (13%)
``` ```
In the preceding output, you can see that if a Pod requests more than 1120m In the preceding output, you can see that if a Pod requests more than 1.120 CPUs,
CPUs or 6.23Gi of memory, it will not fit on the node. or more than 6.23Gi of memory, that Pod will not fit on the node.
By looking at the `Pods` section, you can see which Pods are taking up space on By looking at the Pods section, you can see which Pods are taking up space on
the node. the node.
The amount of resources available to Pods is less than the node capacity, because The amount of resources available to Pods is less than the node capacity, because
system daemons use a portion of the available resources. The `allocatable` field system daemons use a portion of the available resources. Within the Kubernetes API,
[NodeStatus](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#nodestatus-v1-core) each Node has a `.status.allocatable` field
gives the amount of resources that are available to Pods. For more information, see (see [NodeStatus](/docs/reference/kubernetes-api/cluster-resources/node-v1/#NodeStatus)
[Node Allocatable Resources](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md). for details).
The [resource quota](/docs/concepts/policy/resource-quotas/) feature can be configured The `.status.allocatable` field describes the amount of resources that are available
to limit the total amount of resources that can be consumed. If used in conjunction to Pods on that node (for example: 15 virtual CPUs and 7538 MiB of memory).
with namespaces, it can prevent one team from hogging all the resources. For more information on node allocatable resources in Kubernetes, see
[Reserve Compute Resources for System Daemons](/docs/tasks/administer-cluster/reserve-compute-resources/).
### My Container is terminated You can configure [resource quotas](/docs/concepts/policy/resource-quotas/)
to limit the total amount of resources that a namespace can consume.
Kubernetes enforces quotas for objects in particular namespace when there is a
ResourceQuota in that namespace.
For example, if you assign specific namespaces to different teams, you
can add ResourceQuotas into those namespaces. Setting resource quotas helps to
prevent one team from using so much of any resource that this over-use affects other teams.
Your Container might get terminated because it is resource-starved. To check You should also consider what access you grant to that namespace:
whether a Container is being killed because it is hitting a resource limit, call **full** write access to a namespace allows someone with that access to remove any
resource, include a configured ResourceQuota.
### My container is terminated
Your container might get terminated because it is resource-starved. To check
whether a container is being killed because it is hitting a resource limit, call
`kubectl describe pod` on the Pod of interest: `kubectl describe pod` on the Pod of interest:
```shell ```shell
kubectl describe pod simmemleak-hra99 kubectl describe pod simmemleak-hra99
``` ```
The output is similar to:
``` ```
Name: simmemleak-hra99 Name: simmemleak-hra99
Namespace: default Namespace: default
@@ -709,57 +759,48 @@ Status: Running
Reason: Reason:
Message: Message:
IP: 10.244.2.75 IP: 10.244.2.75
Replication Controllers: simmemleak (1/1 replicas created)
Containers: Containers:
simmemleak: simmemleak:
Image: saadali/simmemleak Image: saadali/simmemleak:latest
Limits: Limits:
cpu: 100m cpu: 100m
memory: 50Mi memory: 50Mi
State: Running State: Running
Started: Tue, 07 Jul 2015 12:54:41 -0700 Started: Tue, 07 Jul 2019 12:54:41 -0700
Last Termination State: Terminated Last State: Terminated
Exit Code: 1 Reason: OOMKilled
Started: Fri, 07 Jul 2015 12:54:30 -0700 Exit Code: 137
Finished: Fri, 07 Jul 2015 12:54:33 -0700 Started: Fri, 07 Jul 2019 12:54:30 -0700
Ready: False Finished: Fri, 07 Jul 2019 12:54:33 -0700
Restart Count: 5 Ready: False
Restart Count: 5
Conditions: Conditions:
Type Status Type Status
Ready False Ready False
Events: Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message Type Reason Age From Message
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f ---- ------ ---- ---- -------
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine Normal Scheduled 42s default-scheduler Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d Normal Pulled 41s kubelet Container image "saadali/simmemleak:latest" already present on machine
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d Normal Created 41s kubelet Created container simmemleak
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a Normal Started 40s kubelet Started container simmemleak
Normal Killing 32s kubelet Killing container with id ead3fb35-5cf5-44ed-9ae1-488115be66c6: Need to kill Pod
``` ```
In the preceding example, the `Restart Count: 5` indicates that the `simmemleak` In the preceding example, the `Restart Count: 5` indicates that the `simmemleak`
Container in the Pod was terminated and restarted five times. container in the Pod was terminated and restarted five times (so far).
The `OOMKilled` reason shows that the container tried to use more memory than its limit.
You can call `kubectl get pod` with the `-o go-template=...` option to fetch the status Your next step might be to check the application code for a memory leak. If you
of previously terminated Containers: find that the application is behaving how you expect, consider setting a higher
memory limit (and possibly request) for that container.
```shell
kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-hra99
```
```
Container Name: simmemleak
LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]
```
You can see that the Container was terminated because of `reason:OOM Killed`, where `OOM` stands for Out Of Memory.
## {{% heading "whatsnext" %}} ## {{% heading "whatsnext" %}}
* Get hands-on experience [assigning Memory resources to Containers and Pods](/docs/tasks/configure-pod-container/assign-memory-resource/). * Get hands-on experience [assigning Memory resources to containers and Pods](/docs/tasks/configure-pod-container/assign-memory-resource/).
* Get hands-on experience [assigning CPU resources to Containers and Pods](/docs/tasks/configure-pod-container/assign-cpu-resource/). * Get hands-on experience [assigning CPU resources to containers and Pods](/docs/tasks/configure-pod-container/assign-cpu-resource/).
* For more details about the difference between requests and limits, see * Read how the API reference defines a [container](/docs/reference/kubernetes-api/workload-resources/pod-v1/#Container)
[Resource QoS](https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md). and its [resource requirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources)
* Read the [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) API reference
* Read the [ResourceRequirements](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcerequirements-v1-core) API reference
* Read about [project quotas](https://xfs.org/docs/xfsdocs-xml-dev/XFS_User_Guide/tmp/en-US/html/xfs-quotas.html) in XFS * Read about [project quotas](https://xfs.org/docs/xfsdocs-xml-dev/XFS_User_Guide/tmp/en-US/html/xfs-quotas.html) in XFS
* Read more about the [kube-scheduler Policy reference (v1)](/docs/reference/config-api/kube-scheduler-policy-config.v1/) * Read more about the [kube-scheduler Policy reference (v1)](/docs/reference/config-api/kube-scheduler-policy-config.v1/)