DEV Community

Cover image for Auto-Instrumentação com OpenTelemetry no EKS [Lab Session]

Auto-Instrumentação com OpenTelemetry no EKS [Lab Session]

OpenTelemetry is a collection of APIs, SDKs, and tools. Use it to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) to help you analyze your software’s performance and behavior.

Source: https://opentelemetry.io/

Otel Diagram

Image description

Source: https://opentelemetry.io/docs/


Cenários para auto-instrumentação (Zero-code Instrumentation)

Alguns cenários podem nos levar a recorrer à instrumentação automática de aplicações. São eles:

  • Não ter acesso ao código fonte;
  • Falta de sponsors para um refatoramento, por não ser viável ao negócio;
  • Não ser o "dono" da aplicação;
  • A aplicação já executada há tempos, ninguém tem mais o contexto e o desenvolvimento foi descontinuado.

Mesmo se você se encontrar em um dos motivadores acima (ou mais de um), ainda pode haver a necessidade de observar essas aplicações.
É importante lembrar que essa abordagem de auto-instrumentação traz algumas ressalvas, como, por exemplo, o excesso de telemetria gerado pela aplicação instrumentada.
Quando temos um cenário de uma aplicação greenfield (do zero), será mais interessante já pensar na instrumentação como parte do desenvolvimento, sendo chamada de instrumentação manual e não auto-instrumentação.

Arquitetura do Lab

Nesse lab, vamos explorar a auto-instrumentação com OpenTelemetry Operator para Kubernetes.

Image description

Repositórios:

O provisionamento da infraestrutura e seus componentes, como: Cluster EKS, Istio ingress, karpenter e também a stack de observabilidade que contempla o Grafana Tempo, pode ser feito seguindo esse outro Lab - o11y: OpenTelemetry, Prometheus, Loki e Tempo no EKS [Lab Session]. Portanto, partiremos do ponto em que o EKS já está configurado e com o Grafana Tempo em execução.


Deploy do OpenTelemetry Operator

Componentes já em execução no cluster:

  • Kube-prometheus-stack
  • Promtail
  • Grafana Loki (distributed)
  • Grafana Tempo (distributed)

O que vamos usar aqui é o Grafana Tempo e o Grafana que faz parte da stack do Prometheus. No Grafana, já há um datasource do Tempo configurado.

Image description

Deploy do operator usando Helm:

git clone https://github.com/paulofponciano/o11y-lab-prom-otel-loki-tempo.git
cd o11y-lab-prom-otel-loki-tempo/opentelemetry/auto-instrumentation/operator
Enter fullscreen mode Exit fullscreen mode
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
Enter fullscreen mode Exit fullscreen mode
helm install opentelemetry-operator open-telemetry/opentelemetry-operator \
--namespace opentelemetry-operator-system \
--create-namespace \
--set "manager.collectorImage.repository=otel/opentelemetry-collector-k8s" \
--set admissionWebhooks.certManager.enabled=false \
--set admissionWebhooks.autoGenerateCert.enabled=true
Enter fullscreen mode Exit fullscreen mode

Image description

Logs iniciais do OpenTelemetry Operator:

Image description

Deploy Otel collector

Podemos agora fazer o deploy de um custom resource que é o OpenTelemetryCollector. Basicamente, ele receberá os traces (receivers) e os enviará (exporters) para o Grafana Tempo, onde poderão ser visualizados.

kubectl apply -f otel-collector.yaml
Enter fullscreen mode Exit fullscreen mode

Manifesto do collector:

apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
  name: otelcol
  namespace: o11y
spec:
  config:
    receivers:
      otlp:
        protocols:
          grpc:
            endpoint: 0.0.0.0:4317
          http:
            endpoint: 0.0.0.0:4318
    processors:
      memory_limiter:
        check_interval: 1s
        limit_percentage: 75
        spike_limit_percentage: 15
      batch:
        send_batch_size: 10000
        timeout: 10s

    exporters:
      debug: {}
      otlp:
        endpoint: tempo-distributor.o11y.svc.cluster.local:4317
        tls:
          insecure: true

    service:
      pipelines:
        traces:
          receivers: [otlp]
          processors: [memory_limiter, batch]
          exporters: [debug, otlp]
Enter fullscreen mode Exit fullscreen mode

Logs iniciais do otel collector:

Image description

Exemplo Java e Otel Instrumentation

Mais um custom resource que faremos o deploy é o Instrumentation. Dentre outras configurações, nele definiremos quem será o otel collector, no caso, será o que acabamos de criar.

kubectl apply -f java-auto-instrumentation.yaml
Enter fullscreen mode Exit fullscreen mode

Manifesto de instrumentation:

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: java-auto-instrumentation
  namespace: o11y
spec:
  exporter:
    endpoint: http://otelcol-collector.o11y.svc.cluster.local:4318
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: "1"
Enter fullscreen mode Exit fullscreen mode
kubectl get instrumentation -n o11y
Enter fullscreen mode Exit fullscreen mode

Image description

Agora podemos fazer o deploy de uma aplicação de exemplo em java (vertx-create-span):

kubectl create ns sample-api-java
kubectl apply -f java-service-with-auto-instrumentation.yaml
Enter fullscreen mode Exit fullscreen mode

Importante notar a annotation que devemos informar no manifesto, onde é definida a instrumentation que usaremos:

# Part of the complete manifest:
template:
  metadata:
    labels:
      app: operator-e2e-tests
    annotations:
      instrumentation.opentelemetry.io/inject-java: "o11y/java-auto-instrumentation"
# ...
Enter fullscreen mode Exit fullscreen mode

Image description

Executando kubectl describe pod no pod da aplicação que acabou de subir, vemos que foi injetado um initContainer para auto-instrumentação:

Image description

Dentro do container:

Image description

Simulando tráfego de entrada na aplicação java:

Image description

Logs da aplicação e do otel collector:

Image description

No Grafana, visualizamos os traces recebidos através do datasource plugin do Grafana Tempo:

Image description

Image description

Image description

Exemplo Python e Otel Instrumentation

Faremos o mesmo processo de deploy, mas agora para uma app demo que simula a comunicação de microsserviços. Primeiro o apply do manifesto de instrumentation - Embora fosse possível reutilizar a Instrumentation já criada, optamos por criar uma específica para cada caso:

kubectl apply -f python-auto-instrumentation.yaml
Enter fullscreen mode Exit fullscreen mode
kubectl get instrumentation -n o11y
Enter fullscreen mode Exit fullscreen mode

Image description

Deploy app demo python:

kubectl create ns sample-api-python
kubectl apply -f python-service-with-auto-instrumentation.yaml
Enter fullscreen mode Exit fullscreen mode

Annotation referenciando a Instrumentation:

# Part of the complete manifest:
template:
    metadata:
      annotations:
        instrumentation.opentelemetry.io/inject-python: "o11y/python-auto-instrumentation"
      labels:
        app: microservice-1
# ...
Enter fullscreen mode Exit fullscreen mode

Image description

Com kubectl describe pod novamente vemos o initContainer da auto-instrumentação, agora para python:

Image description

Image description

Gerando tráfego de entrada:

Image description

Image description

No Grafana:

Image description

Image description

Podemos simular uma latência maior entre as chamadas, aumentando o 'RESPONSE_TIME' no manifesto de deploy, e reaplicar:

# Part of the complete manifest:
spec:
  containers:
  - name: app
    image: paulofponciano/demo-ms-intercomunicacao:latest
    ports:
    - containerPort: 5000
    env:
    - name: TITLE
      value: "Microservice 2"
    - name: RESPONSE_TIME
      value: "3500" # bottleneck
    - name: EXTERNAL_CALL_URL
      value: "http://microservice-3.sample-api-python.svc.cluster.local:5000"
    - name: EXTERNAL_CALL_METHOD
    value: "GET"
# ...
Enter fullscreen mode Exit fullscreen mode

Image description

Comparando com o trace anterior (antes da alteração no RESPONSE_TIME), o ponto de gargalo fica visível:

Image description


Referências:

Dose ao vivo: aula prática de OpenTelemetry Operator
OpenTelemetry - Injecting Auto-instrumentation
OpenTelemetry Operator for Kubernetes


Keep shipping! 🐳

Top comments (0)