Kubernetes - Quality of Service (QoS)
Descubre cómo Kubernetes utiliza los requests y limits de CPU y memoria para asignar la clasificación QoS. Conociendo esta clasificación, puedes evitar posibles reinicios innecesarios en tus Pods.
Kubernetes utiliza las requests y limits de CPU y memoria de los contenedores para asignar la clasificación Quality of Service (QoS).
Dependiendo del tipo de QoS asignado, Kubernetes puede mover el Pod a otro nodo, lo que provoca un reinicio del mismo.
Cuando definimos estos valores, es un comportamiento que debemos tener en cuenta si queremos evitar que nuestros Pods y contenedores se reinicien en caso de que un nodo no tenga recursos suficientes.
Requests y Limits
Cuando escribimos la definición de un Pod, tenemos la posibilidad de configurar la memoria y CPU asignada a cada uno de los contenedores que lo componen.
Un Pod se compone de uno o más contenedores
Kubernetes ofrece la posibilidad de hacerlo en las propiedades:
spec.containers[].resources.requests: Memoria y CPU mínima asignada al contenedor.spec.containers[].resources.limits: Memoria y CPU máxima asignada al contenedor.
Valores Quality of Service (QoS)
Utilizando los valores de memoria y CPU, Kubernetes asigna un estado a cada Pod. Los valores del estado Quality of Service (QoS) son tres y se utilizan para asignar el nodo donde se ejecutará el Pod y sus contenedores, así como para priorizar los Pods que se pueden mover a otro nodo en caso de que el nodo necesite liberar recursos.
Guaranteed
Se asigna este estado cuando todos los contenedores que componen el Pod tienen configurados tanto los requests como los limits y los valores de memoria y CPU son iguales.
Los Pods con este estado asignado no se mueven a otros nodos cuando se necesitan recursos en el nodo.
Se pueden reiniciar y mover en caso de que el nodo no se encuentre disponible o sea eliminado del clúster.
Esta configuración se aplica a cargas de trabajo críticas para reducir posibles reinicios de los Pods o los contenedores.
A partir de Kubernetes 1.34 (Of Wind & Will - O´WaW), no es necesario definir la memoria y CPU en cada uno de los contenedores. Podemos hacerlo a nivel del Pod a través de la propiedad spec.resources.limits y spec.resources.requests.
La definición de la memoria y CPU se encuentra en estado Beta, asegúrate que está activada en tu clúster si quieres hacer uso de ella.
Puedes comprobarlo utilizando el endpoint
/metrics:kubectl get --raw /metrics | grep kubernetes_feature_enabled
apiVersion: v1
kind: Pod
metadata:
name: pod-guaranteed
spec:
containers:
- name: container
image: nginx
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "100Mi"
cpu: "100m"Comprobamos el QoS asignado por Kubernetes:
kubectl get pods -n qos -o custom-columns=NAME:.metadata.name,QOS:.status.qosClassBurstable
Kubernetes asigna este estado cuando al Pod no se le asigna el estado Guaranteed y se define la CPU o memoria en los limits o requests de uno de los contenedores que componen el Pod (no es necesario que sean iguales).
Con este tipo de configuración, podemos hacer un mejor uso de la memoria y CPU compartidas.
Los Pods en este estado pueden ser reiniciados y movidos a otro nodo después de haber movido los Pods en estado BestEffort.
apiVersion: v1
kind: Pod
metadata:
name: pod-burstable
spec:
containers:
- name: container
image: nginx
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "200Mi"
cpu: "200m"Comprobamos el QoS asignado por Kubernetes:
kubectl get pods -n qos -o custom-columns=NAME:.metadata.name,QOS:.status.qosClassBestEffort
Se aplica este estado cuando no se define ningún request ni limit en los contenedores del Pod.
Los Pods con este estado son los primeros en ser eliminados y movidos de nodo en caso de que sea necesario.
Aplicamos esta configuración a aplicaciones que se pueden reiniciar sin provocar un impacto importante en nuestra solución.
apiVersion: v1
kind: Pod
metadata:
name: pod-besteffort
spec:
containers:
- name: container
image: nginxComprobamos el QoS asignado por Kubernetes:
kubectl get pods -n qos -o custom-columns=NAME:.metadata.name,QOS:.status.qosClassConclusion
Kubernetes utiliza las clases Quality of Service para priorizar qué Pods permanecen en ejecución cuando un nodo necesita liberar recursos (Node-pressure Eviction). Entender la diferencia entre Guaranteed, Burstable y BestEffort es esencial para configurar correctamente nuestras aplicaciones.
Referencias
https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/
https://kubernetes.io/docs/tasks/configure-pod-container/assign-pod-level-resources/
https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/


