Observabilidade no AKS com Prometheus e Grafana

Observabilidade no AKS com Prometheus e Grafana

Observabilidade no AKS com Prometheus e Grafana

Monitorar não é o mesmo que observar. Implementar observabilidade no AKS é ir além de um dashboard de CPU e memória que diz que algo está lento — é dizer por quê. Este guia implementa os três pilares da observabilidade em um cluster AKS usando serviços gerenciados do Azure — sem manter seu próprio Prometheus, Grafana ou coletor de traces. Você vai coletar métricas com o Azure Managed Prometheus, centralizar logs com o Container Insights, visualizar tudo no Azure Managed Grafana, configurar alertas com regras Prometheus e, por fim, instrumentar a aplicação com OpenTelemetry exportando traces para o Application Insights. No final, você consegue partir de um alerta e chegar até a linha de código que causou o problema.

Leitura relacionada

Sumário

Os três pilares da observabilidade

Observabilidade se apoia em três sinais complementares. Cada um responde a uma pergunta diferente, e é a correlação entre eles que transforma dados em diagnóstico:

PilarPergunta que respondeServiço AzureArmazenamento
MétricasO quê e quanto? (latência, taxa de erro, saturação)Azure Managed PrometheusAzure Monitor Workspace
LogsO que aconteceu em detalhe?Container InsightsLog Analytics Workspace
TracesOnde, na jornada da requisição, quebrou?Application Insights (via OpenTelemetry)Application Insights (Log Analytics)

A abordagem deste artigo para a observabilidade no AKS é usar exclusivamente serviços gerenciados. Você não mantém pods do Prometheus, não faz upgrade do Grafana e não opera um coletor OpenTelemetry — o Azure cuida da retenção, escala e alta disponibilidade. A instrumentação compatível com Prometheus e OpenTelemetry continua sendo padrão de mercado, então não há lock-in na camada de código.

Arquitetura da observabilidade no AKS

A observabilidade no AKS começa na coleta. Quando você habilita as métricas gerenciadas no AKS, o Azure instala o add-on de métricas (pods ama-metrics) que faz o scrape dos endpoints Prometheus do cluster e envia os dados, via uma Data Collection Rule (DCR), para um Azure Monitor Workspace (AMW). O Managed Grafana consome o AMW como data source. Em paralelo, o Container Insights usa o Azure Monitor Agent (ama-logs) para enviar stdout/stderr e métricas de inventário para um Log Analytics Workspace. A aplicação, instrumentada com OpenTelemetry, exporta traces direto para o Application Insights.

            ┌─────────────── Cluster AKS ───────────────┐
            │  ama-metrics ──scrape──▶ /metrics (pods)  │
            │  ama-logs ─────tail────▶ stdout/stderr    │
            │  app + OTel SDK ──────────────────────┐   │
            └───────┬───────────────┬───────────────┼───┘
                    │ (DCR)         │ (DCR)         │ (OTLP/conn string)
                    ▼               ▼               ▼
        Azure Monitor Workspace  Log Analytics   Application Insights
          (métricas Prometheus)    (logs)          (traces)
                    │               │               │
                    └──────► Azure Managed Grafana ◀─┘
                              (dashboards unificados)

Pré-requisitos

  • Cluster AKS em execução (ver AKS Multi-Região com Failover)
  • Azure CLI ≥ 2.60 com a extensão do AKS (az extension add --name aks-preview se necessário)
  • Provider Microsoft.Monitor e Microsoft.Dashboard registrados na subscription
  • Permissão de Contributor no resource group e Monitoring Data Reader no AMW para o Grafana
  • kubectl e helm configurados para o cluster
Segurança: Os comandos usam variáveis de ambiente para IDs de recursos e connection strings. Nunca coloque a Connection String do Application Insights ou IDs de subscription diretamente no código-fonte ou em manifests versionados. Use um arquivo .env local (não versionado), Kubernetes Secrets ou o Azure Key Vault.

Passo 1 — Habilitar Managed Prometheus e Managed Grafana

O primeiro pilar da observabilidade no AKS são as métricas. Primeiro criamos o Azure Monitor Workspace (destino das métricas Prometheus) e a instância do Managed Grafana. Em seguida, um único az aks update conecta o cluster aos dois — o comando cria a DCR, instala o add-on ama-metrics e já registra o AMW como data source no Grafana:

# Variáveis do ambiente
RG="rg-blog-castilho-workload-eastus"
LOCATION="eastus"
AKS="aks-blog-castilho-eastus"

# 1. Azure Monitor Workspace — armazena métricas Prometheus
AMW_ID=$(az monitor account create \
  --name "amw-blog-castilho" \
  --resource-group "$RG" \
  --location "$LOCATION" \
  --query id -o tsv)

# 2. Azure Managed Grafana
GRAFANA_ID=$(az grafana create \
  --name "graf-blog-castilho" \
  --resource-group "$RG" \
  --location "$LOCATION" \
  --query id -o tsv)

# 3. Conectar o AKS ao Prometheus gerenciado + Grafana (uma linha)
az aks update \
  --name "$AKS" \
  --resource-group "$RG" \
  --enable-azure-monitor-metrics \
  --azure-monitor-workspace-resource-id "$AMW_ID" \
  --grafana-resource-id "$GRAFANA_ID"

Após alguns minutos, valide que os pods de coleta subiram no namespace kube-system. Se estiverem Running, o scrape já está ativo:

kubectl get pods -n kube-system -l dsName=ama-metrics
# ama-metrics-xxxxxxxxxx-xxxxx        2/2     Running   0     3m
# ama-metrics-node-xxxxx (DaemonSet)  1/1     Running   0     3m

Passo 2 — Coletar logs com o Container Insights

As métricas dizem que a taxa de erro subiu; os logs dizem qual exceção foi lançada. O Container Insights envia stdout/stderr dos contêineres para um Log Analytics Workspace. Se você já usa o Log Analytics do artigo de monitoramento de DR, reaproveite o mesmo workspace:

# Reaproveitar ou criar o Log Analytics Workspace
LAW_ID=$(az monitor log-analytics workspace create \
  --resource-group "$RG" \
  --workspace-name "law-blog-castilho" \
  --location "$LOCATION" \
  --query id -o tsv)

# Habilitar Container Insights no cluster
az aks enable-addons \
  --name "$AKS" \
  --resource-group "$RG" \
  --addons monitoring \
  --workspace-resource-id "$LAW_ID"

Para controlar custo, o Container Insights permite ajustar quais namespaces são coletados via ConfigMap. Em produção, colete stdout apenas dos namespaces de aplicação e exclua namespaces ruidosos como kube-system para logs (mantendo as métricas de inventário):

[log_collection_settings.stdout]
  enabled = true
  exclude_namespaces = ["kube-system", "gatekeeper-system"]

[log_collection_settings.stderr]
  enabled = true
  exclude_namespaces = ["kube-system"]

Com os logs no Log Analytics, você consulta via KQL. Exemplo — contar erros por pod na última hora:

ContainerLogV2
| where TimeGenerated > ago(1h)
| where LogLevel == "error" or LogMessage has "Exception"
| summarize Erros = count() by PodName
| order by Erros desc

Passo 3 — Coletar métricas customizadas (PodMonitor)

Por padrão, o add-on coleta as métricas de infraestrutura (kubelet, cAdvisor, node exporter). Para coletar métricas da sua aplicação — expostas em um endpoint /metrics no formato Prometheus — crie um PodMonitor no namespace especial kube-system usando a CRD do add-on:

apiVersion: azmonitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: pm-checkout-app
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: checkout
  namespaceSelector:
    matchNames:
      - loja
  podMetricsEndpoints:
    - port: metrics
      interval: 30s
      path: /metrics

Aplique com kubectl apply -f podmonitor.yaml. Em ~1 minuto as métricas da aplicação (ex.: http_requests_total, http_request_duration_seconds) estarão disponíveis no AMW e consultáveis no Grafana via PromQL.

Passo 4 — Dashboards no Managed Grafana

Os dashboards são a face visível da observabilidade no AKS. O Managed Grafana já vem com dashboards prontos de Kubernetes/AKS quando conectado ao AMW. Acesse o endpoint e, em Dashboards → Kubernetes, você encontra visões de cluster, nós, namespaces e workloads sem configuração adicional. Para métricas da aplicação, monte um painel com os quatro golden signals. Exemplo de PromQL para os principais:

Golden SignalPromQL
Tráfego (req/s)sum(rate(http_requests_total[5m])) by (service)
Taxa de erro (%)sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
Latência (p95)histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
Saturação (CPU)sum(rate(container_cpu_usage_seconds_total{namespace="loja"}[5m])) by (pod)

Recupere a URL do Grafana e valide o data source:

az grafana show \
  --name "graf-blog-castilho" \
  --resource-group "$RG" \
  --query properties.endpoint -o tsv

# Saída (o sufixo aleatório é gerado pelo Azure):
# https://graf-blog-castilho-a1b2c3d4e5.eus.grafana.azure.com

Do lado das métricas Prometheus, o Azure Monitor Workspace expõe um endpoint de query PromQL no formato https://<amw>-<hash>.<regiao>.prometheus.monitor.azure.com — é ele que o Grafana consome como data source. Você não precisa configurá-lo manualmente quando usa o --grafana-resource-id no Passo 1: o vínculo do data source já é criado automaticamente.

Passo 5 — Alertas com regras Prometheus

Dashboards são reativos — alguém precisa estar olhando. Alertas são proativos. No Azure Managed Prometheus, os alertas são definidos como Prometheus Rule Groups (recurso Microsoft.AlertsManagement/prometheusRuleGroups), avaliados no lado do AMW. O exemplo abaixo dispara quando a taxa de erro 5xx passa de 5% por 10 minutos:

az resource create \
  --resource-group "$RG" \
  --namespace "Microsoft.AlertsManagement" \
  --resource-type "prometheusRuleGroups" \
  --name "prg-checkout-slo" \
  --location "$LOCATION" \
  --properties '{
    "scopes": ["'"$AMW_ID"'"],
    "clusterName": "'"$AKS"'",
    "interval": "PT1M",
    "rules": [{
      "alert": "HighErrorRate",
      "expression": "sum(rate(http_requests_total{status=~\"5..\"}[5m])) / sum(rate(http_requests_total[5m])) > 0.05",
      "for": "PT10M",
      "labels": { "severity": "critical" },
      "annotations": { "description": "Taxa de erro 5xx acima de 5% no checkout" }
    }]
  }'

Associe o rule group a um Action Group (e-mail, Teams, webhook, SMS) para o roteamento da notificação. A Microsoft também publica um conjunto de recommended alerts para AKS que você pode habilitar com poucos cliques no portal — comece por eles e adicione regras de negócio como a de SLO acima.

Passo 6 — Traces com OpenTelemetry e Application Insights

Métricas e logs mostram que a requisição falhou; o trace distribuído mostra onde, ao longo de todos os serviços que ela atravessou. A forma recomendada de instrumentar hoje é o OpenTelemetry, exportando para o Application Insights. A Azure Monitor OpenTelemetry Distro cuida da configuração do exporter — você só fornece a Connection String.

A Connection String fica em um Kubernetes Secret e é injetada como variável de ambiente no deployment — nunca no código:

# Criar o Application Insights e obter a Connection String
APPI_CONN=$(az monitor app-insights component create \
  --app "appi-blog-castilho" \
  --resource-group "$RG" \
  --location "$LOCATION" \
  --workspace "$LAW_ID" \
  --query connectionString -o tsv)

# Guardar como Secret no cluster
kubectl create secret generic appinsights \
  --namespace loja \
  --from-literal=connection-string="$APPI_CONN"

Na aplicação (exemplo em Python), a instrumentação é praticamente uma linha. A Distro habilita traces, métricas e logs correlacionados automaticamente para bibliotecas comuns (Flask, requests, etc.):

from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace
import os

# Lê a connection string do env (injetada pelo Secret)
configure_azure_monitor(
    connection_string=os.environ["APPLICATIONINSIGHTS_CONNECTION_STRING"],
)

tracer = trace.get_tracer(__name__)

# Spans customizados para trechos críticos do seu código
with tracer.start_as_current_span("processar-pagamento"):
    cobranca = gateway.charge(pedido)
    with tracer.start_as_current_span("baixar-estoque"):
        estoque.decrementar(pedido.itens)

No manifesto do deployment, injete o Secret como a variável esperada pela Distro:

        env:
          - name: APPLICATIONINSIGHTS_CONNECTION_STRING
            valueFrom:
              secretKeyRef:
                name: appinsights
                key: connection-string

Em Application Insights → Application Map, o Azure desenha automaticamente o grafo de dependências entre serviços com latência e taxa de falha em cada aresta. Em Transaction search, você abre um trace individual e vê a cascata de spans — identificando o serviço e a chamada exata que dominou a latência.

Correlacionando métricas, logs e traces

O valor real aparece quando os três pilares se conectam num único fluxo de investigação. Um incidente típico percorre este caminho:

EtapaSinalFerramentaPergunta respondida
1. Alerta disparaMétricaPrometheus rule → Action GroupTaxa de erro do checkout passou de 5%
2. Abrir o dashboardMétricaManaged GrafanaComeçou às 14h03, só no serviço de pagamento
3. Inspecionar a jornadaTraceApplication Insights (Application Map)Latência concentrada na chamada ao gateway externo
4. Ver o detalheLogLog Analytics (KQL)Exceção de timeout no pod checkout-7d9

É aqui que a observabilidade no AKS prova seu valor: como Container Insights, Application Insights e o AMW podem compartilhar o mesmo Log Analytics Workspace, é possível cruzar dados com KQL entre tabelas — por exemplo, unir ContainerLogV2 (logs) com AppDependencies (traces) pelo nome do pod, tudo num único painel do Grafana ou do Azure Monitor.

Boas práticas de custo

Manter a observabilidade no AKS sustentável a longo prazo passa por controlar o custo de ingestão. Alguns pontos práticos:

  • Ingestão de logs é o maior custo. Exclua namespaces ruidosos do stdout no ConfigMap do Container Insights e evite logar payloads inteiros.
  • Amostragem de traces. Em alto volume, ative sampling na Distro do OpenTelemetry (ex.: 5–10%) — a amostragem preserva a estatística sem armazenar cada requisição.
  • Métricas Prometheus são baratas por natureza, mas cuidado com alta cardinalidade: evite labels com valores ilimitados (user_id, request_id) que multiplicam as séries temporais.
  • Basic Logs / retenção. Para tabelas de log verboso, use o tier Basic Logs e ajuste a retenção do Log Analytics para o mínimo exigido por compliance.
  • Commitment tiers. Acima de ~100 GB/dia de ingestão, os tiers de compromisso do Log Analytics reduzem o custo por GB significativamente.

Troubleshooting

ProblemaCausaSolução
Nenhuma métrica no GrafanaO add-on de métricas não subiu ou o data source não foi vinculadoVerifique kubectl get pods -n kube-system -l dsName=ama-metrics. Reexecute o az aks update com --azure-monitor-workspace-resource-id e --grafana-resource-id
PodMonitor não coleta métricas da appCRD criada fora do namespace kube-system ou label/porta incorretosO PodMonitor do add-on deve ficar em kube-system. Confirme que o port bate com o nome da porta no pod e que o app expõe /metrics
Grafana retorna 403 no data sourceFalta a role Monitoring Data Reader no AMW para a identidade do GrafanaAtribua Monitoring Data Reader à managed identity do Managed Grafana no escopo do Azure Monitor Workspace
Traces não aparecem no Application InsightsConnection String ausente ou incorreta no podConfirme a env APPLICATIONINSIGHTS_CONNECTION_STRING via kubectl exec ... env. Verifique egress do cluster para *.applicationinsights.azure.com (regras do Azure Firewall — ver Art. de Firewall)
Logs não chegam ao Log AnalyticsAdd-on monitoring desabilitado ou workspace erradoaz aks show --query addonProfiles.omsagent. Reabilite com az aks enable-addons --addons monitoring --workspace-resource-id
Custo de ingestão explodiustdout de todos os namespaces + logs de debug em produçãoAjuste o ConfigMap do Container Insights excluindo namespaces e desative log de debug. Avalie Basic Logs para tabelas verbosas

Próximos passos

Com os três pilares no ar, a observabilidade no AKS deixou de ser uma caixa-preta: você tem métricas de golden signals no Grafana, logs consultáveis via KQL, traces distribuídos no Application Insights e alertas proativos ligados a Action Groups. O passo natural é transformar isso em SLOs — definir objetivos de disponibilidade e latência, criar error budgets e alertar por burn rate em vez de thresholds fixos. Depois, feche o ciclo conectando essa observabilidade à validação de resiliência: injetar falhas controladas e confirmar que os alertas e dashboards realmente detectam o problema antes dos usuários.

Referências oficiais

Interessado em saber mais sobre artigos relacionados ao Microsoft Azure CLIQUE AQUI

🚀 Vamos nos conectar?

Não perca nenhuma oportunidade! Cadastre-se nas minhas redes e no canal do YouTube para receber conteúdos de TI, Cloud, Azure, Kubernetes e DevOps em primeira mão.

Dica: No Facebook, todos os artigos do blog são publicados automaticamente. Vale a pena curtir!


💬 Dúvidas ou Problemas?

Com o intuito de ajudar a comunidade, caso você tenha dúvidas ou encontre problemas na execução dos comandos deste artigo, deixe um comentário abaixo. Responderei o mais breve possível!

Muito obrigado pela visita e até o próximo post!

Jefferson Castilho Especialista em Cloud & DevOps.

Este guia técnico é exclusivo do Blog do Castilho. Explore mais conteúdos sobre Cloud e DevOps.

 

Deixe uma resposta

Rolar para cima

Descubra mais sobre Blog do Castilho - Tecnologia | FinOps | DevOps | Cloud

Assine agora mesmo para continuar lendo e ter acesso ao arquivo completo.

Continuar lendo