Cuando se crea un pod se pueden reservar recursos de CPU y RAM para los contenedores que corren en el pod. Para reservar recursos, usa el campo resources: requests
en el fichero de configuración. Para establecer límites, usa el campo resources: limits
.
Kubernetes planifica un pod en un nodo sólo si el nodo tiene suficientes recursos de CPU y RAM disponibles para satisfacer la demanda de CPU y RAM total de todos los contenedores en el pod. Es decir, la request es la cantidad que necesita el pod para arrancar y ponerse en funcionamiento.
En función de las tareas que ejecute el pod, los recursos que consume pueden aumentar. Mediante el establecimiento de los limits podemos acotar el uso máximo de recursos disponible para el pod.
Kubernetes no permite que el pod consuma más recursos de CPU y RAM de los límites especificados para en el fichero de configuración.
Si un contenedor excede el límite de RAM, es eliminado.
Si un contenedor excede el límite de CPU, se convierte en un candidato para que su uso de CPU se vea restringido (throttling) .
Unidades de CPU y RAM
Los recursos de CPU se miden en cpus. Se admiten valores fraccionados. Puedes usar el sufijo m para indicar “mili”; por ejemplo, 100m cpu
son 100 milicpu
o 0.1 cpu
.
Los recursos de RAM se miden en bytes. Puedes indicar la RAM como un entero usando alguno de los siguientes sufijos: E
, P
, T
, G
, M
, Ei
, Pi
,Ti
, Gi
, Mi
y Ki
. Por ejemplo, las siguientes cantidades representan aproximadamente el mismo valor:
128974848, 129e6, 129M , 123Mi
Si no conoces por adelantado los recursos que reservar para un pod puedes lanzar la aplicación sin especificar límites, usar el monitor de uso de recursos y determinar los valores apropiados.
Si un contenedor excede los límites establecidos de RAM, se elimina al quedarse sin memoria disponible: out-of-memory
. Debes especificar un valor ligeramente superior al valor esperado para dar un poco de margen al pod.
Si especificas una reserva (request
), el pod tendrá garantizado disponer de la cantidad reservada del recurso. El pod puede usar más recursos que los reservados, pero nunca más del límite establecido.
En el siguiene ejemplo, especificamos tanto una reserva como el límite de recursos de los que puede disponer un pod:
apiVersion: v1
kind: Pod
metadata:
name: cpu-ram-demo
spec:
containers:
- name: cpu-ram-demo-container
image: gcr.io/google-samples/node-hello:1.0
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "1"
El pod reserva 64Mi de RAM y 0.25 cpus, pero puede llegar a usar hasta el doble de RAM y toda una CPU.
Si no especificas reservas o límites
Si no especificas un límite para la RAM, Kubernetes no restinge la cantidad de RAM que puede usar el contenedor. En esta situación un contenedor puede usar toda la memoria disponible en el nodo donde se está ejecutando. Del mismo modo, si no se especifica un límite máximo de CPU, un contenedor puede usar toda la capacidad de CPU del nodo.
Los límites por defecto se aplican en función de la disponibilidad de recursos aplicados al espacio de nombres en el que se ejecutan los pods. Puedes consultar los límites mediante: kubectl describe limitrange limits
.
Es importante tener en cuenta que si se especifican límites a nivel de namespace, la creación de objetos en el namespace debe incluir también los límites o se producirán errores al crear objetos (a no ser que se hayan especificado límites por defecto).
En Set Pod CPU and Memory Limits se indica cómo establecer límites superiores e inferiores para los recursos de un pod. También se pueden especificar límites por defecto para los pods aunque el usuario no los haya especificado en el fichero de configuración.
Los límites establecidos en el namespace se aplican durante la creación o modificación de los pods. Si cambias el rango de recursos permitidos, no afecta a los pods creados previamente en el espacio de nombres.
Se pueden establecer límites en los recursos consumidos por diferentes motivos, pero normalmente se limitan para evitar problemas a posteriori. Por ejemplo, si un nodo tiene 2GB de RAM, evitando la creación de pods que requieran más memoria previene que el pod no pueda desplegarse nunca (al no disponer de memoria suficiente disponible), por lo que es mejor evitar directamente su creación.
El otro motivo habitual para imponer límites es para distribuir los recursos del nodo entre los diferentes equipos/entornos; por ejemplo, asignando un 25% de la capacidad al equipo de desarrollo y el resto a los servicios en producción.
Actualización
En el caso de que se establezca sólo una de las dos opciones (es decir, sólo request o sólo límites), Kubernetes actúa de la siguiente manera:
- Si sólo se establecen límites, Kubernetes establece una reserva (request) igual al límite.
- Si sólo se establece una reserva, no hay un límite definido, por lo que el pod puede llegar a consumir el total de la memoria/CPU disponible en el nodo.