Saltar al contenido

¿Cómo soluciono los problemas de escalamiento de clústeres con el escalamiento automático de Karpenter en Amazon EKS?

13 minutos de lectura
0

Quiero solucionar problemas de escalamiento de clústeres con el escalador automático de Karpenter en Amazon Elastic Kubernetes Service (Amazon EKS).

Resolución

Soluciona el problema según el mensaje de error que recibas.

No se pueden programar pods de Karpenter porque no hay suficientes instancias de grupos de nodos de Amazon EKS

Nota: Si se muestran errores al ejecutar comandos de la Interfaz de la línea de comandos de AWS (AWS CLI), consulta Solución de problemas de AWS CLI. Además, asegúrate de utilizar la versión más reciente de la AWS CLI.

En la versión 0.16.0 y posteriores de Karpenter, el recuento de réplicas predeterminado cambió de 1 a 2. Para obtener más información, consulta v0.16.0 en el sitio web de GitHub. Si no hay suficiente capacidad de nodos en el clúster para admitir la cantidad configurada de réplicas, no puedes programar pods de Karpenter. Como Karpenter no puede aprovisionar nodos para ejecutar sus propios pods, falla debido a una capacidad insuficiente y da como resultado que los pods no estén programados. Si recibes el siguiente mensaje de error:

«Warning FailedScheduling 3m default-scheduler 0/1 nodes are available: 1 Insufficient memory».

Para resolver este error, realiza una de las siguientes acciones:

Reducción de las réplicas de despliegue de Karpenter a una

Si tu despliegue de Karpenter no requiere redundancia, cámbialo para usar una única réplica. Ejecuta el siguiente comando:

kubectl scale deployment karpenter --replicas=1

Aumento de la capacidad de los nodos de los pods de Karpenter

Para ejecutar dos réplicas de Karpenter, asegúrate de que haya suficiente capacidad para dos réplicas. Elige una de las siguientes opciones:

Escalamiento horizontal del grupo de escalamiento automático

  1. Aumenta el recuento mínimo de instancias en el grupo de escalamiento automático. Ejecuta el siguiente comando:
    aws autoscaling update-auto-scaling-group --auto-scaling-group-name your-node-group-name --min-size 2 --desired-capacity 2
    Nota: Sustituye your-node-group-name por el nombre de tu grupo de escalamiento automático.
  2. Asegúrate de que haya nodos que Karpenter no administre. Comprueba las etiquetas de los nodos para ver si hay etiquetas de Karpenter, como karpenter.sh/nodepool. Ejecuta el siguiente comando:
    kubectl get nodes --show-labels | grep karpenter.sh/nodepool

Uso de los nodos existentes

Si el nodo o los nodos existentes de destino tienen etiquetas de Karpenter como karpenter.sh/nodepool, elimina las etiquetas. Ejecuta el siguiente comando:

kubectl label nodes your-node-name karpenter.sh/nodepool-

Nota: Sustituye your-node-name por el nombre de tu nodo.

Fallos de montaje y conexiones de volúmenes

Cuando se programan varios pods con reclamaciones de volumen persistente (PVC) en el mismo nodo, es posible que el nodo supere su límite de conexiones de volúmenes. A continuación, es posible que recibas uno de los siguientes mensajes de error:

«Warning FailedAttachVolume pod/example-pod AttachVolume. Attach failed for volume " " : rpc error: code = Internal desc = Could not attach volume " " to node " ": attachment of disk " " failed, expected device to be attached but was attaching»

«Warning FailedMount pod/example-pod Unable to attach or mount volumes: unmounted volumes=[], unattached volumes=[]: timed out waiting for the condition»

Para resolver los errores de montaje y conexión de volúmenes para cargas de trabajo con alto contenido de PVC, sigue estos pasos:

  1. Aplica topologySpreadConstraints y podAntiAffinity para evitar que los pods con mucho PVC se programen en el mismo nodo. Para obtener más información, consulta topologySpreadConstraints field (Campo topologySpreadConstraints) y Pod affinity example (Ejemplo de afinidad de pods) en el sitio web de Kubernetes. Esta acción distribuye los pods con muchas PVC en diferentes nodos para evitar la concentración de conexiones de volúmenes en un solo nodo.
  2. Utiliza controladores de CSI como el controlador de la interfaz de almacenamiento de contenedores (CSI) de Amazon Elastic Block Store (Amazon EBS) (aws-ebs-csi-driver) y agrega taints de inicio a tu NodePool. Estas acciones garantizan que los pods no se programen prematuramente en los nodos antes de que estén completamente listos.
    Ejemplo de configuración para taints de inicio en Amazon EBS:
    --yaml--
    apiVersion: karpenter.sh/v1
    kind: NodePool
    spec:
      template:
        spec:
          startupTaints:
            - key: ebs.csi.aws.com/agent-not-ready
              effect: NoExecute
    

Error en el complemento de almacenamiento obsoleto

Karpenter no admite complementos de almacenamiento en árbol obsoletos, como Amazon EBS. Si utilizas un volumen persistente (PV) aprovisionado estáticamente con un complemento en árbol, Karpenter no puede descubrir los límites de conexiones de volúmenes del nodo. Este escenario puede provocar errores en la programación y es posible que recibas el siguiente mensaje de error:

«ERROR controller.node_state PersistentVolume source 'AWSElasticBlockStore' uses an in-tree storage plugin which is unsupported by Karpenter and is deprecated by Kubernetes».

Para resolver este problema, utiliza los controladores de CSI para Amazon EBS y actualiza tus configuraciones de volumen persistente para utilizar el controlador de CSI.

Errores de programación o empaquetado debido a solicitudes de recursos no especificadas

Karpenter empaqueta los pods en función de las solicitudes de recursos. Si las solicitudes son demasiado bajas o faltan, es posible que Karpenter asigne demasiados pods al mismo nodo. Este escenario puede provocar una contención de recursos y una limitación de la CPU. Además, si se establecen límites de memoria y los pods intentan usar más memoria que su límite, es posible que se produzcan terminaciones por falta de memoria (OOM). Es posible que se muestre el siguiente mensaje de error:

«Warning OOMKilled pod/your-pod-name Container "container-name" was killed due to OOM (Out of Memory). Memory limit: 512Mi, Memory usage: 513Mi»

Para evitar estos problemas, utiliza las configuraciones de LimitRange para establecer solicitudes de recursos mínimas para un empaquetado preciso de los contenedores. Las configuraciones de LimitRange ayudan a establecer límites máximos para evitar un consumo excesivo. También proporcionan límites predeterminados para los pods no especificados. Para obtener más información, consulta Se utiliza LimitRanges para configurar los valores predeterminados de las solicitudes y los límites de recursos.

Los pods de Windows no se inician con un error de extracción de imágenes

Un pod no se inicia si la versión del sistema operativo (SO) del contenedor no coincide con la versión del sistema operativo Windows. Recibes un mensaje de error similar al siguiente:

«Failed to pull image "mcr.microsoft.com/windows/servercore:xxx": rpc error: code = NotFound desc = failed to pull and unpack image "mcr.microsoft.com/windows/servercore:xxx": no match for platform in manifest: not found»

Para resolver este problema, define el nodeSelector de tu pod para asegurarte de que tus contenedores estén programados en una versión de host del sistema operativo compatible. Para obtener más información, consulta Compatibilidad con versiones de contenedores de Windows en el sitio web de Microsoft.

Los nodos no se inicializaron correctamente

El sistema determina la inicialización de los nodos en función de la preparación de los nodos, el registro de recursos esperados y la eliminación de los taints de inicio de NodePool. Si no se cumple alguna de estas condiciones, el nodo de Karpenter no se inicializa correctamente y el nodo permanece en estado NotReady. Como resultado, el sistema no puede usar el nodo para programar o consolidar las cargas de trabajo. Es posible que se muestre el siguiente mensaje de error:

«Nodes provisioned by Karpenter are in a NotReady state»

Comprueba que el estado del nodo sea Listo. Si no es así, inspecciona los registros de Kubelet para identificar posibles problemas con los permisos, los grupos de seguridad o las redes.

Comprueba que todos los recursos necesarios, como nvidia.com/gpu o vpc.amazonaws.com/pod-eni, estén registrados correctamente en el nodo.

Para comprobar los recursos de nvidia.com/gpu en el nodo, ejecuta el siguiente comando:

kubectl describe node your-node-name

Nota: Sustituye your-node-name por el nombre de tu nodo.

Resultado de ejemplo:

...
Capacity:
  nvidia.com/gpu.shared: 80
...

Si faltan estos recursos, comprueba que se estén ejecutando los complementos o daemonset apropiados. Para comprobar si hay daemonset, ejecuta el siguiente comando:

kubectl get ds -n your-daemonset-namespace

Nota: Sustituye your-daemonset-namespace por tu espacio de nombres de daemonset.

Fallos de programación debido a diversas restricciones y limitaciones

El pod no se puede programar debido a restricciones de afinidad, antiafinidad o distribución de topología

Un pod no está programado si las restricciones de afinidad, antiafinidad o distribución de topología requieren nodos o zonas específicos, pero no existen nodos adecuados en las ubicaciones requeridas. Si el sistema no puede colocar un pod porque no se cumplen los requisitos de nodo o zona, es posible que recibas el siguiente mensaje de error:

«Warning FailedScheduling pod/"pod-name" 0/3 nodes are available: 1 node(s) didn't match pod affinity rules, 2 node(s) didn't match pod topology spread constraints rules, 3 nodes(s) didn't match inter-pod anti-affinity rules».

Para resolver este error, revisa y ajusta la configuración de afinidad y antiafinidad del pod o las restricciones de distribución de topología para alinearlas con los nodos disponibles. Puedes relajar estas restricciones o aprovisionar más nodos en las zonas requeridas.

No se pudo programar el pod por falta de recursos

Los pods permanecen sin programar debido a que las solicitudes de recursos superan la capacidad de nodos disponible. Si no hay ningún nodo que tenga suficiente CPU, memoria u otros recursos para aceptar el pod, es posible que recibas el siguiente mensaje de error:

«Warning FailedScheduling 30s (x13 over 60m) default-scheduler 0/5 nodes are available: 1 Insufficient memory. preemption: 0/5 nodes are available: 5 No preemption victims found for incoming pod».

Para resolver este problema, asegúrate de que las solicitudes de recursos de la especificación del pod reflejen el uso real. Ajusta las solicitudes y los límites de los recursos si es necesario o aprovisiona nodos más grandes con más capacidad para satisfacer las demandas de recursos.

Los taints impiden que se programen los pods

Cuando los administradores de clústeres aplican taints personalizados a nodos específicos, los pods deben tener las mismas tolerancias. Si no tienen tolerancias coincidentes, el sistema no puede programar pods en esos nodos. Si recibes el siguiente mensaje de error:

«0/5 nodes are available: 3 node(s) had taint {dedicated: gpu}, that the pod didn't tolerate, 2 node(s) had taint {dedicated: non-gpu}, that the pod didn't tolerate».

Para resolver este error, agrega las tolerancias adecuadas a la especificación del pod para que pueda tolerar los taints. O bien, puedes eliminar o modificar los taints personalizados innecesarios en los nodos si son demasiado restrictivos.

Para eliminar un taint de un nodo, ejecuta el siguiente comando:

kubectl taint nodes your-node-name your-custom-taint-

Nota: Sustituye your-node-name por el nombre de tu nodo y your-custom-taint por el nodo de tu taint personalizado.

No se cumplen las restricciones de NodeAffinity o NodeSelector

Si hay restricciones de afinidad de nodos o de selección de nodos que no coinciden con ningún nodo disponible en el clúster, el programador no puede colocar pods. Si recibes el siguiente mensaje de error:

«Warning FailedScheduling  3m    default-scheduler 0/4 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 3 node(s) didn't satisfy existing pods anti-affinity rules, 4 node(s) didn't match Pod's node affinity rules».

Para resolver este error, modifica los requisitos del selector de nodos o de afinidad de nodo del pod para que sea más flexible. O bien, puedes aprovisionar nodos adicionales que cumplan con los criterios del pod si es necesario. Para obtener más información, consulta Node affinity (Afinidad de nodos) y nodeSelector en el sitio web de Kubernetes.

No hay suficientes direcciones IP en la subred

Cuando Karpenter intenta aprovisionar nuevos nodos, falla porque no hay suficientes direcciones IP en la subred. Este escenario se produce cuando el rango de enrutamiento entre dominios sin clases (CIDR) de la subred se agota y no puede admitir nuevas instancias de Amazon Elastic Compute Cloud (Amazon EC2). Si recibes el siguiente mensaje de error:

«error»: «creating machine, creating instance, with fleet error(s), InsufficientFreeAddressesInSubnet: There are not enough free addresses in subnet 'subnet-a to satisfy the requested number of instances».

Para resolver este error, realiza una de las siguientes acciones:

Si las direcciones IP de la subred están agotadas, agrega un bloque de CIDR IPv4 adicional como CIDR secundario a tu Amazon Virtual Private Cloud (Amazon VPC).

Alternativa:

Usa redes personalizadas para asignar espacios de direcciones IP independientes a tus pods y nodos. Para activar las redes personalizadas, ejecuta el siguiente comando:

kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true

Para obtener más información sobre las redes personalizadas, consulta ¿Cómo elijo subredes de direcciones IP específicas para los pods de mi clúster de Amazon EKS?

No se puede programar el pod debido a requisitos incompatibles

Karpenter no programa los pods que especifican etiquetas de grupos de nodos, como eks.amazonaws.com/nodegroup, que no coinciden con ningún valor definido en las configuraciones del grupo de nodos. Si se produce esta falta de coincidencia, Karpenter no puede colocar pods en los nodos debido a la ausencia de las etiquetas de nodo necesarias. Es posible que recibas uno de los siguientes mensajes de error:

«incompatible requirements, label \"eks.amazonaws.com/nodegroup\" does not have known values"»

«incompatible requirements, key topology.kubernetes.io/zone, topology.kubernetes.io/zone In [us-east-1a] not in topology.kubernetes.io/zone In [us-east-1b us-east-1c]»

«incompatible requirements, key nodes.ktp.io/role, nodes.ktp.io/role In [ktp-atom-apps] not in nodes.ktp.io/role In [kube-apps]»

Si quieres que Karpenter pueda programar los pods, elimina el nodeSelector específico del grupo de nodos administrados para resolver este error.

Ejemplo:

kubectl edit pod your-pod-name
or  
kubectl edit deployment your-deployment-name
or
kubectl edit daemonset your-daemonset-name

Nota: Sustituye your-pod-name, your-deployment-name o your-daemonset-name por el nombre de tu pod, despliegue o daemonset.

Fallos de consolidación de nodos

La consolidación de nodos de Karpenter puede fallar debido a restricciones de programación o configuraciones específicas de pod que impiden la migración de pods.

Restricciones de programación

La consolidación de nodos falla cuando los pods no se pueden migrar por los siguientes motivos:

  • Afinidad o antiafinidad entre pods: Pods que requieren o evitan la ubicación conjunta con otros pods.
  • Restricciones de distribución de topología: Pods que deben distribuirse en diferentes zonas, nodos o bastidores.
  • Otras restricciones de programación: Cualquier otra restricción que impida que los pods se muevan a otros nodos.

Revisa y ajusta las reglas de afinidad y antiafinidad de pods para que sean menos restrictivas. Ajusta las restricciones de distribución de topología para permitir una mayor flexibilidad y otras restricciones de programación que puedan ser demasiado estrictas.

Prevención específica del pod

Si hay ciertos tipos de pods que se ejecutan en tus nodos, es posible que Karpenter no pueda consolidar los nodos. Karpenter no puede expulsar estos pods debido a las anotaciones, las restricciones de programación, los presupuestos de interrupción de pods (PDB) o la falta de un propietario del controlador. La consolidación puede fallar porque Karpenter no infringirá estas preferencias, incluso si kube-scheduler pudiera colocar técnicamente los pods en otros lugares.

OFICIAL DE AWSActualizada hace un año