Limits
Limitaciones
Las limitaciones de recursos se especifican como limis
y request
, estas se indican en ram como Mi, Gi
referiendose a Mebibyte, y a cpu por unidades o Milicors, que 1 core es 1000 milicors, por lo tanto se especifican porcentajes como 0.1
o 100m
en un 10% de un core.
requests: Cantidad de recursos de las que el pod siempre va a disponer, se le reserva esa cantidad de ram o cpu a ese pod, es suya.
limits: Es la cantidad de ram o cpu hasta la que podrá llegar el pod en el caso de que el nodo lo permita, es decir una vez alcanzada la cantidad total de request tiene un margen para superar siempre que el nodo tenga recursos suficientes. Una vez se alcance el limite, kubernetes reinicia o elimina el pod, según se especifique.
Por defecto si un pod excede el limite de ram kubernetes lo reinicia, por otra parte si intentas crear un pod con el request y limit superior al de un nodo, kubernetes lo deja pendiente hasta encontrar un nodo en el que cumpla los requisitos.
En el caso de la cpu: cuando llega el pod al máximo del limite no pasa nada, kubernetes no reinicia el pod ni lo destruye, simplemente no le deja superar ese limite. Si al crear un pod su request y limit es superior al del nodo se queda en pendiente hasta haber un nodo que cumpla los requisitos.
Ejemplo de limites en un pod a nivel de container.
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr
image: nginx
resources:
limits:
memory: "500Mi"
cpu: "1200m"
requests:
memory: "200Mi"
cpu: "700m"
Qos Classes
Kubernetes usa clases de QoS para tomar decisiones sobre la programación y el desalojo de Pods.
Guaranteed: es el pod en el que el limite es igual al request.
Burstable: es el pod en el que el limite es superior al request, por lo tanto puede aumentar sus capacidades si están disponibles en el nodo.
BestEffort: es el pod en el que no se han establecido ningún tipo de limites, este tipo de pod puede ser peligroso ya que puede llegar a utilizar el total de recursos del nodo..
LimitRange
Permite controlar limites a nivel de objetos , los Containes, Pod, PersistentVolumeClaim
dentro de un namespace estarán limitados a los limites definidos.
Limites por defecto
Al poner un valor de limites por defecto, los objetos de un espacio de trabajo, en el caso de crearlos sin limites se aplican el de defecto.
En el siguiente manifiesto, se especifica un valor por defecto a los contenedores del namespace dev.
apiVersion: v1
kind: Namespace
metadata:
name: dev
labels:
name: dev
---
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
namespace: dev
spec:
limits:
- default:
memory: 512Mi
cpu: 1
defaultRequest:
memory: 256Mi
cpu: 0.5
type: Container
sudo kubectl describe limitrange -n dev
Name: mem-limit-range
Namespace: dev
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu - - 500m 1 -
Container memory - - 256Mi 512Mi -
Cuando creas un pod dentro del namespace dev sin limites definidos, se añaden los de defecto.
sudo kubectl run --generator=run-pod/v1 podtest --image=nginx:alpine --namespace dev
sudo kubectl describe pod podtest -n dev
Limits:
cpu: 1
memory: 512Mi
Requests:
cpu: 500m
memory: 256Mi
Mínimos y Máximos
Los valores mínimos y máximos en limitrange son los recursos mínimos y máximos que puede especificarse a un objeto, en caso que exceda el máximo o no llegue al mínimo, al crear el objeto dará un error y no lo creara, en el caso de no especificar limites en el objeto se añadirán los máximos permitidos.
apiVersion: v1
kind: Namespace
metadata:
name: prod
labels:
name: prod
---
apiVersion: v1
kind: LimitRange
metadata:
name: min-max
namespace: prod
spec:
limits:
- max:
memory: 1Gi
cpu: 1
min:
memory: 100Mi
cpu: 0.1
type: Container
---
apiVersion: v1
kind: Pod
metadata:
name: podtest
namespace: prod
labels:
app: backend
spec:
containers:
- name: contenedor1
image: nginx:alpine
resources:
limits:
memory: "500Mi"
cpu: 1
requests:
memory: "300Mi"
cpu: 0.5
sudo kubectl describe limitrange min-max -n prod
Name: min-max
Namespace: prod
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 100m 1 1 1 -
Container memory 100Mi 1Gi 1Gi 1Gi -
En el caso de exceder los limites dará un error similar a este.
sudo kubectl apply -f limit-range/limits-min-max.yml
namespace/prod unchanged
limitrange/min-max configured
Error from server (Forbidden): error when creating "limit-range/limits-min-max.yml": pods "podtest" is forbidden: maximum cpu usage per Container is 1, but limit is 2
ResourceQuota
Limita recursos a nivel de namespace, establece un limite de recursos que pueden consumir la sumatoria de todos los objetos dentro de el namespace indicado.
Una vez establecido el resourcequota, al crear contenedores tienen que tener obligatoriamente el request y el limit, en caso contrario no dejará crearlos.
apiVersion: v1
kind: Namespace
metadata:
name: prod
labels:
name: prod
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-demo
namespace: prod
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
Se puede ver que el namespace tiene unos limites y aún no tiene nada ocupado.
sudo kubectl describe ns prod
...
Resource Quotas
Name: mem-cpu-demo
Resource Used Hard
-------- --- ---
limits.cpu 0 2
limits.memory 0 2Gi
requests.cpu 0 1
requests.memory 0 1Gi
En este caso ya tiene objetos en su interior y a llegado al limite en request.
sudo kubectl describe resourceQuota -n prod
Name: mem-cpu-demo
Namespace: prod
Resource Used Hard
-------- ---- ----
limits.cpu 1 2
limits.memory 1000Mi 2Gi
requests.cpu 1 1
requests.memory 1000Mi 1Gi
Limitar pods
limitar el número de pods en un espacio de trabajo es otra opción que tiene resourceQuota.
apiVersion: v1
kind: Namespace
metadata:
name: prod
labels:
name: prod
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: pod-demo
namespace: prod
spec:
hard:
pods: "3"