Solucionar problemas de contención de recursos

En esta página se describe cómo identificar y solucionar problemas de contención de recursos en su entorno de Google Distributed Cloud.

Información general

En ocasiones, es posible que tu Google Distributed Cloud experimente una contención de recursos, lo que puede provocar que tus contenedores se ralenticen, no rindan como deberían o se terminen. Esto puede deberse a un consumo elevado de CPU o memoria por parte de los contenedores.

Cómo funciona la gestión de la CPU y la memoria

  • CPU:

    • Un pod se programa en un nodo en función de las solicitudes de CPU especificadas por los contenedores del pod.
    • Un contenedor de un pod no puede usar más CPUs que el límite especificado por el contenedor.
    • El uso de CPU del contenedor se limita al límite de CPU.
    • Si el uso de CPU se limita a nivel de nodo, los contenedores reciben automáticamente los ciclos de CPU proporcionales a las solicitudes.

    Más información sobre cómo se programan los pods con solicitudes de recursos

  • Memoria:

    • Un pod se programa en un nodo en función de las solicitudes de memoria especificadas por los contenedores del pod.
    • Un contenedor no puede usar más memoria que el límite especificado por el contenedor.
    • Si no se especifica ningún límite de memoria, un contenedor puede consumir toda la memoria disponible en un nodo. Entonces, el sistema puede activar el OOM-Killer (Out Of Memory Killer) y expulsar los pods de baja prioridad.

Para obtener más información, consulta las siguientes secciones:

Problemas

El contenedor se vuelve lento

Los problemas de contención de la CPU pueden provocar que los contenedores se ralenticen. A continuación, se indican algunos de los posibles motivos:

Uso elevado de la CPU en el contenedor:

Un contenedor puede ralentizarse si no recibe ciclos de CPU proporcionales a las solicitudes de CPU o si las solicitudes de CPU se han configurado con un valor inferior al que necesita el contenedor. Por lo tanto, comprueba la relación entre el límite de CPU y el uso de CPU del contenedor.

En la Google Cloud consola > Monitoring > Explorador de métricas, en el editor de MQL, ejecuta la siguiente consulta:

  fetch k8s_container
  | metric 'kubernetes.io/anthos/container/cpu/limit_utilization'
  | group_by 1m, [value_limit_utilization_mean: mean(value.limit_utilization)]
  | filter resource.cluster_name == 'CLUSTER_NAME'
  | filter resource.container_name == 'CONTAINER_NAME'
  | filter resource.pod_name == 'POD_NAME'
  | filter resource.namespace_name == 'NAMESPACE_NAME'
  | every 1m

A continuación, realiza una de las siguientes acciones:

Uso elevado de la CPU en el nodo

Si la relación entre el límite de CPU y la utilización no es alta en ningún contenedor del pod, puede que el nodo no tenga suficientes ciclos de CPU para asignar al conjunto de contenedores que se ejecutan en él. Para comprobar la proporción entre el uso real de la CPU y las CPUs asignables del nodo, sigue estos pasos:

  1. Obtén el nodo del pod que funciona lentamente:

    kubectl get pod –kubeconfig CLUSTER_KUBECONFIG --namespace NAMESPACE POD --output wide
    
  2. En la Google Cloud consola > Monitoring > Explorador de métricas, en el editor de MQL, ejecuta la siguiente consulta:

    fetch k8s_node
    | metric 'kubernetes.io/anthos/node/cpu/allocatable_utilization'
    | group_by 1m,
        [value_allocatable_utilization_mean: mean(value.allocatable_utilization)]
    | filter resource.cluster_name == 'CLUSTER_NAME'
    | filter resource.node_name == 'NODE_NAME'
    | every 1m
    

    Si esta relación es alta (≥ 0,8), significa que el nodo no tiene suficientes ciclos de CPU y que está sobresuscrito. Por lo tanto, sigue estos pasos para comprobar el uso de CPU de todos los demás pods de ese nodo e investigar si hay otro contenedor que utilice más CPUs.

    1. Obtener todos los pods del nodo:
    kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME
    
    1. Comprueba el uso de la CPU en cada contenedor:
    fetch k8s_container
    | metric 'kubernetes.io/anthos/container/cpu/limit_utilization'
    | group_by 1m, [value_limit_utilization_mean: mean(value.limit_utilization)]
    | filter resource.cluster_name == 'CLUSTER_NAME'
    | filter resource.container_name == 'CONTAINER_NAME'
    | filter resource.pod_name == 'POD_NAME'
    | filter resource.namespace_name == 'NAMESPACE_NAME'
    | every 1m
    

    Si hay otro contenedor que usa mucha CPU en el nodo, aumenta las solicitudes y los límites de CPU del contenedor que funciona lentamente. De esta forma, se volverá a crear el pod en otro nodo para obtener los ciclos de CPU necesarios.

Si se trata de un Pod del sistema que funciona lento, ponte en contacto con el equipo de Asistencia de Google.

Sobresuscripción de CPU a nivel de vSphere

Si el consumo de CPU no es alto en el nodo ni en el pod, pero el contenedor sigue funcionando con lentitud, es posible que la máquina virtual tenga demasiadas suscripciones a nivel de vSphere. Por lo tanto, el nodo no puede obtener los ciclos de CPU esperados de la virtualización subyacente.

Sigue estos pasos para comprobar si la máquina virtual tiene demasiadas suscripciones. Si se detecta una sobrecontratación, prueba lo siguiente:

  • Mueve algunas máquinas virtuales a otros hosts.
  • Evalúa y reduce el número de vCPUs por VM del host.
  • Asigna más recursos a las VMs del clúster.
  • Aumenta las solicitudes y los límites de CPU del contenedor. De esta forma, se volverá a crear el pod en otro nodo para obtener los ciclos de CPU necesarios.

El pod se cierra por falta de memoria (OOMkilled)

Los pods pueden recibir la señal OOMKilled debido a las fugas de memoria o a una configuración incorrecta de las solicitudes y los límites de memoria de los contenedores. A continuación, se indican algunos de los posibles motivos:

Uso elevado de memoria en el contenedor

Un pod puede recibir una señal OOMKilled si alguno de sus contenedores consume más memoria de la que se le ha asignado. Por lo tanto, comprueba la proporción de solicitudes de memoria con respecto a los límites de memoria del contenedor.

En la Google Cloud consola > Monitoring > Explorador de métricas, en el editor de MQL, ejecuta la siguiente consulta:

fetch k8s_container
| metric 'kubernetes.io/anthos/container/memory/limit_utilization'
| filter (metric.memory_type == 'non-evictable')
| group_by 1m, [value_limit_utilization_mean: mean(value.limit_utilization)]
| filter resource.cluster_name == 'CLUSTER_NAME'
| filter resource.container_name == 'CONTAINER_NAME'
| filter resource.pod_name == 'POD_NAME'
| filter resource.namespace_name == 'NAMESPACE_NAME'
| every 1m

A continuación, realiza una de las siguientes acciones:

Uso elevado de memoria en el nodo

Un pod puede recibir la señal OOMKilled si el uso de memoria de todos los pods que se ejecutan en el nodo supera la memoria disponible. Por lo tanto, comprueba si la condición MemoryPressure del nodo es True.

  1. Ejecuta el siguiente comando e inspecciona la sección Conditions:

    kubectl describe nodes --kubeconfig CLUSTER_KUBECONFIG NODE-NAME
    
  2. Si la condición MemoryPressure es True, comprueba la utilización de memoria en el nodo:

    fetch k8s_node
    | metric 'kubernetes.io/anthos/node/memory/allocatable_utilization'
    | filter (metric.memory_type == 'non-evictable')
    | group_by 1m,
        [value_allocatable_utilization_mean: mean(value.allocatable_utilization)]
    | filter resource.cluster_name == 'CLUSTER_NAME'
    | filter resource.node_name = 'NODE_NAME'
    | every 1m
    

    Si esta proporción es alta (≥ 0,8), significa que el nodo no tiene suficiente memoria para asignar al pod, posiblemente debido a que algunos procesos u otros pods consumen mucha memoria.

  3. En la consola Google Cloud > Monitorización > Explorador de métricas, en el editor de MQL, ejecuta la siguiente consulta para comprobar el uso de memoria de los contenedores del nodo:

    fetch k8s_node
    | metric 'kubernetes.io/anthos/container_memory_usage_bytes'
    | filter resource.cluster_name == 'CLUSTER_NAME'
    | filter resource.node_name == 'NODE_NAME'
    | group_by 1m,
        [value_container_memory_usage_bytes_mean:
          mean(value.container_memory_usage_bytes)]
    | every 1m
    

    Si hay un contenedor que usa mucha memoria, investiga su funcionamiento o aumenta la solicitud de memoria del contenedor, si es necesario.

Si se trata de un pod del sistema que consume mucha memoria, ponte en contacto con el equipo de Asistencia de Google.

Además, puedes habilitar la función de autoescalado en Google Distributed Cloud para aumentar y reducir automáticamente los grupos de nodos en función de las demandas de tus cargas de trabajo.

Consulta cómo habilitar el escalador automático.

Problemas de etcd

En ocasiones, es posible que tus clústeres de Anthos en VMware experimenten fallos de contenedores debido a problemas con el servidor etcd. En ese caso, puede que observes lo siguiente:

  • Registros repetidos del servidor de la API con el siguiente formato:

    etcdserver: request timed out y etcdserver: leader changed

  • Registros de etcd repetidos con el siguiente formato:

    W | wal: sync duration of 2.466870869s, expected less than 1s y W | etcdserver: read-only range request * took too long

A continuación, se indican algunos de los posibles motivos:

Limitación de CPU

El servidor etcd puede ser lento debido a la limitación de la CPU en el pod del servidor etcd o en el nodo en el que se ejecuta el servidor etcd. Consulta los pasos de la sección El contenedor se vuelve lento para comprobar si hay problemas de contención de CPU.

Si detectas una contención de CPU en el pod del servidor etcd o en el nodo, añade CPUs al nodo del plano de control del clúster de usuarios. Usa gkectl update para editar el campo cpus en el archivo de configuración del clúster de usuarios.

Pod de etcd eliminado por falta de memoria

Es posible que el pod de etcd se cierre por falta de memoria debido a problemas de contención de recursos. Consulta los pasos de la sección El pod se cierra por falta de memoria para comprobar si hay problemas de contención de memoria con el pod del servidor etcd o con el nodo en el que se ejecuta el servidor etcd.

Si detectas errores OOMkill en el pod etcd, aumenta la memoria disponible para el nodo de plano de control del clúster de usuarios. Usa gkectl update para editar el campo memoryMB en el archivo de configuración del clúster de usuarios.

Lentitud del disco

Si no hay problemas con el consumo de CPU o memoria en el pod o el nodo del servidor etcd, es posible que etcd vaya lento si el almacén de datos subyacente es lento o está limitado.

Comprueba si se dan los siguientes problemas:

  • Para comprobar si el servidor etcd tarda demasiado en leer o escribir en el disco subyacente, sigue estos pasos:

    1. Obtén los registros de etcd:

      kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n ETCD_POD_NAMESPACE ETCD_POD
      
    2. Busca las entradas con el siguiente patrón para detectar si etcd tarda demasiado en leer del disco:

      W | etcdserver: read-only range request "key:\"/registry/configmaps/default/clusterapi-vsphere-controller-manager-leader-election\" " with result "range_response_count:1 size:685" took too long (6.893127339s) to execute

    3. Busca las entradas con el siguiente patrón para detectar si etcd tarda demasiado en escribir en el disco:

      W | wal: sync duration of 2.466870869s, expected less than 1s

    Si uno o ambos patrones de registro anteriores se muestran con frecuencia en los registros de etcd, significa que el disco es lento. A continuación, comprueba el rendimiento del almacén de datos y los discos.

  • Para comprobar las métricas de etcd, haz lo siguiente:

    1. Obtén las latencias de sincronización de WAL de etcd:

      En la Google Cloud consola > Monitoring > Explorador de métricas, en el editor de MQL, ejecuta la siguiente consulta:

      fetch k8s_container::kubernetes.io/anthos/etcd_disk_wal_fsync_duration_seconds
      | every 1m
      | filter resource.cluster_name == 'CLUSTER_NAME'
      | filter resource.pod_name == 'POD_NAME'
      | filter resource.namespace_name == 'NAMESPACE_NAME'
      | percentile 99
      
    2. Obtén las latencias de escritura de etcd:

      En la Google Cloud consola > Monitoring > Explorador de métricas, en el editor de MQL, ejecuta la siguiente consulta:

      fetch k8s_container::kubernetes.io/anthos/etcd_disk_backend_commit_duration_seconds
      | every 1m
      | filter resource.cluster_name == 'CLUSTER_NAME'
      | filter resource.pod_name == 'POD_NAME'
      | filter resource.namespace_name == 'NAMESPACE_NAME'
      | percentile 99
      

    Si p99 de etcd_disk_wal_fsync_duration_seconds supera los 10 ms de forma continua o p99 de etcd_disk_backend_commit_duration_seconds supera los 25 ms de forma continua, significa que el disco es lento. A continuación, comprueba el rendimiento del almacén de datos y los discos.

Latencias de lectura/escritura en el disco de la VM

Sigue estos pasos para comprobar las latencias de lectura/escritura en el disco virtual de la máquina virtual

  1. Identifica el nodo del pod de etcd lento:

    kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG get pods -n ETCD_POD_NAMESPACE ETCD_POD -owide
    
  2. Inicia sesión en vSphere y selecciona la máquina virtual identificada en el paso anterior: En vSphere, ve a Monitor > Performance > Advanced (Monitor > Rendimiento > Configuración avanzada) y selecciona Virtual Disk (Disco virtual) en la sección View (Ver) para identificar las latencias de lectura y escritura de los discos virtuales.

    Si la latencia de lectura o escritura del disco virtual es alta:

    • Examina otras VMs que se ejecuten en el almacén de datos para comprobar si el uso de operaciones de entrada/salida por segundo (IOPS) es elevado. Si alguna máquina virtual muestra picos en las IOPS, evalúa su funcionamiento.
    • Consulta con tu equipo de laboratorio o infraestructura para asegurarte de que el ancho de banda de lectura y escritura no se limite ni se estrangule en ningún momento.
    • Consulta a tu equipo de laboratorio o infraestructura para identificar los problemas de rendimiento del disco y de rendimiento del almacenamiento, si los hay.

Para obtener más información, consulta las prácticas recomendadas para escalar tus recursos.

Problemas con el servidor de la API

Si los contenedores de tu experiencia de Google Distributed Cloud tienen latencia al comunicarse con el servidor de la API, o si los comandos de Kubectl fallan o tardan demasiado en responder, puede que haya problemas con el servidor de la API.

A continuación, se indican algunos de los posibles motivos:

Volumen alto de solicitudes a la API

El servidor de la API puede tardar en responder si la frecuencia y el volumen de las solicitudes son demasiado altos. El tiempo de respuesta lento puede persistir incluso después de que el servidor de la API empiece a limitar las solicitudes. Por lo tanto, comprueba la frecuencia de las solicitudes de API en el servidor de la API.

En la Google Cloud consola > Monitoring > Explorador de métricas, en el editor de MQL, ejecuta la siguiente consulta:

fetch k8s_container::kubernetes.io/anthos/apiserver_request_total
| filter resource.cluster_name == 'CLUSTER_NAME'
| filter resource.pod_name == 'APISERVER_POD_NAME'
| filter resource.namespace_name == 'NAMESPACE_NAME'
| align rate(1m)
| every 1m
| group_by [metric.verb]

Si se produce un aumento inesperado de las solicitudes de API, usa Cloud Audit Logging para identificar el pod que podría estar consultando el servidor de la API con demasiada frecuencia.

  • Si se trata de un Pod del sistema, ponte en contacto con el equipo de Asistencia de Google.
  • Si se trata de un pod de usuario, investiga más a fondo para determinar si las solicitudes de API son las esperadas.

Limitación de CPU

Una alta tasa de solicitudes en el servidor de la API puede provocar una limitación de la CPU. En ese caso, el servidor de la API puede ralentizarse debido a la contención de la CPU en el pod del servidor de la API o en el nodo.

Consulta la sección El contenedor se vuelve lento para comprobar si hay algún problema de contención de CPU con el pod o el nodo.

Se ha producido un error OutOfMemory en el pod del servidor de la API

Es posible que el pod del servidor de la API se cierre por falta de memoria debido a problemas de contención de recursos. Sigue los pasos de la sección El pod se ha cerrado por falta de memoria para comprobar si hay problemas de contención de memoria con el pod o el nodo.

Respuestas lentas de etcd

El servidor de la API depende de la comunicación con el clúster de etcd para atender las solicitudes de lectura y escritura de los clientes. Si etcd es lento o no responde, el servidor de la API también se ralentiza.

Obtén los registros del servidor de la API para comprobar si el servidor de la API es lento debido a problemas de etcd:

kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n APISERVER_NAMESPACE APISERVER_POD_NAME

Si observas registros recurrentes como etcdserver: request timedout o etcdserver: leader changed, sigue los pasos que se indican en Problemas de etcd para resolver cualquier problema relacionado con el disco.

Si tu clúster no exporta métricas

Las técnicas que se han mostrado anteriormente en este documento se basan en que las métricas se exporten desde tu clúster a un proyecto de Google Cloud .

Si tu clúster no exporta métricas, puedes usar la línea de comandos para investigar la contención de recursos. Estos son algunos de los comandos que puedes ejecutar en tu estación de trabajo de administrador para ver las métricas.

Para ver las métricas de un nodo, sigue estos pasos:

kubectl --kubeconfig CLUSTER_KUBECONFIG get --raw \
    /apis/metrics.k8s.io/v1beta1/nodes/NODE_NAME | jq

Haz los cambios siguientes:

  • CLUSTER_KUBECONFIG: la ruta del archivo kubeconfig del clúster
  • NODE_NAME: el nombre del nodo

Para ver las métricas de un pod, sigue estos pasos:

kubectl --kubeconfig CLUSTER_KUBECONFIG get --raw \
    /apis/metrics.k8s.io/v1beta1/namespaces/NAMESPACE/pods/POD_NAME | jq

Haz los cambios siguientes:

  • NAMESPACE: el espacio de nombres del pod
  • POD_NAME: nombre del pod

Para ver las métricas de todos los nodos, sigue estos pasos:

kubectl --kubeconfig CLUSTER_KUBECONFIG top node

Ver las métricas de todos los pods de un espacio de nombres:

kubectl --kubeconfig CLUSTER_KUBECONFIG top pod --namespace NAMESPACE

Ver las métricas de los contenedores de todos los pods de un espacio de nombres:

kubectl --kubeconfig CLUSTER_KUBECONFIG top pod --containers --namespace NAMESPACE

Para obtener más información, consulta kubectl top pod y kubectl top node.

También puedes ejecutar el comando top desde un contenedor que se esté ejecutando en un nodo.

Estas son dos formas de ejecutar un comando en un contenedor:

Siguientes pasos

Si necesitas más ayuda, ponte en contacto con el servicio de atención al cliente de Cloud.

También puedes consultar la sección Obtener asistencia para obtener más información sobre los recursos de asistencia, incluidos los siguientes: