Soluciona problemas de contención de recursos

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

Si necesitas asistencia adicional, comunícate con Atención al cliente de Cloud.

Descripción general

A veces, Google Distributed Cloud puede experimentar una contención de recursos, lo que hace que los contenedores se ralenticen, tengan un rendimiento inferior o se cierren. Esto puede ocurrir debido al alto consumo de CPU o memoria por parte de los contenedores.

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

  • CPU:

    • Un Pod se programa en un nodo según las solicitudes de CPU que especifican los contenedores en el Pod.
    • Un contenedor en un Pod no puede usar más CPUs que el límite especificado por el contenedor.
    • El uso de la CPU del contenedor se limita en el límite de la CPU.
    • Si el uso de la CPU se limita a nivel del nodo, a los contenedores se les asignan automáticamente los ciclos de CPU proporcionales a las solicitudes.

    Obtén más información sobre cómo se programan los Pods con solicitudes de recursos.

  • Memoria:

    • Un Pod se programa en un nodo según las solicitudes de memoria que especifican los contenedores en el Pod.
    • Un contenedor no puede usar más memoria que el límite especificado por el contenedor.
    • Si no se especifica un límite de memoria, un contenedor podría consumir toda la memoria disponible en un nodo. Luego, el sistema podría activar el OOM-Killer (Out Of Memory Killer) y expulsar los Pods de baja prioridad.

Para obtener más información, consulta Asigna recursos de CPU, Asigna recursos de memoria en Kubernetes y Métricas de GKE Enterprise.

Problemas

El contenedor se vuelve lento

Los problemas de contención de la CPU pueden hacer que los contenedores se vuelvan lentos. Estos son algunos de los motivos posibles:

Uso alto de CPU en el contenedor:

Un contenedor puede volverse lento si no recibe ciclos de CPU proporcionales a las solicitudes de CPU o si estas se establecieron en un valor demasiado bajo para lo que necesita el contenedor. Por lo tanto, verifica la proporción del límite de CPU en relación con el uso de CPU del contenedor.

En la consola de Google Cloud > Supervisión > 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 alto de CPU en el nodo

Si la proporción del límite de CPU en relación con el uso no es alta para ningún contenedor individual del Pod, es posible que el nodo no tenga suficientes ciclos de CPU para asignar al conjunto de contenedores que se ejecutan en él. Por lo tanto, sigue estos pasos para verificar la proporción entre el uso real de la CPU y las CPUs asignables en el nodo:

  1. Obtén el nodo del Pod que funciona lento:

    kubectl get pod –kubeconfig CLUSTER_KUBECONFIG --namespace NAMESPACE POD --output wide
    
  2. En la consola de Google Cloud > Supervisión > 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 proporción es alta (>=0.8), significa que el nodo no tiene suficientes ciclos de CPU y tenga un asignación excesiva. Por lo tanto, sigue estos pasos para verificar el uso de CPU de todos los demás Pods en ese nodo y para investigar si hay otro contenedor que use más CPUs.

    1. Obtén 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 una CPU alta en el nodo, aumenta las solicitudes y los límites de CPU en el contenedor que funciona lento. Esto volverá a crear el Pod en otro nodo para obtener los ciclos de CPU necesarios.

Si es un Pod del sistema que funciona lento, comunícate con el equipo de Atención al cliente de Google.

Asignación excesiva de CPU a nivel de vSphere

Si el consumo de CPU no es alto en el nodo o el Pod, y el contenedor sigue siendo lento, es posible que la VM tenga una asignación excesiva 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 verificar si la VM tiene una suscripción excesiva. Si se detecta una asignación excesiva, prueba lo siguiente:

El Pod se cierra por falta de memoria (OOM).

Los Pods pueden recibir OOMKilled debido a fugas de memoria o a una configuración deficiente de las solicitudes y los límites de memoria en los contenedores. Estos son algunos de los motivos posibles:

Alto uso de memoria en el contenedor

Un Pod puede recibir un error de OOM si algún contenedor de un Pod consume más de la memoria total asignada. Por lo tanto, verifica la proporción de solicitudes de memoria en relación con los límites de memoria del contenedor.

En la consola de Google Cloud > Supervisión > 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:

Alto uso de memoria en el nodo

Un Pod puede recibir un error de OOM si el uso de memoria de todos los Pods que se ejecutan en el nodo supera la memoria disponible. Por lo tanto, verifica si la condición MemoryPressure en el nodo es True.

  1. Ejecuta el siguiente comando y, luego, inspecciona la sección Conditions:

    kubectl describe nodes --kubeconfig CLUSTER_KUBECONFIG NODE-NAME
    
  2. Si la condición MemoryPressure es True, verifica el uso 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 o otros pods consumen mucha memoria.

  3. En la consola de Google Cloud > Supervisión > Explorador de métricas, en el editor de MQL, ejecuta la siguiente consulta para verificar el uso de memoria de los contenedores en el 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, comunícate con el equipo de Atención al cliente de Google.

Además, puedes habilitar la función de ajuste de escala automático en Google Distributed Cloud para aumentar o disminuir automáticamente los grupos de nodos según las demandas de tus cargas de trabajo.

Obtén más información para habilitar el escalador automático.

Problemas de etcd

A veces, es posible que tus clústeres de Anthos en VMware experimenten fallas de contenedor debido a problemas del servidor etcd y que observes lo siguiente:

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

    etcdserver: request timed out y etcdserver: leader changed

  • Registros de etcd repetidos del siguiente formato:

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

Estos son algunos de los motivos posibles:

Limitación de la CPU

Es posible que el servidor etcd sea lento debido al regulador 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 verificar si hay problemas de contención de la CPU.

Si detectas una contención de CPU en el Pod del servidor ectd o en el nodo, agrega CPUs al nodo del plano de control del clúster de usuario. Usa gkectl update para editar el campo cpus en el archivo de configuración del clúster de usuario.

Etcd Pod OOMkilled

Es posible que el Pod de etcd se elimine 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 verificar si hay algún problema de contención de memoria con el Pod del servidor de etcd o el nodo en el que se ejecuta.

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

Lentitud del disco

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

Verifica los siguientes problemas:

  • Para verificar si el servidor etcd tarda demasiado en leer o escribir en el disco subyacente, haz lo siguiente:

    1. Recupera los registros de etcd:

      kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n ETCD_POD_NAMESPACE ETCD_POD
      
    2. Busca las entradas del 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 del 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 alguno o ambos de los patrones de registro anteriores aparecen con frecuencia en los registros de etcd, significa que el disco es lento. Luego, verifica el rendimiento del almacén de datos y los discos.

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

    1. Recupera las latencias de sincronización de etcd wal:

      En la consola de Google Cloud > Supervisión > 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. Recupera las latencias de escritura de etcd:

      En la consola de Google Cloud > Supervisión > 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 para etcd_disk_wal_fsync_duration_seconds es superior a 10 ms de forma continua o p99 para etcd_disk_backend_commit_duration_seconds es superior a 25 ms de forma continua, significa que el disco es lento. Luego, verifica el rendimiento del almacén de datos y los discos.

Latencias de lectura y escritura en el disco de la VM

Sigue estos pasos para verificar las latencias de lectura y escritura en el disco virtual de la VM

  1. Identifica el nodo del Pod de etcd lento:

    kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG get pods -n ETCD_POD_NAMESPACE ETCD_POD -owide
    
  2. Accede a vSphere y selecciona la VM identificada en el paso anterior. En vSphere, ve a Monitor > Rendimiento > Avanzado y selecciona Disco virtual en la sección Vista para identificar las latencias de lectura y escritura de los discos virtuales.

    Si la latencia de lectura y escritura del disco virtual es alta, haz lo siguiente:

    • Examina otras VMs que se ejecutan en el almacén de datos para verificar si hay un uso alto de operaciones de entrada y salida por segundo (IOPS). Si alguna VM muestra aumentos repentinos en las IOPS, evalúa su funcionamiento.
    • Consulta a tu equipo de lab o de infraestructura para asegurarte de que el ancho de banda de lectura y escritura no se reduzca ni limite en ningún momento.
    • Consulta a tu equipo de lab o de 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 del servidor de la API

Si los contenedores de tu Google Distributed Cloud experimentan latencia mientras se comunican con el servidor de la API, o si los comandos de Kubectl fallan o tardan demasiado en responder, es posible que haya problemas con el servidor de la API.

Estos son algunos de los motivos posibles:

Alto volumen de solicitudes a la API

Es posible que el servidor de la API tarde 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 comience a reducir la velocidad de las solicitudes. Por lo tanto, verifica la tasa de solicitudes a la API en el servidor de la API.

En la consola de Google Cloud > Supervisión > 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 hay un aumento inesperado en las solicitudes a la API, usa el registro de auditoría de Cloud para identificar el Pod que podría estar consultando el servidor de la API con demasiada frecuencia.

Limitación de la CPU

Una tasa de solicitudes alta en el servidor de la API puede provocar una limitación de la CPU. Luego, es posible que el servidor de la API se ralentice 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 verificar si hay problemas de contención de CPU con el Pod o el nodo.

Pod del servidor de la API OOMkilled

Es posible que el Pod del servidor de API se elimine debido a problemas de contención de recursos. Consulta los pasos de la sección El pod se cierra por falta de memoria para verificar si hay algún problema de contención de memoria con el pod o el nodo.

Respuestas lentas de etcd

El servidor de la API se basa en la comunicación con el clúster de etcd para entregar solicitudes de lectura y escritura a los clientes. Si etcd es lento o no responde, el servidor de la API también se vuelve lento.

Recupera los registros del servidor de la API para verificar si este 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 mostraron anteriormente en este documento se basan en las métricas que se exportan de 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 comandos que puedes ejecutar en tu estación de trabajo de administrador para ver las métricas.

Consulta las métricas de un nodo:

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

Reemplaza lo siguiente:

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

Consulta las métricas de un Pod:

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

Reemplaza lo siguiente:

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

Visualiza las métricas de todos los nodos:

kubectl --kubeconfig CLUSTER_KUBECONFIG top node

Visualiza las métricas de todos los Pods en un espacio de nombres:

kubectl --kubeconfig CLUSTER_KUBECONFIG top pod --namespace NAMESPACE

Consulta 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 ejecuta en un nodo.

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

¿Qué sigue?

Si necesitas asistencia adicional, comunícate con Atención al cliente de Cloud.