# 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:

* [monitoring.elven.works/setup](https://monitoring.elven.works/setup)

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:

```bash
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 \
  -n monitoring \
  --from-literal=tenantId="<SEU_TENANT_ID>" \
  --from-literal=apiToken="<SEU_API_TOKEN>"

helmfile apply
```

Depois valide:

```bash
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:

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

SSH:

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

#### 2. Criar o namespace `monitoring`

```bash
kubectl apply -f monitoring-namespace.yaml
```

#### 3. Criar a secret central

Busque o `tenantId` e o `apiToken` em [monitoring.elven.works/setup](https://monitoring.elven.works/setup) e crie a secret:

```bash
kubectl create secret generic elven-observability-credentials \
  -n monitoring \
  --from-literal=tenantId="<SEU_TENANT_ID>" \
  --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

```bash
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:

```bash
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`

```bash
kubectl annotate namespace commerce-demo \
  instrumentation.opentelemetry.io/inject-nodejs="true" \
  --overwrite
```

`Python`

```bash
kubectl annotate namespace commerce-demo \
  instrumentation.opentelemetry.io/inject-python="true" \
  --overwrite
```

`Java`

```bash
kubectl annotate namespace commerce-demo \
  instrumentation.opentelemetry.io/inject-java="true" \
  --overwrite
```

#### Exemplo por workload

```yaml
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:

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

**Python em musl**

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

**.NET em musl**

```yaml
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:

```yaml
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:

```yaml
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:

```bash
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`:

```bash
kubectl get instrumentation -n default instrumentation -o yaml
```

Validação rápida do collector:

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

Validação de logs:

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

***

### Atualização da stack

Quando houver atualização do template:

```bash
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:

```bash
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:

```bash
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:

```yaml
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](https://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

* Instrumentação Kubernetes com OpenTelemetry Operator
* Collector FE — Instrumentação Frontend com Grafana Faro
* [Repositório da stack Kubernetes](https://github.com/elven-observability/stack-observability-k8s)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.elven.works/elven-platform/elven-observability/integracao-e-instrumentacao/kubernetes/instalacao-da-stack-de-observabilidade-no-kubernetes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
