Instalação da Stack de Observabilidade no Kubernetes


Sumário

  • Visão geral
  • O que a stack instala
  • Pré-requisitos
  • Antes de começar: tenant e token
  • Quick start
  • Instalação passo a passo
  • O que pode ser customizado
  • Como a instrumentação funciona
  • Métricas Prometheus de aplicação
  • Logs das aplicações
  • Validação após a instalação
  • Atualização da stack
  • Remoção da stack
  • Troubleshooting
  • Checklist final
  • Veja também

Visão geral

A stack Kubernetes da Elven segue esta divisão de responsabilidade:

Componente Responsabilidade
Prometheus métricas de infraestrutura e Kubernetes
OpenTelemetry Collector OTLP das aplicações e scrape genérico de métricas de app
OpenTelemetry Operator auto-instrumentação e inject-sdk
Grafana Alloy logs stdout/stderr para Loki
collector-fe telemetria frontend via Faro, quando esse fluxo for usado
Beyla opcional, desligado por padrão

Resumo do fluxo:

Aplicações -> OpenTelemetry Operator -> elven-otel-collector -> Tempo / Mimir
Pods stdout/stderr -> Grafana Alloy -> Loki
Infra / Kubernetes -> Prometheus -> Mimir
Frontend Faro -> collector-fe -> Loki

Pontos importantes do baseline atual:

  • o Prometheus continua responsável por métricas de infra e cluster
  • o elven-otel-collector recebe OTLP das apps e também pode fazer scrape genérico de pods anotados com prometheus.io/*
  • os logs do cluster seguem por Alloy -> Loki
  • o Instrumentation é aplicado automaticamente pela stack, mas a injeção continua sendo opt-in por annotation
  • Beyla fica preparado no template, mas não sobe no helmfile apply padrão

O que a stack instala

No fluxo padrão, o helmfile apply sobe:

  1. cert-manager
  2. kube-prometheus-stack
  3. Grafana Alloy
  4. collector-fe
  5. elven-otel-collector
  6. elven-instrumentation-operator
  7. Instrumentation nos namespaces elegíveis

Arquivos principais do template:

Arquivo Função
helmfile.yaml orquestra a instalação da stack
monitoring-namespace.yaml cria o namespace monitoring
elven-prometheus/values-prometheus.yaml Prometheus e remote write
elven-logs-collector/values-alloy.yaml logs via Alloy
elven-collector-fe/values.yaml release do collector-fe
elven-collector-fe/collector-fe-env-secret.yaml envs do collector-fe
elven-otel-collector/collector-config.yaml configuração do collector
elven-otel-operator/opentelemetry-operator.yaml manifesto do Operator
elven-otel-operator/instrumentation.yaml perfil global de instrumentação

Pré-requisitos

Você vai precisar de:

  • cluster Kubernetes funcional
  • kubectl
  • helm
  • helmfile
  • acesso ao repositório stack-observability-k8s
  • credenciais da Elven:
  • tenantId
  • apiToken

Também é importante saber:

  • quais namespaces do cluster devem ser instrumentados
  • quais workloads vão usar auto-instrumentação
  • se alguma aplicação já usa outro agente APM ou SDK legado

Se uma aplicação já tiver agente legado ativo, não habilite a auto-instrumentação da Elven em paralelo sem validar antes. Dupla instrumentação costuma gerar conflito, overhead e comportamento imprevisível.


Antes de começar: tenant e token

Para obter o tenantId e o apiToken, acesse:

Esse é o único ponto externo que o cliente precisa consultar antes do primeiro deploy da stack.

Essas credenciais alimentam automaticamente:

  • Prometheus remoteWrite
  • elven-otel-collector
  • Grafana Alloy
  • collector-fe

Ou seja: o cliente cria uma secret central e a stack reaproveita isso em todos os componentes.


Quick start

Se você quer o caminho mais rápido:

git clone https://github.com/elven-observability/stack-observability-k8s.git
cd stack-observability-k8s

kubectl apply -f monitoring-namespace.yaml

kubectl create secret generic elven-observability-credentials <br>
  -n monitoring <br>
  --from-literal=tenantId="<SEU_TENANT_ID>" <br>
  --from-literal=apiToken="<SEU_API_TOKEN>"

helmfile apply

Depois valide:

kubectl get pods -n monitoring
kubectl get instrumentations -A
kubectl logs -n monitoring deploy/elven-otel-collector --since=2m
kubectl logs -n monitoring deploy/elven-instrumentation-operator-controller-manager --since=2m

Instalação passo a passo

1. Clonar o template

HTTPS:

git clone https://github.com/elven-observability/stack-observability-k8s.git
cd stack-observability-k8s

SSH:

git clone git@github.com:elven-observability/stack-observability-k8s.git
cd stack-observability-k8s

2. Criar o namespace monitoring

kubectl apply -f monitoring-namespace.yaml

3. Criar a secret central

Busque o tenantId e o apiToken em monitoring.elven.works/setup e crie a secret:

kubectl create secret generic elven-observability-credentials <br>
  -n monitoring <br>
  --from-literal=tenantId="<SEU_TENANT_ID>" <br>
  --from-literal=apiToken="<SEU_API_TOKEN>"

4. Revisar opcionais antes do primeiro deploy

Na maioria dos ambientes, o cliente não precisa editar nada antes do primeiro helmfile apply.

Os pontos mais comuns de revisão são:

  • elven-prometheus/values-prometheus.yaml
  • elven-logs-collector/values-alloy.yaml
  • elven-collector-fe/values.yaml
  • elven-collector-fe/collector-fe-env-secret.yaml
  • elven-ebpf/values.yaml

5. Subir a stack

helmfile apply

O que esse comando faz no template atual:

  1. instala ou atualiza os releases Helm
  2. renderiza o tenantId do Prometheus direto da secret central
  3. aplica o ClusterIssuer
  4. aplica a kustomization.yaml da raiz
  5. sobe ou atualiza o elven-otel-collector
  6. sobe ou atualiza o elven-instrumentation-operator
  7. espera a CRD instrumentations.opentelemetry.io
  8. aplica o Instrumentation automaticamente nos namespaces elegíveis
  9. reinicia os componentes locais que dependem de secret/config para garantir convergência

Você não precisa aplicar o Instrumentation manualmente no fluxo padrão. O helmfile apply já faz isso na ordem correta.

6. Restringir namespaces, se necessário

Por padrão, a stack cria o objeto Instrumentation em todos os namespaces elegíveis, ignorando namespaces operacionais.

Se você quiser limitar explicitamente:

INSTRUMENTATION_TARGET_NAMESPACES="payments,backoffice,workers" helmfile apply

O que pode ser customizado

Prometheus

Arquivo:

  • elven-prometheus/values-prometheus.yaml

Uso:

  • ajuste fino de scrape de infra
  • retenção
  • política de remote write
  • filtros de cardinalidade de métricas de infraestrutura

Importante:

  • o tenantId do remoteWrite é resolvido automaticamente a partir da secret central
  • não é mais necessário editar X-Scope-OrgID manualmente no values

Logs com Alloy

Arquivo:

  • elven-logs-collector/values-alloy.yaml

Uso:

  • pipelines de logs
  • labels extras
  • comportamento de parsing

collector-fe

Arquivos:

  • elven-collector-fe/values.yaml
  • elven-collector-fe/collector-fe-env-secret.yaml

Uso:

  • customizar SECRET_KEY
  • customizar LOKI_URL
  • customizar ALLOW_ORIGINS
  • customizar JWT_ISSUER

Se o cliente não usa telemetria frontend agora, normalmente dá para deixar esse release como está e tratar depois.

Beyla

Arquivo:

  • elven-ebpf/values.yaml

Status:

  • opcional
  • desligado por padrão no helmfile.yaml

Só habilite se o cliente realmente precisar de observabilidade via eBPF.


Como a instrumentação funciona

Instalar a stack não injeta agentes em toda aplicação automaticamente. O helmfile apply cria o Instrumentation em cada namespace elegível, mas a injeção continua sendo opt-in por annotation.

Você pode anotar:

  • o namespace
  • ou o workload (Deployment, StatefulSet, DaemonSet, Job)

Exemplo por namespace

Node.js

kubectl annotate namespace commerce-demo <br>
  instrumentation.opentelemetry.io/inject-nodejs="true" <br>
  --overwrite

Python

kubectl annotate namespace commerce-demo <br>
  instrumentation.opentelemetry.io/inject-python="true" <br>
  --overwrite

Java

kubectl annotate namespace commerce-demo <br>
  instrumentation.opentelemetry.io/inject-java="true" <br>
  --overwrite

Exemplo por workload

apiVersion: apps/v1
kind: Deployment
metadata:
  name: checkout-api
spec:
  template:
    metadata:
      annotations:
        instrumentation.opentelemetry.io/inject-nodejs: "true"

Annotations suportadas

Runtime Annotation
Java instrumentation.opentelemetry.io/inject-java
Node.js instrumentation.opentelemetry.io/inject-nodejs
Python instrumentation.opentelemetry.io/inject-python
.NET instrumentation.opentelemetry.io/inject-dotnet
Go instrumentation.opentelemetry.io/inject-go
Apache HTTPD instrumentation.opentelemetry.io/inject-apache-httpd
Nginx instrumentation.opentelemetry.io/inject-nginx
SDK only instrumentation.opentelemetry.io/inject-sdk

Casos especiais

Go

Para Go auto-instrumentado, o binário-alvo precisa ser informado por workload:

metadata:
  annotations:
    instrumentation.opentelemetry.io/inject-go: "true"
    instrumentation.opentelemetry.io/otel-go-auto-target-exe: "/app/seu-binario"

Python em musl

metadata:
  annotations:
    instrumentation.opentelemetry.io/inject-python: "true"
    instrumentation.opentelemetry.io/otel-python-platform: "musl"

.NET em musl

metadata:
  annotations:
    instrumentation.opentelemetry.io/inject-dotnet: "true"
    instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-musl-x64"

Ruby e Rust

Para Ruby e Rust, use inject-sdk quando a aplicação já tiver SDK OTel embutido:

metadata:
  annotations:
    instrumentation.opentelemetry.io/inject-sdk: "true"

Métricas Prometheus de aplicação

Além de OTLP, o collector também pode fazer scrape genérico de apps anotadas com prometheus.io/*.

Use estas annotations quando a aplicação expõe endpoint Prometheus:

metadata:
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "8080"
    prometheus.io/path: "/metrics"
    prometheus.io/scheme: "http"

Esse scrape genérico continua no collector. O baseline não inclui scrapes específicos de cliente.


Logs das aplicações

Logs seguem o caminho:

stdout/stderr do pod -> Grafana Alloy -> Loki

Na prática:

  • se a aplicação escreve logs em stdout ou stderr, o Alloy já coleta
  • você não precisa configurar pipeline de logs no OpenTelemetry Collector
  • o baseline atual usa Alloy, não Promtail

Para aplicações JSON estruturadas, o Loki continua recebendo a linha completa, sem truncar apenas em message.


Validação após a instalação

Comandos principais:

kubectl get pods -n monitoring
kubectl get instrumentations -A
kubectl logs -n monitoring deploy/elven-otel-collector --since=2m
kubectl logs -n monitoring deploy/elven-instrumentation-operator-controller-manager --since=2m

O que você deve esperar:

  • pods de monitoring em Running
  • elven-otel-collector saudável
  • elven-instrumentation-operator-controller-manager saudável
  • pelo menos um Instrumentation criado nos namespaces elegíveis
  • endpoint do Instrumentation apontando para http://elven-otel-collector.monitoring.svc.cluster.local:4318

Validação do Instrumentation:

kubectl get instrumentation -n default instrumentation -o yaml

Validação rápida do collector:

kubectl logs -n monitoring deploy/elven-otel-collector --since=5m

Validação de logs:

kubectl get pods -n monitoring | grep elven-logs-collector

Atualização da stack

Quando houver atualização do template:

git pull
helmfile apply

O fluxo padrão reaplica:

  • releases Helm
  • manifests locais
  • Instrumentation

Sem necessidade de reaplicar tudo manualmente por fora.


Remoção da stack

Para desmontar a stack:

helmfile destroy

Esse fluxo remove:

  • releases Helm da stack
  • ClusterIssuer
  • manifests locais do collector e do operator
  • Instrumentation aplicado pela stack
  • secret de config do collector
  • secret de env do collector-fe

Esse fluxo não remove:

  • namespace monitoring
  • secret central elven-observability-credentials

Isso é intencional, para não apagar recursos adicionais do cliente por acidente.


Troubleshooting

helmfile apply falhou porque não encontrou tenantId ou apiToken

Confira se a secret existe:

kubectl get secret elven-observability-credentials -n monitoring

O Operator subiu, mas a aplicação não foi instrumentada

Confira:

  1. se existe Instrumentation no namespace
  2. se o namespace ou workload recebeu a annotation correta
  3. se a aplicação não já usa outro agente legado em paralelo

O namespace não recebeu Instrumentation

Se você usou INSTRUMENTATION_TARGET_NAMESPACES, confira se o namespace está na lista.

A aplicação não envia métricas Prometheus para o collector

Confira as annotations:

prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
prometheus.io/scheme: "http"

A aplicação escreve logs em arquivo e não aparece no Loki

O baseline coleta stdout e stderr. Se a aplicação escreve apenas em arquivo local dentro do container, ajuste a estratégia de logging da app.


Checklist final

  • [ ] acesso a monitoring.elven.works/setup
  • [ ] tenantId e apiToken copiados
  • [ ] namespace monitoring criado
  • [ ] secret elven-observability-credentials criada
  • [ ] helmfile apply executado com sucesso
  • [ ] pods em monitoring saudáveis
  • [ ] Instrumentation criado nos namespaces elegíveis
  • [ ] workloads anotados com inject-* quando necessário
  • [ ] apps com /metrics anotadas com prometheus.io/* quando aplicável
  • [ ] logs saindo por stdout ou stderr

Veja também