Compartir a través de


Resolución de problemas del servidor API y etcd en AKS

Resumen

Este artículo le ayuda a solucionar problemas de servidor de API y etcd en implementaciones grandes de Azure Kubernetes Service (AKS).

Microsoft prueba la confiabilidad y el rendimiento del servidor de API a una escala de 5000 nodos y 200 000 pods. El clúster que contiene el servidor de API puede escalar horizontalmente y entregar automáticamente objetivos de nivel de servicio (SLO) de Kubernetes. Si experimenta latencias o tiempos de espera elevados, es probable que la causa sea una pérdida de recursos en el directorio distribuido etc (etcd) o un cliente infractor que tenga llamadas API excesivas.

Prerequisites

  • LaCLI de Azure.

  • La herramienta kubectl de Kubernetes. Para instalar kubectl mediante la CLI de Azure, ejecute el comando az aks install-cli .

  • Registros de diagnóstico de AKS (específicamente eventos kube-audit) que están habilitados y enviados a un área de trabajo Log Analytics. Para determinar si los registros se recopilan mediante el modo específico del recurso o modo diagnóstico de Azure, compruebe la hoja Configuración de diagnóstico en el portal de Azure.

  • Nivel Estándar para clústeres de AKS. Si usa el nivel Gratis, el servidor de API y etcd contienen recursos limitados. Los clústeres de AKS en el nivel Gratis no proporcionan alta disponibilidad. Esta condición suele ser la causa principal de los problemas del servidor de API y etcd.

  • El complemento kubectl-aks para ejecutar comandos directamente en nodos de AKS sin usar el plano de control de Kubernetes.

Comprobaciones de estado básicas

  • Verificar eventos de estado de recursos

    AKS proporciona eventos de estado de los recursos para el tiempo de inactividad crítico del componente. Antes de continuar, asegúrese de que Resource Health no notifica ningún evento crítico.

    Captura de pantalla de un evento de estado de recursos de AKS que indica el estado del plano de control.

  • Diagnóstico y solución de problemas

    AKS proporciona una categoría de solución de problemas dedicada para disponibilidad y rendimiento del plano de control y clústeres.

    Captura de pantalla de la categoría Diagnósticos de disponibilidad y rendimiento del plano de control y clúster en AKS.

Symptoms

En la tabla siguiente se describen los síntomas comunes de los errores del servidor de API.

Symptom Description
Pod del servidor de API en CrashLoopbackOff estado o errores en las llamadas de webhook Compruebe que no tiene ningún webhook de admisión personalizado (como el motor de directivas de Kyverno ) que bloquee las llamadas al servidor de API.
Tiempos de espera del servidor de API Tiempos de espera frecuentes que van más allá de las garantías en el Acuerdo de Nivel de Servicio del servidor de API de AKS. Por ejemplo, kubectl comandos con límite de tiempo de espera.
Latencias elevadas Las latencias elevadas provocan que los SLO de Kubernetes fallen. Por ejemplo, el comando kubectl tarda más de 30 segundos en listar los pods.
* Respuestas HTTP 429 elevadas del servidor API

* Mensaje siguiente para los comandos kubectl get :
"El servidor no puede controlar actualmente la solicitud"
El servidor API está sobrecargado y está limitando las llamadas. Consulte Causa 4 y Causa 5

Causa y resolución

Causa 1: una regla de red bloquea el tráfico de los nodos del agente al servidor de API.

Una regla de red puede bloquear el tráfico entre los nodos del agente y el servidor de API.

Para comprobar si una directiva de red mal configurada está bloqueando la comunicación entre el servidor de API y los nodos del agente, ejecute los siguientes comandos kubectl-aks :

kubectl aks config import \
    --subscription <mySubscriptionID> \
    --resource-group <myResourceGroup> \
    --cluster-name <myAKSCluster>

kubectl aks check-apiserver-connectivity --node <myNode>

El comando config import recupera la información del conjunto de escalado de máquinas virtuales para todos los nodos del clúster. A continuación, el comando check-apiserver-connectivity usa esta información para comprobar la conectividad de red entre el servidor de API y un nodo especificado, específicamente para su instancia del conjunto de escalado subyacente.

Note

Si la salida del check-apiserver-connectivity comando contiene el Connectivity check: succeeded mensaje, la conectividad de red no está impedida.

Solución 1: Corrección de la directiva de red para eliminar el bloqueo del tráfico

Si la salida del comando indica que se produjo un error de conexión, vuelva a configurar la directiva de red para que no bloquee el tráfico entre los nodos del agente y el servidor de API.

Causa 2: un webhook personalizado provoca un deadlock en los pods del servidor API

Un webhook personalizado, como Kyverno, podría causar un bloqueo dentro de los pods del servidor de la API.

Compruebe los eventos relacionados con el servidor de API. Es posible que vea mensajes de evento similares al texto siguiente:

Error interno: error al llamar al webhook "mutate.kyverno.svc-fail": no se pudo llamar al webhook: Post "https://kyverno-system-kyverno-system-svc.kyverno-system.svc:443/mutate/fail?timeout=10s": write unix @->/tunnel-uds/proxysocket: write: broken pipe

Recuperación de registros del servidor de API

AKSControlPlane
| where TimeGenerated between(now(-1h)..now())
| where Category=="kube-apiserver"
| where Message contains "Failed calling webhook, failing closed"
| limit 100
| project TimeGenerated, Level, Message

En este ejemplo, el webhook de validación está bloqueando la creación de algunos objetos de servidor de API. Dado que este escenario puede producirse durante el tiempo de arranque, no se pueden crear el servidor de API ni los pods de Konnectivity. Por lo tanto, el webhook no se puede conectar a esos pods. Esta secuencia de eventos provoca el interbloqueo y el mensaje de error.

Solución 2: Eliminar configuraciones de webhook

Para solucionar este problema, elimine las configuraciones de webhook de validación y mutación. Para eliminar estas configuraciones de webhook en Kyverno, revise el artículo de solución de problemas de Kyverno.

Causa 3: Un cliente que infringe filtra objetos etcd y provoca una ralentización de etcd

Una situación común es que los objetos se crean continuamente aunque no se quiten los objetos existentes sin usar en la base de datos etcd. Esta situación puede causar problemas de rendimiento si etcd controla demasiados objetos (más de 10 000) de cualquier tipo. Un rápido aumento de los cambios en estos objetos también podría provocar que se supere el tamaño predeterminado de la base de datos etcd (por defecto, ocho (8) gigabytes).

Para comprobar el uso de la base de datos etcd, vaya a Diagnóstico y solución de problemas>Disponibilidad y rendimiento del clúster y del plano de control en el portal de Azure. Ejecute la herramienta de diagnóstico de Problemas de Capacidad de Etcd y Problemas de Rendimiento de Etcd. La herramienta de diagnóstico muestra el desglose del uso y el tamaño total de la base de datos.

Captura de pantalla de la herramienta de diagnóstico de problemas de capacidad de Etcd en la experiencia de Azure Portal de AKS.

Para obtener una vista rápida del tamaño actual de la base de datos etcd en bytes, ejecute el siguiente comando:

kubectl get --raw /metrics | grep -E "etcd_db_total_size_in_bytes|apiserver_storage_size_bytes|apiserver_storage_db_total_size_in_bytes"

Note

Si el plano de control no está disponible, los comandos kubectl no funcionan. Use Diagnosticar y resolver problemas en Azure Portal, como se muestra en la sección anterior.

El nombre de métrica del comando anterior es diferente para diferentes versiones de Kubernetes. Para Kubernetes 1.25 y versiones anteriores, use etcd_db_total_size_in_bytes. Para Kubernetes 1.26 a 1.28, use apiserver_storage_db_total_size_in_bytes. Una base de datos etcd con un tamaño superior a dos (2) gigabytes se considera una base de datos etcd grande.

Solución 3: Definir cuotas para la creación de objetos, eliminar objetos o limitar la duración del objeto en etcd

Para evitar que etcd alcance la capacidad y provocar el tiempo de inactividad del clúster, limite el número máximo de recursos que se crean. También puede ralentizar el número de revisiones que se generan para las instancias de recursos. Para limitar el número de objetos que puede crear, defina cuotas de objetos.

Si identifica objetos que ya no están en uso, pero que consumen recursos, considere la posibilidad de eliminarlos. Por ejemplo, elimine los trabajos completados para liberar espacio:

kubectl delete jobs --field-selector status.successful=1

En el caso de los objetos que admiten la limpieza automática, establezca Valores de Período de vida (TTL) para limitar la duración de estos objetos. También puede etiquetar los objetos para que pueda eliminar de forma masiva todos los objetos de un tipo específico mediante selectores de etiquetas. Si establece referencias de propietario entre objetos, los objetos dependientes se eliminan automáticamente después de eliminar el objeto primario.

Consulte también la solución 6 para las técnicas de reducción de tamaño de objeto.

Causa 4: Se aplicó la protección del servidor de API administrada de AKS

Si observa una alta tasa de errores HTTP 429, una posible causa es que AKS aplica una protección gestionada para el servidor de API. AKS aplica esta protección mediante flowSchema y PriorityLevelConfiguration denominada "aks-managed-apiserver-guard". Este mecanismo de protección se activa cuando el servidor de API encuentra eventos frecuentes de falta de memoria (OOM) después de que los esfuerzos de escalado en el servidor de API fallan en estabilizarlo. Esta protección actúa como una medida de último recurso para proteger el servidor de API limitando las solicitudes de cliente que no son del sistema al servidor de API y evitando que no responda completamente.

  • Compruebe la presencia del clúster en "aks-managed-apiserver-guard" FlowSchema y PriorityLevelConfiguration o compruebe los eventos de Kubernetes.

Note

Los comandos de Kubectl pueden tardar más de lo esperado o agotar el tiempo de espera cuando se sobrecarga el servidor de API. Vuelva a intentarlo si se produce un error.

kubectl get flowschemas
kubectl get prioritylevelconfigurations

FlowSchema
ConfiguraciónDeNivelDePrioridad
  • Compruebe los eventos de Kubernetes.
kubectl get events -n kube-system aks-managed-apiserver-throttling-enabled

Solución 4: Identificación de clientes no optimizados y mitigación

Paso 1: Identificar clientes no optimizados

  • Consulte Causa 5 para identificar clientes problemáticos y refinar sus patrones de llamada LIST, especialmente aquellos clientes que generan solicitudes de alta frecuencia o latencia alta, ya que son los principales colaboradores de la degradación del servidor de API. Consulte los procedimientos recomendados para obtener más instrucciones sobre la optimización del cliente.

Paso 2: Mitigación

  • Reduzca el tamaño del clúster para disminuir la carga en el servidor API.
  • Si el paso 1 identifica un controlador agregado recientemente, CRD o DaemonSet como controlador principal de la sobrecarga del servidor de API, quite el objeto asociado del clúster.
  • Use métricas del plano de control para supervisar la carga en el servidor de API. Consulte el blog para obtener más detalles.
  • Cuando complete los pasos anteriores, elimine aks-managed-apiserver-guard.
kubectl delete flowschema aks-managed-apiserver-guard
kubectl delete prioritylevelconfiguration aks-managed-apiserver-guard

Advertencia

Evite volver a escalar el clúster al punto de escalado previsto originalmente hasta que se hayan optimizado los patrones de llamada de cliente, consulte los procedimientos recomendados. El escalado prematuro puede hacer que el servidor de la API falle de nuevo.

  • También puede modificar aks-managed-apiserver-guard FlowSchema y PriorityLevelConfiguration aplicando la etiqueta aks-managed-skip-update-operation: true. Esta etiqueta conserva las configuraciones modificadas y evita que AKS vuelva a reconciliarlos con los valores predeterminados. Esto es relevante si está aplicando un esquema de flujo personalizado y una configuración del nivel de prioridad adaptada a los requisitos del clúster, tal como se especifica en la solución 5b y no quiere que AKS administre automáticamente el control de la limitación de clientes.
kubectl label prioritylevelconfiguration aks-managed-apiserver-guard aks-managed-skip-update-operation=true
kubectl label flowschema aks-managed-apiserver-guard aks-managed-skip-update-operation=true

Causa 5: un cliente infractor realiza llamadas LIST o PUT excesivas

Si etcd no está sobrecargado con demasiados objetos como se define en la causa 3, un cliente infractor podría estar realizando demasiadas LIST llamadas o PUT llamadas al servidor de API. Si experimenta una latencia alta o tiempos de espera frecuentes, siga estos pasos para identificar el cliente infractor y los tipos de llamadas API que producen un error.

Paso 1: Identificación de los agentes de usuario principales por el número de solicitudes

Para identificar qué clientes generan la mayoría de las solicitudes (y potencialmente la mayor carga del servidor de API), ejecute una consulta similar al código siguiente. En esta consulta se enumeran los 10 agentes de usuario principales por el número de solicitudes de servidor de API enviadas.

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| summarize count() by UserAgent
| top 10 by count_
| project UserAgent, count_

Note

Si la consulta no devuelve ningún resultado, es posible que haya seleccionado la tabla incorrecta para consultar los registros de diagnóstico. En el modo específico del recurso, los datos se escriben en tablas individuales, en función de la categoría del recurso. Los registros de diagnóstico se escriben en la tabla AKSAudit. En el modo de diagnóstico de Azure, todos los datos se escriben en la AzureDiagnostics tabla. Para más información, consulte Registros de recursos de Azure.

Aunque resulta útil saber qué clientes generan el volumen de solicitud más alto, es posible que el volumen de solicitudes elevado por sí solo no sea una causa de preocupación. La latencia de respuesta que experimentan los clientes es un indicador mejor de la carga real que cada una genera en el servidor de API.

Paso 2: Identificación y análisis de la latencia del agente de usuario

Uso de Diagnóstico y Solución de problemas en Azure Portal

AKS ahora proporciona un analizador integrado, el Detector de listados intensivos de recursos del servidor de API, para ayudarle a identificar los agentes que realizan llamadas LIST que consumen muchos recursos. Estas llamadas son una causa principal de problemas de rendimiento del servidor de API y etcd.

Para acceder al detector, siga estos pasos:

  1. Abra el clúster de AKS en Azure Portal.
  2. Vaya a Diagnóstico y solución de problemas.
  3. Seleccione Disponibilidad y rendimiento del plano de control y clúster.
  4. Seleccione Detector de enumeración intensiva de recursos del servidor de API.

El detector analiza la actividad reciente del servidor de API y resalta los agentes o cargas de trabajo que generan llamadas LIST grandes o frecuentes. Proporciona un resumen de los posibles efectos, como los tiempos de espera de solicitud, un mayor número de errores "408" y "503", inestabilidad del nodo, errores de sondeo de estado y OOM-Kills en el servidor de API o etcd.

Captura de pantalla del resumen del detector de listados intensivos en recursos del servidor de API en los diagnósticos de AKS.

Captura de pantalla de la vista detallada para el análisis intensivo de recursos de la lista del servidor de API en AKS.

Interpretación de la salida del detector

  • Summary:
    Indica si se detectaron llamadas LIST que consumen muchos recursos y describe posibles impactos en el clúster.
  • Ventana de análisis:
    Muestra la ventana de 30 minutos analizada, con uso máximo de memoria y CPU.
  • Tipos de lectura:
    Explica si las llamadas LIST se han servido desde la caché del servidor de API (preferido) o si ha sido necesario obtenerlas de etcd (más impactante).
  • Gráficos y tablas:
    Identifique qué agentes, espacios de nombres o cargas de trabajo generan las llamadas LIST que consumen más recursos.

Note

Uso de registros

Para identificar la latencia media de las solicitudes de servidor de API por agente de usuario, como se traza en un gráfico de tiempo, ejecute la consulta siguiente.

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize avg(latency) by UserAgent, bin(start_time, 5m)
| render timechart

Esta consulta es un seguimiento de la consulta en la sección "Identificar los agentes de usuario principales por el número de solicitudes ". Puede proporcionar más información sobre la carga real que genera cada agente de usuario a lo largo del tiempo.

Tip

Al analizar estos datos, puede identificar patrones y anomalías que indican problemas en el clúster o las aplicaciones de AKS. Por ejemplo, puede observar que un usuario determinado experimenta una latencia alta. Este escenario puede indicar el tipo de llamadas API que provocan una carga excesiva en el servidor de API o en etcd.

Paso 3: Identificación de llamadas API no optimizados para un agente de usuario determinado

Ejecute la siguiente consulta para tabular la latencia del percentil 99 (P99) de las llamadas API en distintos tipos de recursos para un cliente determinado.

AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend HttpMethod = Verb
| extend Resource = tostring(ObjectRef.resource)
| where UserAgent == "DUMMYUSERAGENT" // Filter by name of the useragent you are interested in
| where Resource != ""
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize p99latency=percentile(latency, 99) by HttpMethod, Resource
| render table

Los resultados de esta consulta pueden ayudarle a identificar los tipos de llamadas API que producen errores en los SLO de Kubernetes ascendentes. En la mayoría de los casos, un cliente infractor realiza demasiadas LIST llamadas en un conjunto muy numeroso de objetos o en objetos excesivamente grandes. Los límites de escalabilidad del servidor de API o etcd son multidimensionales y se explican en Umbrales de escalabilidad de Kubernetes.

Solución 5a: Ajuste del patrón de llamada api

Para reducir la presión en el plano de control, considere la posibilidad de ajustar el patrón de llamada del servidor de API del cliente. Consulte los procedimientos recomendados.

Solución 5b: Restringir un cliente que sobrecarga el plano de control

Si no puede ajustar el cliente, use la característica Prioridad y Equidad en Kubernetes para limitar el cliente. Esta característica puede ayudar a conservar el estado del plano de control y evitar que se produzcan errores en otras aplicaciones.

En el siguiente procedimiento se muestra cómo regular la API "LIST Pods" para un cliente infractor, con un límite de cinco llamadas simultáneas.

  1. Cree un flowSchema que coincida con el patrón de llamada API del cliente infractor:

    apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
    kind: FlowSchema
    metadata:
      name: restrict-bad-client
    spec:
      priorityLevelConfiguration:
        name: very-low-priority
      distinguisherMethod:
        type: ByUser
      rules:
      - resourceRules:
        - apiGroups: [""]
          namespaces: ["default"]
          resources: ["pods"]
          verbs: ["list"]
        subjects:
        - kind: ServiceAccount
          serviceAccount:
            name: bad-client-account
            namespace: default 
    
  2. Cree una configuración de prioridad inferior para limitar las llamadas API incorrectas del cliente:

    apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
    kind: PriorityLevelConfiguration
    metadata:
      name: very-low-priority
    spec:
      limited:
        assuredConcurrencyShares: 5
        limitResponse:
          type: Reject
      type: Limited
    
  3. Observe la llamada limitada en las métricas del servidor de API:

    kubectl get --raw /metrics | grep "restrict-bad-client"
    

Causa 6: Uso elevado de memoria etcd (por alerta)

Es posible que reciba una alerta que indique que el uso de memoria etcd supera los 20 GiB. Esta alerta indica que el clúster está experimentando una carga intensiva del servidor de API. La carga puede propagarse en cascada y sobrecargar la capacidad de memoria de etcd. Si la carga excesiva no se resuelve rápidamente, puede provocar una degradación del rendimiento o interrupciones.

Para comprobar el uso de memoria etcd actual y comprender los factores específicos que contribuyen al consumo elevado de memoria, vaya a Diagnóstico y solución de problemas en Azure Portal. Ejecute el Analizador de rendimiento de Etcd al buscar "rendimiento etcd" en el cuadro de búsqueda. El analizador muestra el desglose del uso de memoria y ayuda a identificar si la causa del problema es altas tasas de solicitud, recuentos de objetos grandes o tamaños de objetos grandes.

Captura de pantalla del Analizador de rendimiento de Etcd que muestra el desglose del uso de memoria y los principales colaboradores en AKS.

La causa principal del uso elevado de memoria etcd suele ser una carga intensiva del servidor de API. Este problema se superpone a las otras causas que se describen en este artículo. Para identificar el problema específico que afecta al clúster, use la siguiente solución.

Solución 6: Usar las herramientas de diagnóstico existentes para identificar y resolver la causa subyacente

Determinar el factor de contribución principal

La alerta de memoria etcd puede desencadenarse debido a cualquier combinación de factores. Identifique qué factor es más problemático en su situación.

  • Si se identifican llamadas LIST o PUT excesivas: siga la solución Cause 5 para ajustar los patrones de llamada api o limitar los clientes problemáticos.

  • Si hay demasiados objetos almacenados en etcd: siga la solución Cause 3 para limpiar objetos e implementar directivas de retención.

  • Si los objetos grandes consumen memoria excesiva: céntrese en las siguientes técnicas de reducción de tamaño de objeto.

    • Para reducir el tamaño de la especificación de pod, mueva las variables de entorno de la especificación de pod a ConfigMaps.
    • Divida secretos grandes o ConfigMaps en partes más pequeñas y manejables.
    • Revise y optimice las especificaciones de recursos en las aplicaciones.
    • Reduzca los recuentos de revisiones.
    # Example: Clean up completed jobs that may have large specifications
    kubectl delete jobs --field-selector status.successful=1
    
    # Example: Clean up failed pods that may be consuming memory
    kubectl delete pods --field-selector status.phase=Failed
    

Tip

La alerta de memoria etcd suele indicar una combinación de factores. Comience en el Analizador de enumeración intensivo de recursos del servidor de API para identificar problemas de frecuencia de solicitudes inmediatas. A continuación, use Etcd Performance Analyzer y Etcd Capacity Analyzer para analizar las contribuciones relacionadas con objetos al uso de memoria.

Importante

La presión severa de memoria etcd puede hacer que el servidor de API deje de responder. Esta condición puede impedir que realice los pasos de diagnóstico que se proporcionan en este artículo. En esta situación, póngase en contacto con el soporte técnico de Azure inmediatamente para solicitar ayuda para limpiar objetos problemáticos o limitar las solicitudes excesivas.

Aviso de declinación de responsabilidades sobre la información de contacto de terceros

Microsoft proporciona información de contacto de otros proveedores para ayudarle a encontrar información adicional sobre este tema. Esta información de contacto puede cambiar sin previo aviso. Microsoft no garantiza la precisión de esta información de contacto de terceros.

Aviso de declinación de responsabilidades sobre la información de terceros

Los productos de otros fabricantes que se mencionan en este artículo han sido creados por compañías independientes de Microsoft. Microsoft no ofrece ninguna garantía, ya sea implícita o de otro tipo, sobre la confiabilidad o el rendimiento de dichos productos.