Solución de problemas de servidor de API y etcd en Azure Kubernetes Services
Esta guía está diseñada para ayudarle a identificar y resolver cualquier problema poco probable que pueda encontrarse en el servidor de API en implementaciones de Microsoft Azure Kubernetes Services (AKS) de gran tamaño.
Microsoft ha probado 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 tiene la capacidad de escalar horizontalmente y entregar automáticamente objetivos de nivel de servicio (SLO) de Kubernetes. Si experimenta latencias elevadas o tiempos de espera, es probable que se deba a que hay una pérdida de recursos en el directorio distribuido etc
(etcd) o un cliente infractor tiene llamadas API excesivas.
Requisitos previos
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 de Log Analytics. Para determinar si los registros se recopilan mediante el modo específico del recurso o diagnóstico de Azure, consulte la hoja Configuración de diagnóstico en Azure Portal.
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. Esto 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
Eventos de estado del recurso.
AKS proporciona eventos de Resource Health para el tiempo de inactividad crítico del componente. Antes de continuar, asegúrese de que no haya ningún evento crítico notificado en Resource Health.
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.
Síntomas
En la tabla siguiente se describen los síntomas comunes de los errores del servidor de API:
Síntoma | Description |
---|---|
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 se agota el tiempo de espera de los comandos. |
Latencias elevadas | Se produce un error en las latencias elevadas que hacen que los SLO de Kubernetes produzcan un error. Por ejemplo, el kubectl comando tarda más de 30 segundos en enumerar pods. |
Pod del servidor de API en CrashLoopbackOff estado o errores de llamada de webhook accesibles |
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. |
Lista de comprobación de solución de problemas
Si experimenta tiempos de latencia alta, siga estos pasos para identificar el cliente infractor y los tipos de llamadas API que producen errores.
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 la consulta siguiente 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_
Nota:
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 AKSAudit
tabla. 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. Un indicador mejor de la carga real que genera cada cliente en el servidor de API es la latencia de respuesta que experimentan.
Paso 2: Identificar y trazar la latencia media de las solicitudes de servidor de API por agente de usuario
Para identificar la latencia media de las solicitudes de servidor de API por agente de usuario como trazadas 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 generada por cada agente de usuario a lo largo del tiempo.
Sugerencia
Al analizar estos datos, puede identificar patrones y anomalías que pueden indicar problemas en el clúster o las aplicaciones de AKS. Por ejemplo, puede observar que un usuario determinado está experimentando una latencia alta. Este escenario puede indicar el tipo de llamadas API que están causando una carga excesiva en el servidor de API o en etcd.
Paso 3: Identificación de llamadas API incorrectas para un agente de usuario determinado
Ejecute la consulta siguiente 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 ser útiles para 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 podría estar realizando demasiadas LIST
llamadas en un gran conjunto de objetos u objetos que son demasiado grandes. Desafortunadamente, no hay límites de escalabilidad difíciles disponibles para guiar a los usuarios sobre la escalabilidad del servidor de API. Los límites de escalabilidad del servidor de API o etcd dependen de varios factores que se explican en umbrales de escalabilidad de Kubernetes.
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.
Nota:
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 innecesariamente el tráfico entre los nodos del agente y el servidor de API.
Causa 2: un cliente infractor pierde objetos etcd y da como resultado una ralentización de etcd
Un problema común es crear continuamente objetos sin eliminar los que no se usaron en la base de datos etcd. Esto puede causar problemas de rendimiento cuando etcd se ocupa de 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 de la base de datos etcd (4 gigabytes de forma predeterminada).
Para comprobar el uso de la base de datos etcd, vaya a Diagnóstico y solución de problemas en Azure Portal. Ejecute la herramienta de diagnóstico de problemas de disponibilidad de Etcd buscando "etcd" en el cuadro de búsqueda. La herramienta de diagnóstico muestra el desglose del uso y el tamaño total de la base de datos.
Si solo desea una manera rápida de ver el 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"
Nota:
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
.
Solución 2: 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, puede limitar 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 se pueden crear, puede definir cuotas de objetos.
Si ha identificado objetos que ya no están en uso, pero que están ocupando recursos, considere la posibilidad de eliminarlos. Por ejemplo, puede eliminar 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, puede establecer 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.
Causa 3: un cliente infractor realiza llamadas LIST o PUT excesivas
Si determina que etcd no está sobrecargado con demasiados objetos, un cliente infractor podría estar realizando demasiadas LIST
llamadas o PUT
al servidor de API.
Solución 3a: Ajuste del patrón de llamada api
Considere la posibilidad de ajustar el patrón de llamada API del cliente para reducir la presión en el plano de control.
Solución 3b: Limitación de un cliente que es abrumador el plano de control
Si no puede ajustar el cliente, puede usar 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 procedimiento siguiente se muestra cómo limitar la API LIST Pods de un cliente infractor establecido en cinco llamadas simultáneas:
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
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
Observe la llamada limitada en las métricas del servidor de API.
kubectl get --raw /metrics | grep "restrict-bad-client"
Causa 4: un webhook personalizado podría provocar un interbloqueo en los pods del servidor de API
Un webhook personalizado, como Kyverno, podría estar causando un interbloqueo dentro de los pods del servidor de 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
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 4: Eliminación de 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.
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.
Ponte en contacto con nosotros para obtener ayuda
Si tiene preguntas o necesita ayuda, cree una solicitud de soporte o busque consejo en la comunidad de Azure. También puede enviar comentarios sobre el producto con los comentarios de la comunidad de Azure.