Istio y Kubernetes en producción. Parte 2. Seguimiento

En el pasado статье Analizamos los componentes básicos de Service Mesh Istio, nos familiarizamos con el sistema y respondimos las principales preguntas que suelen surgir al empezar a trabajar con Istio. En esta parte veremos cómo organizar la recopilación de información de rastreo a través de una red.

Istio y Kubernetes en producción. Parte 2. Seguimiento

Lo primero que les viene a la mente a muchos desarrolladores y administradores de sistemas cuando escuchan las palabras Service Mesh es seguimiento. De hecho, agregamos un servidor proxy especial a cada nodo de la red a través del cual pasa todo el tráfico TCP. Parece que ahora es posible enviar fácilmente información sobre todas las interacciones de la red. Desafortunadamente, en realidad hay muchos matices que deben tenerse en cuenta. Mirémoslos.

Concepto erróneo número uno: podemos obtener datos de senderismo online de forma gratuita.

De hecho, de forma relativamente gratuita, sólo podemos conectar los nodos de nuestro sistema mediante flechas y la velocidad de datos que pasa entre servicios (de hecho, sólo el número de bytes por unidad de tiempo). Sin embargo, en la mayoría de los casos, nuestros servicios se comunican a través de algún tipo de protocolo de capa de aplicación, como HTTP, gRPC, Redis, etc. Y, por supuesto, queremos ver información de seguimiento específicamente para estos protocolos; queremos ver la tasa de solicitudes, no la tasa de datos. Queremos comprender la latencia de las solicitudes utilizando nuestro protocolo. Finalmente, queremos ver la ruta completa que sigue una solicitud desde que inicia sesión en nuestro sistema hasta recibir una respuesta del usuario. Este problema ya no es tan fácil de resolver.

Primero, veamos cómo se ve el envío de tramos de seguimiento desde un punto de vista arquitectónico en Istio. Como recordamos de la primera parte, Istio tiene un componente separado llamado Mixer para recopilar telemetría. Sin embargo, en la versión actual 1.0.*, el envío se realiza directamente desde servidores proxy, es decir, desde el proxy enviado. El proxy Envoy admite el envío de tramos de seguimiento utilizando el protocolo zipkin listo para usar. Es posible conectar otros protocolos, pero sólo mediante un complemento. Con Istio obtenemos inmediatamente un proxy enviado ensamblado y configurado, que solo admite el protocolo zipkin. Si queremos utilizar, por ejemplo, el protocolo Jaeger y enviar tramos de seguimiento a través de UDP, necesitaremos crear nuestra propia imagen istio-proxy. Hay soporte para complementos personalizados para istio-proxy, pero todavía está en la versión alfa. Por lo tanto, si queremos prescindir de una gran cantidad de configuraciones personalizadas, la gama de tecnologías utilizadas para almacenar y recibir tramos de seguimiento se reduce. De los sistemas principales, de hecho, ahora puedes usar el propio Zipkin, o Jaeger, pero enviar todo allí usando el protocolo compatible con zipkin (que es mucho menos eficiente). El protocolo zipkin en sí implica enviar toda la información de rastreo a los recolectores a través del protocolo HTTP, lo cual es bastante costoso.

Como ya dije, queremos rastrear protocolos a nivel de aplicación. Esto significa que los servidores proxy que se encuentran junto a cada servicio deben comprender qué tipo de interacción está ocurriendo en ese momento. De forma predeterminada, Istio configura todos los puertos para que sean TCP simple, lo que significa que no se enviarán rastros. Para que se envíen los seguimientos, primero debe habilitar esta opción en la configuración de malla principal y, lo que es muy importante, nombrar todos los puertos de las entidades de servicio de Kubernetes de acuerdo con el protocolo que se utiliza en el servicio. Es decir, por ejemplo, así:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
    name: http
  selector:
    app: nginx

También puede usar nombres compuestos como http-magic (Istio verá http y reconocerá ese puerto como un punto final http). El formato es: proto-extra.

Para no parchear una gran cantidad de configuraciones para determinar el protocolo, puede utilizar una solución sucia: parchear el componente Pilot en el momento en que recién está realiza la lógica de definición de protocolo. Al final, por supuesto, será necesario cambiar esta lógica a la estándar y pasar a una convención de nomenclatura para todos los puertos.

Para comprender si el protocolo está realmente definido correctamente, debe ingresar a cualquiera de los contenedores sidecar con el proxy del enviado y realizar una solicitud al puerto de administración de la interfaz del enviado con la ubicación /config_dump. En la configuración resultante, debe observar el campo de operación del servicio deseado. Se utiliza en Istio como identificador del lugar donde se realiza la solicitud. Para personalizar el valor de este parámetro en Istio (luego lo veremos en nuestro sistema de seguimiento), es necesario especificar el indicador serviceCluster en la etapa de lanzamiento del contenedor sidecar. Por ejemplo, se puede calcular así a partir de variables obtenidas de la API de Kubernetes descendente:

--serviceCluster ${POD_NAMESPACE}.$(echo ${POD_NAME} | sed -e 's/-[a-z0-9]*-[a-z0-9]*$//g')

Un buen ejemplo para entender cómo funciona el rastreo en enviado es aquí.

El propio punto final para enviar tramos de seguimiento también se debe especificar en los indicadores de lanzamiento del proxy del enviado, por ejemplo: --zipkinAddress tracing-collector.tracing:9411

Concepto erróneo número dos: podemos obtener de forma económica rastros completos de las solicitudes a través del sistema listo para usar

Desafortunadamente, no lo es. La complejidad de la implementación depende de cómo ya se haya implementado la interacción de los servicios. ¿Porqué es eso?

El hecho es que para que istio-proxy pueda comprender la correspondencia de las solicitudes entrantes a un servicio con las que salen del mismo servicio, no basta con interceptar todo el tráfico. Necesita tener algún tipo de identificador de comunicación. El proxy de envío HTTP utiliza encabezados especiales, mediante los cuales el enviado comprende qué solicitud específica al servicio genera solicitudes específicas a otros servicios. Lista de dichos encabezados:

  • ID de solicitud x,
  • x-b3-traceida,
  • x-b3-español,
  • x-b3-padresespañol,
  • x-b3-muestreado,
  • banderas x-b3,
  • x-ot-span-contexto.

Si tiene un único punto, por ejemplo, un cliente básico, en el que puede agregar dicha lógica, entonces todo está bien, solo necesita esperar a que esta biblioteca se actualice para todos los clientes. Pero si tiene un sistema muy heterogéneo y no hay unificación para pasar de un servicio a otro a través de la red, lo más probable es que esto sea un gran problema. Sin agregar esa lógica, toda la información de rastreo será sólo de "un solo nivel". Es decir, recibiremos todas las interacciones entre servicios, pero no se unirán en cadenas únicas de paso a través de la red.

Conclusión

Istio proporciona una herramienta conveniente para recopilar información de seguimiento a través de una red, pero debe comprender que para la implementación deberá adaptar su sistema y tener en cuenta las características de la implementación de Istio. Como resultado, es necesario resolver dos puntos principales: definir el protocolo a nivel de aplicación (que debe ser compatible con el proxy enviado) y configurar el reenvío de información sobre la conexión de solicitudes al servicio a partir de solicitudes del servicio (usando encabezados , en el caso del protocolo HTTP). Cuando se resuelven estos problemas, tenemos una poderosa herramienta que nos permite recopilar información de la red de forma transparente, incluso en sistemas muy heterogéneos escritos en muchos lenguajes y marcos diferentes.

En el próximo artículo sobre Service Mesh, veremos uno de los mayores problemas con Istio: el gran consumo de RAM por cada contenedor proxy sidecar y discutiremos cómo solucionarlo.

Fuente: habr.com

Añadir un comentario