Una guía para el desalojo de pods de Kubernetes

Uno de los puntos fuertes de Kubernetes es la planificación. Administra la ubicación del módulo de la aplicación entre los nodos de un clúster y su asignación de recursos, por lo que no tiene que preocuparse por equilibrar los recursos por su cuenta. Cuando se queda sin recursos, Kubernetes puede desalojar pods, pero ¿cómo decide Kubernetes qué pod desalojar?

Índice

    Pods y recursos de Kubernetes

    Si bien un pod puede contener varios contenedores, a los fines de este artículo, los analizaré como un solo objeto.

    En Kubernetes, puede definir los requisitos del módulo para la CPU (cálculo) y la memoria. La CPU se mide en unidades: 1 CPU equivale a 1 vCPU de nube única o 1 hiperproceso en hardware dedicado. La memoria se mide en bytes (por ejemplo, Mi por megabyte, Gi por gigabyte, etc.).

    La cantidad mínima de recursos necesarios para ejecutar el pod se define en la sección YAML. Para evitar que se utilicen todos los recursos del nodo, la sección YAML define el uso máximo de recursos. Aquí hay un ejemplo:

    apiVersion: v1
    kind
    : Pod
    metadata
    :
      name
    : frontend
    spec
    :
      Contenedores
    :
      - name
    : app
        image
    : images.my-company.example/app:v4
        resources
    :
          requests
    :
            memory
    : "64Mi"
            cpu
    : "250m"
          limits
    :
            memory
    : "128Mi"
            cpu
    : "500m"

    Cuando el programador de Kubernetes quiere colocar el pod en un nodo, primero confirma qué nodo tiene los recursos disponibles para cumplir con sus solicitudes. Nota: si tiene pods en un nodo sin solicitudes definidas, Kubernetes no los tendrá en cuenta y esto puede causar errores.

    Hay dos tipos de recursos: flexibles y exactos. La CPU es un recurso flexible y se puede aprovisionar en exceso. Las aplicaciones pueden seguir ejecutándose aunque no obtengan los recursos de CPU necesarios, pero su rendimiento será menor. Por otro lado, la memoria es un recurso exacto: una aplicación no puede ejecutarse sin la cantidad requerida. Si mi pod requiere 1 G de memoria y solo puede obtener 0,8 G, falla con un error de asignación de memoria cuando intenta asignar la cantidad total.

    Los límites funcionan de manera diferente a las solicitudes. Los límites se aplican a las CPU solo cuando la CPU del nodo está cargada (es decir, al 100 % de utilización de la CPU). Este es un escenario común y el sistema operativo del nodo local puede manejarlo. Pero si un pod excede su límite de memoria, el asesino de memoria baja (OOM) lo terminará.

    ¿Cuándo se produce el desalojo?

    Esta diferencia se relaciona con la forma en que Kubernetes maneja la presión de los recursos. Kubernetes debe eliminar los pods si los recursos del nodo se están agotando, un evento llamado caída de presión del nodo. Cuando una CPU se utiliza por completo, el programador de nodos puede manejarla, por lo que no se producirá el desalojo. Sin embargo, si no hay suficiente memoria disponible, debe quitar los pods del nodo e intentar colocarlos en otro nodo. Esto se conoce como desalojo debido a la presión de la memoria. Quedarse sin espacio en disco también puede hacer que la presión del nodo disminuya.

    ¿Cómo decide Kubernetes qué pods desalojar?

    Los pods se eliminan en función de los recursos, como la memoria o el espacio en disco, lo que genera presión en los nodos. Los primeros pods que se eliminan son los que se encuentran en estado de error, ya que no se están ejecutando pero aún pueden estar usando recursos. A continuación, Kubernetes evalúa los pods en ejecución.

    Eliminar el pod que consume la mayor cantidad de memoria no funcionará, ya que lo más probable es que sea un pod activo y más difícil de colocar. En cambio, Kubernetes tiene en cuenta dos clases diferentes al tomar esta decisión: la clase de calidad de servicio (QoS) y la clase de prioridad.

    Clase de QoS

    Kubernetes tiene tres clases de QoS que se pueden asignar a un pod:

    garantizado: Para cada contenedor en el pod:

    • Debe haber un límite de memoria y una solicitud de memoria.
    • El límite de memoria debe ser igual a la solicitud de memoria.
    • Debe haber un límite de CPU y una solicitud de CPU.
    • El límite de CPU debe ser igual a la demanda de CPU.

    Explosivo: el pod no cumple con los criterios para la clase QoS garantizada, pero tiene al menos un contenedor en el pod con una solicitud de memoria o CPU

    Mejor esfuerzo: El pod no debe tener contenedores con límites o solicitudes de memoria o CPU.

    La clase de QoS del pod está determinada por la clase de QoS más baja del contenedor.

    clase de prioridad

    La clase de prioridad de un pod define la importancia del pod en relación con otros pods que se ejecutan en el clúster: cuanto mayor sea la prioridad, más importante será el pod. Kubernetes usa la clase de prioridad cuando intenta programar el pod. Si no se puede programar, eliminará un pod de menor prioridad para hacerle espacio.

    Puede configurar la política de preferencia (desalojo) de pods con estas categorías:

    • Nunca: Este pod tiene una prioridad alta, pero Kubernetes no debería expulsar a otros pods para ejecutarlo. Este pod se puede eliminar para ejecutar pods de mayor prioridad.
    • Preempt Baja prioridad: Eliminar pods de una clase de prioridad más baja para ejecutar este pod

    La clase de prioridad de pod está determinada por la clase de prioridad de contenedor más baja.

    La plataforma en la nube de OKD (anteriormente conocida como Minishift y base de Red Hat OpenShift) tiene tres clases de prioridad integradas:

    • nodo crítico del sistema: Pods que nunca se deben desalojar de un nodo
    • clúster-critico-sistema: pods que son importantes para el clúster y se pueden eliminar del nodo, pero solo en determinadas circunstancias
    • registro de clúster: Pods que deben programarse en otras aplicaciones

    Usar clases para ordenar desalojos

    Para la presión del disco, Kubernetes solo usa la clase de prioridad de pod para ordenar su eliminación, ya que no existe un mecanismo para solicitar previamente la cantidad de recursos antes de programar los pods. Por este motivo, es importante utilizar volúmenes persistentes locales basados ​​en CSI en lugar de la ruta del host para los datos de un pod.

    Para la presión de la memoria, Kubernetes intentará expulsar los pods cuyo uso exceda las solicitudes teniendo en cuenta la clase de prioridad del pod, en este orden:

    1. Los pods con una clase de QoS de BestEffort no tienen demandas, por lo que siempre se consideran para desalojo.
    2. Si la presión persiste después de eliminar los pods de clase BestEffort, los pods se eliminan según su clase de prioridad. Los pods con la misma prioridad se desalojan en función de la cantidad que su nivel de uso supera la demanda.
    3. Si todavía hay presión, Kubernetes intentará desalojar los pods garantizados y los pods expandibles que no excedan las demandas. Estos pods se desalojan en función de su prioridad.

    Evitar el desalojo de la vaina

    ¿Cómo puede reducir la posibilidad de que sus pods esenciales sean desalojados?

    • Asigne siempre la clase de prioridad, ya que Kubernetes tiene en cuenta tanto la memoria como la presión del disco.
    • Evite tener pods con una clase de QoS BestEffort.
    • Para pods con uso fijo de memoria, use la clase QoS garantizada. No recomiendo usarlo para cada pod, ya que puede causar un uso de memoria ineficiente. La mayoría de las aplicaciones utilizan la mayor parte de la memoria durante la carga. Establecer solicitudes iguales a los límites puede significar establecer solicitudes más altas para permitir que el pod obtenga la cantidad máxima de memoria o reducir los límites para que la aplicación no obtenga más memoria.

    Si está interesado en obtener más información sobre la planificación y el desalojo de pods, puede explorar la documentación de Kubernetes:

    Artículos de interés

    Subir