Elven Observability: Operator collector (instrumentação automática)

Para que possamos usar o auto-instrumentação devemos instalar o operator do collector

  • Dependencies

cert-manager

  • Instale o operator
				
					kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
				
			
  • Caso vá instrumentar aplicações Golang:
				
					kubectl -n opentelemetry-operator-system patch deployment opentelemetry-operator-controller-manager \
--type=json \
-p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--enable-go-instrumentation=true"}]'
				
			

Instale o collector

É uma prática recomendada enviar telemetria de contêineres para um OpenTelemetry Collector em vez de diretamente para um backend. O Collector ajuda a simplificar o gerenciamento de segredos, desacopla problemas de exportação de dados (como a necessidade de fazer novas tentativas) de seus aplicativos e permite que você adicione dados adicionais à sua telemetria, como com o componente k8sattributesprocessor . Se você optar por não usar um Collector, pode pular para a próxima seção.

https://opentelemetry.io/docs/kubernetes/operator/automatic/

Exemplo de configuracao

				
					apiVersion: opentelemetry.io/v1beta1
kind: OpenTelemetryCollector
metadata:
  name: otel
spec:
  config: 
    receivers:
      otlp:
        protocols:
          grpc:
          http:
    processors:
      memory_limiter:
        check_interval: 1s
        limit_percentage: 75
        spike_limit_percentage: 15
      batch:
        send_batch_size: 10000
        timeout: 10s
    exporters:
      otlp:
        endpoint: "tempo-distributor.domain.io:443"
        tls:
          insecure: false
          insecure_skip_verify: true
      prometheusremotewrite:
        endpoint: https://mimir-distributor.domain.io/api/v1/push
        headers:
          X-Scope-OrgID: <TENANT>          
    service:
      pipelines:
        metrics:
          receivers: [otlp] 
          processors: [batch]
          exporters: [prometheusremotewrite]
        traces:
          receivers: [otlp]
          processors: []
          exporters: [otlp]
				
			
  • Aplique o collector
				
					kubectl apply -k otel-collector-operator/
				
			

OpenTelemetry instrumentation

Para poder gerenciar a instrumentação automática, o Operator precisa ser configurado para saber quais pods instrumentar e qual instrumentação automática usar para esses pods. Isso é feito por meio do Instrumentation CRD.

Ex. Java

				
					apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: instrumentation-sample
spec:
  propagators:
    - tracecontext
    - baggage
    - b3
  sampler:
    type: parentbased_traceidratio
    argument: "1"
  env:
    - name: OTEL_EXPORTER_OTLP_ENDPOINT
      value: otel-collector.monitoring:4318
  java:    
    env:
      - name: OTEL_EXPORTER_OTLP_ENDPOINT
        value: http://otel-collector.monitoring:4317 
				
			

Ex. DOTNET

				
					apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: instrumentation-sample
spec:
  propagators:
    - tracecontext
    - baggage
    - b3
  sampler:
    type: parentbased_traceidratio
    argument: "1"
  env:
    - name: OTEL_EXPORTER_OTLP_ENDPOINT
      value: otel-collector.default:4318   
  dotnet:
    env:
      - name: OTEL_DOTNET_AUTO_METRICS_CONSOLE_EXPORTER_ENABLED
        value: "false"
      - name: OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED
        value: "false"
      - name: OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED
        value: "false"  
      - name: OTEL_EXPORTER_OTLP_ENDPOINT
        value: http://otel-collector.monitoring:4318
      - name: OTEL_TRACES_EXPORTER
        value: "true"
      - name: OTEL_METRICS_EXPORTER
        value: "true"
				
			

Adicionar anotações a implantações existentes

O passo final é optar por seus serviços para instrumentação automática. Isso é feito atualizando seus serviços spec.template.metadata.annotations para incluir uma anotação específica do idioma:

.NET: instrumentation.opentelemetry.io/inject-dotnet: “true”

Go: instrumentation.opentelemetry.io/inject-go: “true”

Java: instrumentation.opentelemetry.io/inject-java: “true”

Node.js: instrumentation.opentelemetry.io/inject-nodejs: “true”

Python: instrumentation.opentelemetry.io/inject-python: “true”

  • Aplicacao test usando auto-instrumentação JAVA

https://opentelemetry.io/docs/kubernetes/operator/automatic/

				
					kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: java-sample
  template:
    metadata:
      labels:
        app: java-sample
      annotations:
        instrumentation.opentelemetry.io/inject-java: "true"
    spec:
      containers:
      - name: java-sample
        image: emr001/java-app
        ports:
        - containerPort: 8080
        env:
          - name: OTEL_SERVICE_NAME
            value: "java-demo"
---
apiVersion: v1
kind: Service
metadata:
  name: java-app
spec:
  selector:
    app: java-sample
  ports:
    - port: 8080
      protocol: TCP
      targetPort: 8080
---
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: instrumentation-sample
spec:
  propagators:
    - tracecontext
    - baggage
    - b3
  sampler:
    type: parentbased_traceidratio
    argument: "1"
  env:
    - name: OTEL_EXPORTER_OTLP_ENDPOINT
      value: otel-collector.monitoring:4318
  java:    
    env:
      - name: OTEL_EXPORTER_OTLP_ENDPOINT
        value: http://otel-collector.monitoring:4317
  dotnet:
    env:
      - name: OTEL_DOTNET_AUTO_METRICS_CONSOLE_EXPORTER_ENABLED
        value: "false"
      - name: OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED
        value: "false"
      - name: OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED
        value: "false"  
      - name: OTEL_EXPORTER_OTLP_ENDPOINT
        value: http://otel-collector.monitoring:4318
      - name: OTEL_TRACES_EXPORTER
        value: "true"
      - name: OTEL_METRICS_EXPORTER
        value: "true"              
EOF 
				
			

Execute um restart no deployment para o operator inserir o agent via init-container

				
					kubectl rollout restart deployment java-sample 
				
			

Faça um port-forward na porta 8080 e use o loop abaixo para enviar traces, metricas e logs

				
					kubectl port-forward svc/java-app 8080:8080
				
			

Vamos fazer um loop para enviar várias requests

				
					while true; do curl http://localhost:8080/api/hello && echo "" && sleep 1; done
				
			

Tracing Grafana

  • Aplicacao test usando auto-instrumentação DOTNET
				
					kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dotnet-sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dotnet-sample
  template:
    metadata:
      labels:
        app: dotnet-sample
      annotations:
        instrumentation.opentelemetry.io/inject-dotnet: "true"
    spec:
      containers:
      - name: dotnet-sample
        image: emr001/dotnet8-app:v1
        ports:
        - containerPort: 8080
        env:
          - name: OTEL_SERVICE_NAME
            value: "dotnet-demo"
---
apiVersion: v1
kind: Service
metadata:
  name: dotnet-app
spec:
  selector:
    app: dotnet-sample
  ports:
    - port: 80
      protocol: TCP
      targetPort: 8080
EOF
				
			

Execute um restart no deployment para o operator inserir o agent via init-container

				
					kubectl rollout restart deployment dotnet-sample 
				
			

Faça um port-forward na porta 8080 e use o loop abaixo para enviar traces, metricas e logs

				
					kubectl port-forward svc/dotnet-app 80:80
				
			

Vamos fazer um loop para enviar varias requests

				
					while true; do curl http://localhost/weatherforecast && echo "" && sleep 1; done
				
			
				
					while true; do curl http://localhost/error && echo "" && sleep 1; done
				
			

Dashboard Grafana

Rolar para cima