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"