¿Por qué OpenTelemetry? ¿Por qué darse el trabajo de entrar en otro ámbito más en el universo de la observabilidad? ¿Además, qué es OpenTelemetry?
Veamos cómo lo define la comunidad: OpenTelemetry es un framework y un conjunto de herramientas de observabilidad diseñadas para crear y administrar los datos de telemetría como las trazas, las métricas y los logs. Lo esencial es que OpenTelemetry es independiente del proveedor y de las herramientas. Esto quiere decir que se puede utilizar con una gran variedad de backends de observabilidad, lo que incluye herramientas de código abierto como Jaeger y Prometheus, además de productos comerciales. OpenTelemetry es un proyecto de la Cloud Native Computing Foundation (CNCF).
Suena interesante. Y si lees sobre la misión, la visión y los valores de la comunidad, parece aún más interesante. Pero igual, probablemente hay un montón de proyectos de sandbox de la CNCF que tienen objetivos muy similares. ¿Qué hace que OpenTelemetry (también conocido como OTel) sea tan especial?
Échale un vistazo a cómo este proyecto ha evolucionado con el tiempo y qué compañías están contribuyendo activamente; puedes ver cómo está creciendo y lo que será capaz de hacer en los próximos años.
Así que la pregunta real es: ¿por qué no unirse ahora?
Comprender Kubernetes
El propósito de este blog no es hablar de lo que la mayoría de nosotros ya sabemos sobre Kubernetes, pero un poco de contexto podría ser útil.
Se supone que Kubernetes es una plataforma con un alto grado de disponibilidad. Para ello, fue diseñado para transferir varias responsabilidades a varios componentes escalables. Echemos un vistazo rápido al resumen de los documentos oficiales:
Hay muchas variables que deben funcionar correctamente para que tus flujos de trabajo puedan ejecutarse sin problemas. Afortunadamente, estos componentes muestran su información de rendimiento de manera detallada para que puedas tener una mejor perspectiva de lo que está sucediendo en el clúster. Aún mejor, todos utilizan un lenguaje común: Prometheus.
Recopilar métricas en todo el clúster
Puesto que Kubernetes nos habla en Prometheus, ¿por qué no responder de la misma manera? Aunque parezca sencillo, realmente no lo es.
Para comenzar, Prometheus funciona con un mecanismo pull, lo que quiere decir que tú eres responsable de definir los extremos que Prometheus necesita para buscar y extraer las métricas que expone. Eso es todo un desafío si se tiene en cuenta que Kubernetes es por naturaleza extremadamente dinámico en lo que se refiere a crear y eliminar contenedores rápidamente.
Por suerte, Prometheus ha incorporado la detección de servicios para Kubernetes para la cual puedes configurar diferentes trabajos de extracción (scrape) para que tus instancias de Prometheus puedan determinar qué se debe verificar de antemano.
¿Y la escalabilidad?
A medida que nuestro clúster crece cada vez más, una instancia de Prometheus podría necesitar una gran cantidad de recursos y por lo tanto una máquina muy grande para poder ejecutarse. Preferiríamos tener varias instancias más pequeñas que se ejecutan en máquinas más pequeñas. Sin embargo, puesto que estamos extrayendo métricas, tener varias instancias quiere decir que extraeríamos los mismos extremos varias veces.
Dicho esto, ahora es un buen momento para introducir el recolector de OpenTelemetry. Resumido brevemente, el recolector OTel consta de tres componentes principales: receptores, procesadores y exportadores. Si utilizas diferentes opciones de estos tres componentes, podrás crear varias canalizaciones para manejar los datos de telemetría y enviarlos a los distintos backends según tus necesidades.
¿Cómo podemos aprovechar el recolector OTel para que hable con Kubernetes?
Viene con un receptor Prometheus, que se puede configurar de la misma manera que un servidor Prometheus, es decir, podemos utilizar las mismas definiciones de los trabajos de extracción. Lo bueno es que no es necesario almacenar las métricas obtenidas localmente (aparte de la memoria en sí). Puedes pensar en ello como Prometheus en modo de agente.
Hasta aquí, vamos bien. Pero el problema del sharding (particionamiento) sigue estando presente: todavía no podemos escalar nuestros recolectores OTel horizontalmente. Para eso es que sirve el Target Allocator. Este está ubicado al frente de los recolectores OTel con información de estado y manipula sus configuraciones de Prometheus, en función de los objetivos que se deben extraer, distribuyéndolos en todas las instancias. Cada extremo es extraído por una instancia del recolector OTel a la vez. Para obtener más información sobre cómo funciona la escalabilidad del extractor, consulta la documentación oficial.
Hemos hablado mucho sobre cómo funciona Prometheus, cómo aprovechar los recolectores OTel y cómo escalarlos, pero no hemos dicho nada acerca de lo que en realidad tenemos que recolectar. Veamos qué ofrece Kubernetes.
Primero, cada componente del panel de control aparece en sus puertos dedicados y proporciona sus métricas en el extremo /metrics
. Por ejemplo, veamos la configuración de un trabajo de extracción del kube-api-server:
scrape_configs:
- job_name: 'kubernetes-apiservers'
scrape_interval: 60s
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
Segundo, necesitamos visibilidad en las máquinas (nodos). Un producto popular y maduro para la recopilación y exposición de las métricas de nodos es Node Exporter. Podemos ejecutarlo como un daemonset en todos los nodos (Linux) y extraer lo que recopila de la máquina subyacente como sigue:
scrape_configs:
- job_name: 'kubernetes-node-exporter'
scrape_interval: 60s
honor_labels: true
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape_slow]
action: drop
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: (.+?)(?::\d+)?;(\d+)
replacement: $$1:$$2
- source_labels: [__meta_kubernetes_service_name]
action: keep
regex: <NODE_EXPORTER_SERVICE_NAME>
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: service
- source_labels: [__meta_kubernetes_pod_node_name]
action: replace
target_label: node
Ahora que ya tenemos las métricas a nivel de máquina, podemos pasar a un nivel superior y monitorear nuestros contenedores. Las métricas de contenedores son recopiladas por la herramienta cAdvisor (Container Advisor), que se ejecuta en cada nodo. Podemos extraerlas como sigue:
scrape_configs:
- job_name: 'kubernetes-nodes-cadvisor'
scrape_interval: 60s
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
- role: node
relabel_configs:
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/$$1/proxy/metrics/cadvisor
Por último, pero no menos importante, ahora tenemos que conocer el estado de los componentes de nuestro clúster. La herramienta kube-state-metrics solicita esa información a los distintos extremos y genera métricas que podemos extraer una vez más con el receptor Prometheus de nuestros recolectores OTel:
scrape_configs:
- job_name: 'kubernetes-kube-state-metrics'
scrape_interval: 60s
honor_labels: true
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape_slow]
action: drop
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: (.+?)(?::\d+)?;(\d+)
replacement: $$1:$$2
- source_labels: [__meta_kubernetes_service_name]
action: keep
regex: <KUBE_STATE_METRICS_SERVICE_NAME>
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: service
- source_labels: [__meta_kubernetes_pod_node_name]
action: replace
target_label: node
En este momento, no es necesario decir que simplemente podemos crear un trabajo de extracción dedicado a cada componente individual que deseamos monitorear.
¿Qué más podemos obtener del clúster?
Además de las métricas que hemos recopilado exitosamente con el receptor Prometheus, también podemos recopilar eventos y logs de nuestros clústeres. (Nota: no hablaremos de las trazas en este blog.)
Comencemos con los eventos. Kubernetes gatilla eventos cada vez que se produce una creación, eliminación o mutación en el clúster. Esos eventos se pueden recuperar haciendo una consulta a kube-api-server. Afortunadamente, el recolector OTel cuenta con un receptor para eso: el receptor k8sevents. (Nota: en la actualidad se está hablando sobre si conviene convertir este receptor en obsoleto y usar el receptor k8sobject en el futuro.)
Puedes ejecutar una sola instancia del recolector para obtener los eventos de Kubernetes y enviarlos a New Relic como logs. Atención: varias instancias del receptor k8sevent obtendrán los mismos eventos y los enviarán a New Relic.
¿Y los logs? El recolector OTel incluye un receptor filelog, que puedes ejecutar como un daemonset y en el que puedes montar el directorio de logs del nodo. Puedes utilizar distintas expresiones regulares (regex) para recopilar, analizar, filtrar y enriquecer los logs de cualquier componente en tu clúster.
Desplegar recolectores OTel y monitorear con New Relic
Sabemos dónde se encuentran los datos de telemetría que se necesitan y cómo recopilarlos. Ahora tenemos que:
- Crear una estrategia para desplegar nuestras instancias del recolector OTel con las configuraciones necesarias.
- Crear dashboards y alertas adecuados con consultas extensas de New Relic Query Language (NRQL) para monitorear nuestros clústeres.
¡Buenas noticias! Hay un repositorio que contiene todo lo que hemos mencionado hasta ahora:
- Un gráfico Helm público que puedes usar para implementar tus recolectores OTel.
- Un despliegue Terraform que puedes utilizar para arrancar el monitoreo prediseñado en tu cuenta de New Relic.
Si deseas más información, échale un vistazo a los siguientes recursos:
- Lee esta documentación para comprender por qué necesitamos varios tipos (daemonset, despliegue, statefulset, singleton) de recolectores.
- Consulta esta documentación si quieres desplegar la solución de monitoreo en tu clúster.
- Averigua cómo consultar correctamente y descifrar los datos recopilados de Prometheus en esta documentación.
Consulta esta documentación si deseas crear dashboards y alertas en tu cuenta de New Relic.
Próximos pasos
Este respositorio fue diseñado como un trabajo colectivo público. Descubre todo lo que te ofrece. No dudes en crear tickets de problemas, solicitar nuevas funciones y, lo más importante, contribuir.
Las opiniones expresadas en este blog son las del autor y no reflejan necesariamente las opiniones de New Relic. Todas las soluciones ofrecidas por el autor son específicas del entorno y no forman parte de las soluciones comerciales o el soporte ofrecido por New Relic. Únase a nosotros exclusivamente en Explorers Hub ( discus.newrelic.com ) para preguntas y asistencia relacionada con esta publicación de blog. Este blog puede contener enlaces a contenido de sitios de terceros. Al proporcionar dichos enlaces, New Relic no adopta, garantiza, aprueba ni respalda la información, las vistas o los productos disponibles en dichos sitios.