Cómo las prioridades de los pods en Kubernetes provocaron el tiempo de inactividad en Grafana Labs

Nota. traducir: Presentamos a su atención detalles técnicos sobre los motivos de la reciente caída del servicio en la nube mantenido por los creadores de Grafana. Este es un ejemplo clásico de cómo una característica nueva y aparentemente extremadamente útil diseñada para mejorar la calidad de la infraestructura... puede causar daño si no se tienen en cuenta los numerosos matices de su aplicación en las realidades de producción. Es fantástico cuando aparecen materiales como este que te permiten aprender no sólo de tus errores. Los detalles están en la traducción de este texto del vicepresidente de producto de Grafana Labs.

Cómo las prioridades de los pods en Kubernetes provocaron el tiempo de inactividad en Grafana Labs

El viernes 19 de julio, el servicio Hosted Prometheus en Grafana Cloud dejó de funcionar durante aproximadamente 30 minutos. Pido disculpas a todos los clientes afectados por la interrupción. Nuestro trabajo es brindarle las herramientas de monitoreo que necesita y entendemos que no tenerlas disponibles puede hacerle la vida más difícil. Nos tomamos este incidente muy en serio. Esta nota explica lo que sucedió, cómo respondimos y qué estamos haciendo para garantizar que no vuelva a suceder.

Prehistoria

El servicio Grafana Cloud Hosted Prometheus se basa en Corteza — Proyecto CNCF para crear un servicio Prometheus multiinquilino, de alta disponibilidad y escalable horizontalmente. La arquitectura Cortex consta de un conjunto de microservicios individuales, cada uno de los cuales realiza su propia función: replicación, almacenamiento, consultas, etc. Cortex está en desarrollo activo y constantemente agrega nuevas funciones y mejora el rendimiento. Regularmente implementamos nuevas versiones de Cortex en clústeres para que los clientes puedan aprovechar estas características; afortunadamente, Cortex se puede actualizar sin tiempo de inactividad.

Para actualizaciones perfectas, el servicio Ingester Cortex requiere una réplica de Ingester adicional durante el proceso de actualización. (Nota. traducir: Ingestión - el componente básico de la corteza. Su trabajo es recopilar un flujo constante de muestras, agruparlas en fragmentos de Prometheus y almacenarlas en una base de datos como DynamoDB, BigTable o Cassandra). Esto permite a los Ingesters antiguos reenviar datos actuales a los nuevos Ingesters. Vale la pena señalar que los Ingesters exigen recursos. Para que funcionen, es necesario tener 4 núcleos y 15 GB de memoria por pod, es decir. 25% de la potencia de procesamiento y memoria de la máquina base en el caso de nuestros clusters Kubernetes. En general, normalmente tenemos muchos más recursos no utilizados en el clúster que 4 núcleos y 15 GB de memoria, por lo que podemos activar fácilmente estos ingestadores adicionales durante las actualizaciones.

Sin embargo, sucede a menudo que durante el funcionamiento normal ninguna de las máquinas tiene este 25% de recursos no utilizados. Sí, ni siquiera nos esforzamos: la CPU y la memoria siempre serán útiles para otros procesos. Para resolver este problema decidimos utilizar Prioridades del módulo de Kubernetes. La idea es dar a los Ingesters una mayor prioridad que otros microservicios (sin estado). Cuando necesitamos ejecutar un Ingester adicional (N+1), desplazamos temporalmente otros pods más pequeños. Estos pods se transfieren a recursos libres en otras máquinas, dejando un “agujero” lo suficientemente grande para ejecutar un Ingester adicional.

El jueves 18 de julio, implementamos cuatro nuevos niveles de prioridad en nuestros clústeres: crítico, alto, promedio и bajo. Fueron probados en un clúster interno sin tráfico de clientes durante aproximadamente una semana. De forma predeterminada, se reciben pods sin una prioridad especificada promedio prioridad, la clase fue establecida para Ingesters con alto prioridad. Crítico estaba reservado para monitoreo (Prometheus, Alertmanager, node-exporter, kube-state-metrics, etc.). Nuestra configuración está abierta y puedes ver el PR. aquí.

Accidente

El viernes 19 de julio, uno de los ingenieros lanzó un nuevo clúster Cortex dedicado para un cliente grande. La configuración de este clúster no incluía nuevas prioridades de pods, por lo que a todos los pods nuevos se les asignó una prioridad predeterminada: promedio.

El clúster de Kubernetes no tenía suficientes recursos para el nuevo clúster de Cortex y el clúster de producción existente de Cortex no se actualizó (los Ingesters se quedaron sin высокого prioridad). Dado que los Ingesters del nuevo cluster por defecto tenían promedio prioridad, y los pods existentes en producción funcionaban sin ninguna prioridad, los Ingesters del nuevo cluster reemplazaron a los Ingesters del cluster de producción Cortex existente.

El ReplicaSet para el Ingester desalojado en el clúster de producción detectó el pod desalojado y creó uno nuevo para mantener la cantidad especificada de copias. El nuevo pod fue asignado por defecto promedio prioridad, y otro “viejo” Ingester en producción perdió sus recursos. El resultado fue proceso de avalancha, lo que provocó el desplazamiento de todas las cápsulas de Ingester a los grupos de producción de Cortex.

Los ingestadores tienen estado y almacenan datos de las 12 horas anteriores. Esto nos permite comprimirlos de manera más eficiente antes de escribirlos en un almacenamiento a largo plazo. Para lograr esto, Cortex fragmenta los datos en series usando una tabla hash distribuida (DHT) y replica cada serie en tres Ingesters usando consistencia de quórum estilo Dynamo. Cortex no escribe datos en los Ingesters que están deshabilitados. Por lo tanto, cuando una gran cantidad de Ingesters abandonan el DHT, Cortex no puede proporcionar una replicación suficiente de las entradas y fallan.

Detección y remediación

Nuevas notificaciones de Prometheus basadas en "presupuesto de errores" (basado en el presupuesto de errores — los detalles aparecerán en un artículo futuro) comenzó a hacer sonar la alarma 4 minutos después del inicio del apagado. Durante los siguientes cinco minutos aproximadamente, ejecutamos algunos diagnósticos y ampliamos el clúster de Kubernetes subyacente para albergar los clústeres de producción nuevos y existentes.

Después de otros cinco minutos, los antiguos Ingesters escribieron con éxito sus datos, los nuevos se iniciaron y los grupos de Cortex volvieron a estar disponibles.

Se dedicaron otros 10 minutos a diagnosticar y corregir errores de falta de memoria (OOM) de los servidores proxy inversos de autenticación ubicados frente a Cortex. Los errores de OOM fueron causados ​​por un aumento diez veces mayor en QPS (creemos que debido a solicitudes demasiado agresivas de los servidores Prometheus del cliente).

Secuelas

El tiempo de inactividad total fue de 26 minutos. No se perdió ningún dato. Los integradores han cargado con éxito todos los datos en memoria en el almacenamiento a largo plazo. Durante el cierre, los servidores cliente Prometheus almacenados en el búfer se eliminaron (remoto) grabaciones usando nueva API escritura_remota basado en WAL (escrito por Callum Styan de Grafana Labs) y repitió las escrituras fallidas después del bloqueo.

Cómo las prioridades de los pods en Kubernetes provocaron el tiempo de inactividad en Grafana Labs
Operaciones de escritura del clúster de producción

Hallazgos

Es importante aprender de este incidente y tomar las medidas necesarias para evitar que se repita.

En retrospectiva, no deberíamos haber establecido el valor predeterminado promedio prioridad hasta que todos los Ingesters en producción hayan recibido alto una prioridad. Además, era necesario cuidarlos con antelación. alto prioridad. Todo está arreglado ahora. Esperamos que nuestra experiencia ayude a otras organizaciones a considerar el uso de prioridades de pod en Kubernetes.

Agregaremos un nivel adicional de control sobre la implementación de cualquier objeto adicional cuyas configuraciones sean globales para el clúster. De ahora en adelante, dichos cambios serán evaluados bоmas gente. Además, la modificación que causó el bloqueo se consideró demasiado menor para un documento de proyecto separado; solo se discutió en una edición de GitHub. De ahora en adelante, todos estos cambios en las configuraciones irán acompañados de la documentación adecuada del proyecto.

Finalmente, automatizaremos el cambio de tamaño del proxy inverso de autenticación para evitar la sobrecarga de OOM que presenciamos y revisaremos la configuración predeterminada de Prometheus relacionada con el respaldo y el escalado para evitar problemas similares en el futuro.

El fallo también tuvo algunas consecuencias positivas: habiendo recibido los recursos necesarios, Cortex se recuperó automáticamente sin intervención adicional. También adquirimos una valiosa experiencia trabajando con Grafana loki - nuestro nuevo sistema de agregación de registros, que ayudó a garantizar que todos los Ingesters se comportaran correctamente durante y después de la falla.

PD del traductor

Lea también en nuestro blog:

Fuente: habr.com

Añadir un comentario