Distrito Telefónica. Hub de Innovación y Talento
Cuando se opera y evoluciona un sistema complejo, la observabilidad es imprescindible. Normalmente, muchos componentes y capas de software se entrelazan en flujos complejos. Como resultado, es difícil extraer algunas ideas valiosas para diagnosticar y abordar los principales cuellos de botella en el rendimiento o reducir el retraso e2e. En la misma dirección, poder rastrear solicitudes específicas a través del sistema e2e es clave para una depuración adecuada de errores o escenarios hipotéticos.
Tradicionalmente, la observabilidad de los sistemas se basa en tres pilares principales: Registros, Métricas y Rastreo (aunque se pueden considerar algunos pilares extra, los mantendremos fuera del ámbito de este post). En este contexto de observabilidad, OpenTelemetry ha conseguido muchos adeptos y se presenta como una opción tentadora que merece la pena probar. Nos gustaría compartir contigo cómo lo estamos utilizando en nuestra plataforma.
OpenTelemetry es un proyecto alojado en el CNCF
Puedes encontrar información detallada sobre la plataforma Telefónica Kernel en el siguiente enlace. Telefónica Kernel es también la plataforma subyacente compatible con GSMA Iniciativa Open Gateway en la huella de Telefónica, como se ha demostrado recientemente durante el MWC 2023 en Barcelona. Puedes consultar las API que ofrece Open Gateway aquí.
Telefónica Kernel se compone de varios subsistemas (no se necesitan más detalles en este punto) y se integra tanto hacia el norte, con servicios que consumen las API y SDK de Telefónica Kernel ; como hacia el sur, con redes y sistemas locales de telco mediante API e interfaces nativas de telco proporcionadas localmente por cada operación de Telefónica. En este contexto, como en cualquier otro escenario de sistema complejo, la observabilidad e2e tiene un gran valor.
En este post nos centraremos en el pilar de la observabilidad del rastreo distribuido pilar. La plataforma Telefónica Kernel ya cuenta con registros sólidos de última generación y subsistemas de métricas construidos sobre ElasticSearch y pilas Prometheus/Grafana respectivamente. Pero no existía un soporte actual para el rastreo en toda la plataforma, así que trabajamos duro para solucionarlo.
En el sitio web Datadog, el rastreo distribuido podría definirse como:
"El rastreo distribuido es un método de rastreo de las solicitudes de las aplicaciones a medida que fluyen desde los dispositivos frontend hasta los servicios backend y las bases de datos"
Un rastro está compuesto por un trace-id, que lo identifica de forma única en todo el sistema, y un conjunto de tramos. Cada 'tramo' representa el paso de la solicitud por cada componente implicado en el procesamiento e2e y contiene un conjunto de atributos con información útil (tiempo de duración, id, etc.).
Concepto de rastro y tramo en el sitio web de Jaeger
Es importante aclarar en este punto que Telefónica Kernel es una plataforma multilocal desplegada en la nube Azure, basada en Azure managed Kubernetes Service (AKS), como infraestructura de computación subyacente. Es "global" porque está disponible en toda la huella de Telefónica pero lo hace con un despliegue específico por país donde opera Telefónica (en la región correspondiente de Azure ).
De esta forma, los servicios construidos sobre las API de Telefónica Kernel pueden ser accesibles a cualquier cliente de Telefónica (por lo que son globales en la huella de Telefónica), pero esto se hace mediante un despliegue local dedicado por operación local, que es operado como cualquier otro sistema o red local por la operación local. Hay varias razones para ese enfoque multilocal, no solo técnicas, pero esto también queda fuera del alcance de este post.
El enfoque seguido para habilitar el rastreo distribuido de forma transparente en Telefónica Kernel fue aprovechar la capacidad de rastreo proporcionada por la malla de servicios. Internamente en Telefónica Kernel, se estaba integrando una malla de servicios en el momento en que se evaluaba el rastreo distribuido. Los objetivos iniciales de la malla de servicios eran proporcionar capacidades de gestión del tráfico necesarias en la interconexión de los distintos componentes de la plataforma. Nosotros "secuestramos" esa actividad en curso y ampliamos su alcance para incluir el rastreo distribuido como una de sus primeras características aplicables.
El concepto Sidecar es una malla de servicios, fuente sitio web de Istio
Para el análisis de rendimiento de la lista de seleccionados, hemos utilizado la misma prueba de rendimiento utilizada en el proyecto Linkerd para compararla con Istio (llamada emojivoto aplicación), así podemos tener algo común para comparar entre ellos.
Componentes simples de la aplicación Emojivoto, de GitHub
vCPU utilizada por el proxy sidecar sin rastreo
vCPU (normalizada en 1 K/s) utilizada por el proxy sidecar con el seguimiento habilitado y el muestreo del 1 %
Memoria utilizada por el proxy sidecar, en MB
En estas circunstancias, preferimos mantener Cilium como una opción prometedora para seguir rastreando (los beneficios potenciales en términos de retraso y consumo de recursos son enormes) pero centrarnos en Linkerd e Istio inicialmente como enfoque de menor riesgo.
En cuanto a Linkerd, durante los preparativos de la prueba encontramos una limitación de bloqueo sobre la capacidad del proxy de Linkerd para incluir una lista configurable de cabeceras HTTP como parte de los atributos de rastreo (que en realidad es compatible con Envoy). Necesitamos esa característica para poder añadir la cabecera de Telefónica Kernel e2e Correlator-Id a los atributos de rastreo, de forma que podamos usarlo como clave para emparejar el rastreo y el registro realizado en la plataforma para la misma solicitud. Esta limitación nos impidió aprovechar un consumo menor de recursos del proxy de Linkerd en comparación con Istio Envoy.
Por último, Istio se estaba utilizando actualmente en otros equipos de Telefónica CDO Engineering. Teniendo todo esto en cuenta, decidimos seguir adelante con Istio como el enfoque con mejor relación riesgo/rendimiento. De todas formas esta es una decisión a corto plazo que podría ser revertida en caso de cualquier cambio relevante sobre Cillium de Linkerd, o cualquier otra malla relevante.
Una vez que hemos decidido utilizar Istio como malla de servicios, tenemos que construir realmente la infraestructura de rastreo que se alimentará con el rastreo generado por la malla. Ahí es donde Recolector OpenTelemetry entra en la ecuación. Necesitamos desplegar el Recolector OTEL en nuestra plataforma, pero tenemos que hacerlo de forma que se cubran algunos requisitos:
El primer requisito lo cumple el Recolector OpenTelemetry porque proporciona una extensa lista de recolectores y exportadores en diferentes formatos y protocolos, incluidos los mencionados explícitamente en el requisito.
A efectos del requisito de muestreo "coherente", la propagación del contexto de rastreo garantiza que la decisión de muestreo pueda progresar entre servicios basados en Telefónica Kernel, componentes internos de Telefónica Kernel y plataformas y sistemas locales. Los componentes de Telefónica Kernel reenvían este contexto (inicialmente Cabecera B3 y W3C en un futuro a corto plazo) cuando el tráfico cruza la plataforma, por lo que la decisión de muestreo tomada en algún punto del flujo será reenviada.
Rastreo de la propagación del contexto mediante cabeceras B3, desde github
Modelo de canalización del recopilador de OpenTelemetry, desde github
Las acciones realizadas en estos pasos de canalización (qué recolectores, procesamiento y exportaciones se utilizan) se define como configuración del despliegue de OTEL mediante la definición de la canalización que será ejecutada por el despliegue del Recolector OTEL.
Cada instancia del Recolector OpenTelemetry es una canalización completa e independiente. Aumentar el número de instancias de despliegue del Recolector OpenTelemetry aumentará el rendimiento solo si equilibramos la carga de los tramos de rastreo entrante al conjunto de instancias disponibles. Pero este equilibrio de tramos debe hacerse teniendo en cuenta cómo afectará a la forma de realizar el muestreo.
Si no se toman medidas especiales, podría ocurrir que los tramos de rastreo generados por diferentes componentes al gestionar la misma solicitud sean procesados por diferentes instancias del Recolector OpenTelemetry (no se utiliza el equilibrio de carga basado en trace-id). Un escenario específico al que hay que prestar especial atención es cuando se utiliza políticas de "muestreo de cola" que retrasarán la decisión de muestreo hasta que se hayan recibido todos los componentes del rastro(tramos).
Un ejemplo de política de "muestreo de cola" es muestrear solo las solicitudes fallidas. Para ello sería necesario que todos los tramos de un rastro fueran gestionados por la misma instancia del recolector. Esa instancia esperaría a ver el resultado de la solicitud para decidir si esta tiene que ser muestreada o no. El equilibrio de carga de rastreo debe garantizar que se tenga en cuenta el trace-id para que todos los tramos del mismo trace-id terminen en la misma instancia del recolector.
En el escenario de Telefónica Kernel no tenemos actualmente ningún plan de "muestreo de cola". No confiamos en el muestreo realizado en OpenTelemetry debido al impacto que tiene tanto en el Recoletor OpenTelemetry como en los sidecars de malla de servicios (como se ha explicado anteriormente). El muestreo es ejecutado mediante servicios externos de invocación o, en caso de que no se aplique ese muestreo externo, será realizado por el controlador de ingreso de Telefónica Kernel, Traefik.
Debido al volumen de tráfico gestionado por el controlador de ingreso, como criterio de diseño, decidimos evitar la inyección de sidecar a Traefik y confiar en las capacidades nativas de rastreo proporcionadas por Traefik incluyendo OpenCensus (precursor de OTLP) y OTLP en la última versión principal (v3.0, actualmente en beta).
Combinando todo, decidimos dividir la canalización de OpenTelemetry en dos subcanalizaciones diferentes, cada una ejecutada por distintos despliegues de OpenTelemetry (con su propia definición de canalización y conjunto de instancias) desacopladas por una cola tipo Kafka entre ellos. Definimos 2 despliegues OTEL independientes:
2 pipelines Enfoque de implementación de OTEL
Además, la capacidad de transmisión(cola Kafka ) utilizada entre ambos despliegues es una capacidad de transmisión SaaS(Azure Eventhubs) proporcionada por el proveedor de infraestructura en la nube. Esta decisión(streaming SaaS) se tomó para poder escalar adecuadamente sin restricciones en las primeras fases. Una vez adquirida experiencia en la producción, podrían estudiarse otras opciones para aplicarlo.
En nuestro caso, HPA(Horizontal Pod Autoscaling) para la canalización del recolector se basa en la CPU y la memoria utilizadas por los contenedores, pero HPA, para la distribución de la canalización incluye también métricas de transmisión(desfase de la cola Kafka) como criterio de escalado, mediante soluciones HPA como Keda. Con Keda podemos definir reglas de escalado basadas en las métricas recopiladas por Prometheus, incluidas las generadas por el propio Recolector OpenTelemetry . El escalado de ambos despliegues de Recolector OTEL es independiente el uno del otro.
Este desacoplamiento de la exportación de la recolección nos permite mantener la política de reintentos activada en nuestra canalización de exportación, sin preocuparnos de perder el rastreo entrante debido a la sobrecarga causada por los reintentos. Esta política de reintentos nos ayudará a cumplir el requisito de minimizar la pérdida de información de los rastros debido a fallos en la entrega sin causar una sobrecarga que pueda afectar al manejo en la recepción de los rastros(protección de contrapresión ).
Los despliegues de Telefónica Kernel tienen (inicialmente) 2 destinos diferentes para los rastros: un despliegue local Jaeger que forma parte de la plataforma Telefónica Kernel y un backend de rastros remoto proporcionado por la operación local de Telefónica. Para esto último, se acordó utilizar el formato OTLP ya que se verificó que las soluciones comerciales de rastreo desplegadas en la huella de Telefónica son compatibles con este formato común no bloqueado por el proveedor. Para esta integración, actualmente utilizamos el enlace GRPC OTLP, protegido con TLS.
Como complemento al subsistema OTEL, también desplegamos una solución de backend de rastreo como parte de la plataforma Telefónica Kernel . Actualmente estamos utilizando el backend de rastreo Jaegertracing, que persiste en la misma infraestructura de ElasticSearch que también es compatible con nuestro subsistema de registro de Telefónica Kernel . En realidad, es la implementación actual del subsistema de registro de Telefónica Kernel que inspiró este enfoque de dos canalizaciones para el subsistema de rastreo.
Como se mencionó al principio del post, actualmente planeamos utilizar OpenTelemetry solo para fines de rastreo. Los registros y métricas son gestionados por su correspondiente subsistema de plataforma. En cuanto a los registros, la posibilidad de incluir cabeceras HTTP en los atributos de rastreo es la clave que permite la comprobación cruzada de registros y rastros de la misma solicitud. Además, en el momento de la elaboración de este post, solo se declaró una capacidad de rastreo como estable en el Recolector OpenTelemetry, con registros y métricas presentadas como beta en muchos procesadores recoletores y exportadores OTEL .
En el despliegue en Telefónica Kernel de Jaeger, como rastreo de backend interno de la plataforma, obtuvimos un beneficio extra derivado del enfoque de 2 canales para el despliegue de OpenTelemetry . Como ya disponemos de un paso de transmisión en la canalización de rastreo, no es necesario desplegar Jaeger con Kafka interno. Como la canalización del exportador de OTEL implementa reintentos en caso de error, es posible desplegar Jaeger sin Kafka interno, y dejar que HPA Jaeger Ingest escale adecuadamente, sin preocuparse de rastrear tramos perdidos en la canalización interna Jaeger .
Componentes internos de Jaeger del sitio web de Jaeger
Esperamos que nuestras experiencias te sean de utilidad. ¡¡Te deseamos un feliz rastreo!!