Docker & Kubernetes

Guia Completo de Grafana em Kubernetes: Dashboards, Alertas e Loki para Logs

16 min de leitura

Guia Completo de Grafana em Kubernetes: Dashboards, Alertas e Loki para Logs

Introdução ao Grafana em Kubernetes Grafana é uma plataforma de visualização e análise de dados amplamente utilizada em ambientes de produção. Quando integrada a um cluster Kubernetes, ela se torna uma ferramenta poderosa para monitorar a saúde e o desempenho de suas aplicações. O diferencial do Grafana em Kubernetes é sua capacidade de coletar dados de múltiplas fontes (Prometheus, Loki, InfluxDB, entre outras) e transformá-los em dashboards intuitivos e em tempo real. A abordagem que veremos aqui é prática e focada no que realmente funciona em produção. Vamos começar com a implantação do Grafana em um cluster Kubernetes usando Helm, depois construir dashboards efetivos, configurar alertas que realmente disparam quando necessário, e integrar o Loki para centralizar logs. Este é o trio essencial para observabilidade em Kubernetes. Deployment do Grafana em Kubernetes com Helm Instalação e Configuração Básica A forma mais robusta de implantar Grafana em Kubernetes é usar Helm, o gerenciador de pacotes da plataforma. Helm abstrai a complexidade

<h2>Introdução ao Grafana em Kubernetes</h2>

<p>Grafana é uma plataforma de visualização e análise de dados amplamente utilizada em ambientes de produção. Quando integrada a um cluster Kubernetes, ela se torna uma ferramenta poderosa para monitorar a saúde e o desempenho de suas aplicações. O diferencial do Grafana em Kubernetes é sua capacidade de coletar dados de múltiplas fontes (Prometheus, Loki, InfluxDB, entre outras) e transformá-los em dashboards intuitivos e em tempo real.</p>

<p>A abordagem que veremos aqui é prática e focada no que realmente funciona em produção. Vamos começar com a implantação do Grafana em um cluster Kubernetes usando Helm, depois construir dashboards efetivos, configurar alertas que realmente disparam quando necessário, e integrar o Loki para centralizar logs. Este é o trio essencial para observabilidade em Kubernetes.</p>

<h2>Deployment do Grafana em Kubernetes com Helm</h2>

<h3>Instalação e Configuração Básica</h3>

<p>A forma mais robusta de implantar Grafana em Kubernetes é usar Helm, o gerenciador de pacotes da plataforma. Helm abstrai a complexidade dos manifestos YAML e fornece valores pré-configurados que facilitam a instalação.</p>

<p>Primeiro, adicione o repositório Helm oficial do Grafana e instale-o no seu cluster:</p>

<pre><code class="language-bash"># Adicionar repositório

helm repo add grafana https://grafana.github.io/helm-charts

helm repo update

Criar namespace para isolamento

kubectl create namespace monitoring

Instalar Grafana com valores customizados

helm install grafana grafana/grafana \

--namespace monitoring \

--set adminPassword=seu_senha_aqui \

--set persistence.enabled=true \

--set persistence.size=10Gi \

--set service.type=LoadBalancer</code></pre>

<p>Este comando cria um deployment do Grafana com persistência de dados (importante em produção), define uma senha de admin segura e expõe o serviço via LoadBalancer. Se estiver em um ambiente local (minikube, kind), use <code>service.type=NodePort</code> em vez de LoadBalancer.</p>

<h3>Acessando Grafana e Primeiros Passos</h3>

<p>Após a instalação, obtenha o acesso ao Grafana:</p>

<pre><code class="language-bash"># Para NodePort (desenvolvimento local)

kubectl port-forward -n monitoring svc/grafana 3000:80

Para LoadBalancer (produção)

kubectl get svc -n monitoring grafana</code></pre>

<p>Abra seu navegador em <code>http://localhost:3000</code> ou no IP externo fornecido. Faça login com usuário <code>admin</code> e a senha que você definiu. O primeiro passo após autenticar é adicionar uma data source.</p>

<h2>Data Sources e Conexão com Prometheus e Loki</h2>

<h3>Configurando Prometheus como Data Source</h3>

<p>Antes de criar dashboards, você precisa de dados. Prometheus é o sistema padrão para coleta de métricas em Kubernetes. Vamos configurar Grafana para se conectar ao Prometheus.</p>

<p>Na interface do Grafana, vá em <strong>Configuration</strong> &gt; <strong>Data Sources</strong> &gt; <strong>Add data source</strong> e escolha Prometheus. A URL do Prometheus geralmente é <code>http://prometheus:9090</code> (se estiver no mesmo cluster). Aqui está um exemplo de manifest Kubernetes para Prometheus, caso não tenha instalado:</p>

<pre><code class="language-yaml">apiVersion: v1

kind: Service

metadata:

name: prometheus

namespace: monitoring

spec:

ports:

  • port: 9090

targetPort: 9090

selector:

app: prometheus

---

apiVersion: v1

kind: ConfigMap

metadata:

name: prometheus-config

namespace: monitoring

data:

prometheus.yml: |

global:

scrape_interval: 15s

scrape_configs:

  • job_name: &#039;kubernetes-pods&#039;

kubernetes_sd_configs:

  • role: pod

relabel_configs:

  • source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]

action: keep

regex: &#039;true&#039;

  • source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]

action: replace

target_label: __metrics_path__

regex: (.+)

  • source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]

action: replace

regex: ([^:]+)(?::\d+)?;(\d+)

replacement: $1:$2

target_label: __address__

---

apiVersion: apps/v1

kind: Deployment

metadata:

name: prometheus

namespace: monitoring

spec:

replicas: 1

selector:

matchLabels:

app: prometheus

template:

metadata:

labels:

app: prometheus

spec:

containers:

  • name: prometheus

image: prom/prometheus:latest

ports:

  • containerPort: 9090

volumeMounts:

  • name: config

mountPath: /etc/prometheus

args:

  • &#039;--config.file=/etc/prometheus/prometheus.yml&#039;

volumes:

  • name: config

configMap:

name: prometheus-config</code></pre>

<h3>Configurando Loki para Centralização de Logs</h3>

<p>Loki é um sistema de agregação de logs otimizado para Kubernetes. Diferente de Elasticsearch, Loki é mais leve e indexa apenas metadados, mantendo os logs compactados. Para adicionar Loki como data source, instale-o primeiro:</p>

<pre><code class="language-bash">helm install loki grafana/loki-stack \

--namespace monitoring \

--set loki.enabled=true \

--set promtail.enabled=true \

--set grafana.enabled=false</code></pre>

<p>Depois, no Grafana, adicione Loki como data source apontando para <code>http://loki:3100</code>. A partir daí, você consegue fazer queries em seus logs usando LogQL. Aqui está um exemplo de query prática:</p>

<pre><code class="language-logql">{namespace=&quot;production&quot;} | json | level=&quot;ERROR&quot;</code></pre>

<p>Esta query retorna todos os logs do namespace production, converte-os de JSON e filtra apenas mensagens de erro.</p>

<h2>Criando Dashboards Efetivos em Grafana</h2>

<h3>Estrutura de um Dashboard Bem Projetado</h3>

<p>Um dashboard Grafana que realmente agrega valor segue uma estrutura clara: status geral no topo, métricas críticas em destaque, e detalhes exploráveis abaixo. Evite dashboards poluídos com 50 panels — uma pessoa deve entender a saúde do sistema em 10 segundos olhando para ele.</p>

<p>Vamos criar um dashboard para monitorar aplicações em Kubernetes. No Grafana, clique em <strong>Create</strong> &gt; <strong>Dashboard</strong> e adicione um novo panel. Escolha Prometheus como data source e insira a query abaixo:</p>

<pre><code class="language-promql">sum(rate(container_cpu_usage_seconds_total[5m])) by (pod_name)</code></pre>

<p>Esta query retorna o uso de CPU agregado por pod nos últimos 5 minutos. Configure o painel como gráfico para visualizar tendências. Repita o processo para memória:</p>

<pre><code class="language-promql">sum(container_memory_usage_bytes) by (pod_name) / 1024 / 1024</code></pre>

<h3>Integrando Logs no Dashboard com Loki</h3>

<p>Uma funcionalidade poderosa do Grafana é correlacionar métricas com logs. Quando um pod tem consumo anômalo de CPU, você quer ver os logs daquele pod no mesmo dashboard. Adicione um panel de logs com:</p>

<pre><code class="language-logql">{pod_name=~&quot;$pod&quot;} | json</code></pre>

<p>Use a variável <code>$pod</code> para permitir seleção dinâmica. Para configurar variáveis, vá em <strong>Dashboard Settings</strong> &gt; <strong>Variables</strong> e crie uma nova variável com query Prometheus:</p>

<pre><code class="language-promql">label_values(container_cpu_usage_seconds_total, pod_name)</code></pre>

<p>Agora, ao selecionar um pod no dropdown, tanto as métricas quanto os logs se atualizam automaticamente. Aqui está um exemplo de manifest que exporta um dashboard como JSON (útil para versionamento em Git):</p>

<pre><code class="language-bash"># Exportar dashboard existente

curl -s http://admin:senha@localhost:3000/api/dashboards/uid/seu_uid | jq &#039;.dashboard&#039; &gt; dashboard.json

Importar dashboard em outro cluster

curl -X POST http://admin:senha@localhost:3000/api/dashboards/db \

-H &quot;Content-Type: application/json&quot; \

-d @dashboard.json</code></pre>

<h2>Alertas em Grafana: Detecção e Notificação</h2>

<h3>Estruturando Regras de Alerta Práticas</h3>

<p>Alertas são inúteis se forem genéricos demais ou muito ruidosos. A chave está em criar alertas baseados em SLOs (Service Level Objectives) reais do seu negócio. Um alerta só deve disparar quando uma ação humana é necessária.</p>

<p>Para criar um alerta efetivo, comece definindo a condição. No Grafana, abra um panel e clique em <strong>Alert</strong>. Configure uma query de avaliação — por exemplo, um alerta quando CPU ultrapassa 80%:</p>

<pre><code class="language-promql">avg(rate(container_cpu_usage_seconds_total[5m])) by (namespace, pod) &gt; 0.8</code></pre>

<p>Configure o intervalo de avaliação em 1 minuto e o tempo de espera (for) em 5 minutos. O &quot;for&quot; evita que picos momentâneos disparem alertas falsos. Defina as labels e anotações que ajudem na investigação:</p>

<pre><code class="language-yaml"># Anotação dentro da regra

description: &quot;Pod {{ $labels.pod }} no namespace {{ $labels.namespace }} com CPU acima de 80%&quot;

runbook_url: &quot;https://seu-wiki.com/cpu-high&quot;</code></pre>

<h3>Configurando Notificações via Webhook</h3>

<p>Grafana suporta múltiplos canais de notificação: email, Slack, PagerDuty, webhooks customizados, entre outros. Para configurar um webhook (útil para integrar com sistemas legados), vá em <strong>Configuration</strong> &gt; <strong>Notification channels</strong> e crie um novo canal:</p>

<pre><code class="language-json">{

&quot;type&quot;: &quot;webhook&quot;,

&quot;settings&quot;: {

&quot;url&quot;: &quot;https://seu-sistema.com/api/alerts&quot;,

&quot;httpMethod&quot;: &quot;POST&quot;

}

}</code></pre>

<p>Aqui está um exemplo de payload recebido pelo seu webhook:</p>

<pre><code class="language-json">{

&quot;status&quot;: &quot;firing&quot;,

&quot;alerts&quot;: [

{

&quot;status&quot;: &quot;firing&quot;,

&quot;labels&quot;: {

&quot;alertname&quot;: &quot;HighCPU&quot;,

&quot;namespace&quot;: &quot;production&quot;,

&quot;pod&quot;: &quot;api-server-abc123&quot;

},

&quot;annotations&quot;: {

&quot;description&quot;: &quot;Pod api-server-abc123 no namespace production com CPU acima de 80%&quot;,

&quot;runbook_url&quot;: &quot;https://seu-wiki.com/cpu-high&quot;

},

&quot;startsAt&quot;: &quot;2024-01-15T10:30:00.000Z&quot;,

&quot;endsAt&quot;: &quot;0001-01-01T00:00:00Z&quot;

}

]

}</code></pre>

<h3>Agrupamento e Silenciamento de Alertas</h3>

<p>Em ambientes grandes, você pode receber centenas de alertas relacionados ao mesmo problema (um node down gera alertas de todos os pods daquele node). Configure agrupamento no arquivo <code>alertmanager.yml</code> para reduzir ruído:</p>

<pre><code class="language-yaml">route:

group_by: [&#039;alertname&#039;, &#039;cluster&#039;, &#039;namespace&#039;]

group_wait: 30s

group_interval: 5m

repeat_interval: 4h

receiver: &#039;default&#039;

routes:

  • match:

severity: critical

receiver: &#039;pagerduty&#039;

continue: true

  • match:

severity: warning

receiver: &#039;slack&#039;</code></pre>

<p>O Grafana permite silenciar alertas manualmente através da UI. Isso é essencial durante manutenções planejadas:</p>

<pre><code class="language-bash"># Exemplo de curl para silenciar alertas (via AlertManager)

curl -X POST http://alertmanager:9093/api/v1/silences \

-H &quot;Content-Type: application/json&quot; \

-d &#039;{

&quot;matchers&quot;: [

{&quot;name&quot;: &quot;namespace&quot;, &quot;value&quot;: &quot;staging&quot;, &quot;isRegex&quot;: false}

],

&quot;startsAt&quot;: &quot;2024-01-15T10:00:00Z&quot;,

&quot;endsAt&quot;: &quot;2024-01-15T12:00:00Z&quot;,

&quot;createdBy&quot;: &quot;usuario@empresa.com&quot;,

&quot;comment&quot;: &quot;Manutenção planejada&quot;

}&#039;</code></pre>

<h2>Loki: Centralizando e Consultando Logs</h2>

<h3>Arquitetura e Fluxo de Logs no Loki</h3>

<p>Loki funciona de forma diferente de stacks ELK. Enquanto Elasticsearch indexa todo o conteúdo dos logs (custoso), Loki indexa apenas labels (metadados) e compacta o conteúdo. Isso torna Loki muito mais eficiente em termos de armazenamento e custos, especialmente em Kubernetes.</p>

<p>O fluxo é simples: aplicações geram logs no stdout, Promtail (agente de coleta) os lê, adiciona labels dinâmicos baseado em metadados do Kubernetes, e envia para Loki. Loki os armazena em chunks compactados. Quando você consulta, Loki faz matching de labels primeiro (rápido) e depois busca no conteúdo (menos custoso).</p>

<h3>Configuração de Promtail para Capturar Logs de Kubernetes</h3>

<p>O Promtail é um agente leve que roda em cada node do cluster. Ele tira proveito da auto-descoberta do Kubernetes para identificar todos os pods e seus logs. Aqui está uma configuração real de Promtail:</p>

<pre><code class="language-yaml">apiVersion: v1

kind: ConfigMap

metadata:

name: promtail-config

namespace: monitoring

data:

promtail-config.yaml: |

clients:

  • url: http://loki:3100/loki/api/v1/push

scrape_configs:

  • job_name: kubernetes-pods

kubernetes_sd_configs:

  • role: pod

relabel_configs:

  • source_labels: [__meta_kubernetes_pod_name]

action: replace

target_label: pod_name

  • source_labels: [__meta_kubernetes_namespace]

action: replace

target_label: namespace

  • source_labels: [__meta_kubernetes_pod_label_app]

action: replace

target_label: app

  • source_labels: [__meta_kubernetes_pod_container_name]

action: replace

target_label: container

  • action: labelmap

regex: __meta_kubernetes_pod_label_(.+)

---

apiVersion: apps/v1

kind: DaemonSet

metadata:

name: promtail

namespace: monitoring

spec:

selector:

matchLabels:

app: promtail

template:

metadata:

labels:

app: promtail

spec:

serviceAccountName: promtail

containers:

  • name: promtail

image: grafana/promtail:latest

args:

  • -config.file=/etc/promtail/promtail-config.yaml

volumeMounts:

  • name: config

mountPath: /etc/promtail

  • name: varlog

mountPath: /var/log

  • name: varlibdockercontainers

mountPath: /var/lib/docker/containers

readOnly: true

volumes:

  • name: config

configMap:

name: promtail-config

  • name: varlog

hostPath:

path: /var/log

  • name: varlibdockercontainers

hostPath:

path: /var/lib/docker/containers

---

apiVersion: v1

kind: ServiceAccount

metadata:

name: promtail

namespace: monitoring

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

name: promtail

rules:

  • apiGroups: [&quot;&quot;]

resources:

  • nodes
  • nodes/proxy
  • services
  • endpoints
  • pods

verbs: [&quot;get&quot;, &quot;list&quot;, &quot;watch&quot;]

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

name: promtail

roleRef:

apiGroup: rbac.authorization.k8s.io

kind: ClusterRole

name: promtail

subjects:

  • kind: ServiceAccount

name: promtail

namespace: monitoring</code></pre>

<h3>Queries Práticas em LogQL</h3>

<p>LogQL é a linguagem de consulta do Loki, similar a PromQL mas otimizada para logs. Diferente de Elasticsearch, você não consulta campos individuais sem ter um label correspondente. Aqui estão queries reais que você usará:</p>

<pre><code class="language-logql"># Todos os logs de um namespace específico

{namespace=&quot;production&quot;}

Logs ERROR de uma aplicação específica

{app=&quot;api-gateway&quot;} | json | level=&quot;ERROR&quot;

Logs contendo &quot;timeout&quot; com duração acima de 5s

{namespace=&quot;production&quot;} | json | duration &gt; 5 and message=~&quot;timeout&quot;

Taxa de erros por minuto

sum(rate({namespace=&quot;production&quot;} | json | level=&quot;ERROR&quot; [1m])) by (pod_name)

Logs ordenados por timestamp e limitados aos últimos 100

{app=&quot;web-server&quot;} | json | line_format &quot;{{.timestamp}} {{.level}} {{.message}}&quot; | limit 100</code></pre>

<p>A query abaixo é particularmente útil para investigar comportamentos anormais — mostra a evolução de um erro ao longo do tempo:</p>

<pre><code class="language-logql">avg_over_time({namespace=&quot;staging&quot;, app=&quot;backend&quot;} | json | duration | unwrap duration(s) [1m]) by (endpoint)</code></pre>

<h2>Conclusão</h2>

<p>Você aprendeu nesta aula que Grafana, Prometheus e Loki formam um trio poderoso para observabilidade em Kubernetes. O conhecimento prático que você ganhou vai além de &quot;clicar em botões&quot;: você entendeu que alertas efetivos exigem foco em SLOs reais, que dashboards devem contar uma história clara em 10 segundos, e que logs indexados por labels (Loki) são fundamentalmente mais eficientes que indexação full-text em clusters Kubernetes. A chave para sucesso em produção é começar simples (monitorar CPU e memória), testar seus alertas antes de conectar notificações, e evoluir baseado em alertas que realmente são acionáveis.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://grafana.com/docs/grafana/latest/" target="_blank" rel="noopener noreferrer">Documentação Oficial do Grafana</a></li>

<li><a href="https://prometheus.io/docs/prometheus/latest/configuration/configuration/" target="_blank" rel="noopener noreferrer">Guia do Prometheus para Kubernetes</a></li>

<li><a href="https://grafana.com/docs/loki/latest/" target="_blank" rel="noopener noreferrer">Loki: Log Aggregation for Kubernetes</a></li>

<li><a href="https://www.prometheus.io/docs/guides/kubernetes-monitoring/" target="_blank" rel="noopener noreferrer">Kubernetes Monitoring with Prometheus (Livro)</a></li>

<li><a href="https://prometheus.io/docs/alerting/latest/configuration/" target="_blank" rel="noopener noreferrer">AlertManager Configuration Guide</a></li>

</ul>

<p>&lt;!-- FIM --&gt;</p>

Comentários

Mais em Docker & Kubernetes

Dominando Persistent Volumes em Kubernetes: PV, PVC e Storage Classes em Projetos Reais
Dominando Persistent Volumes em Kubernetes: PV, PVC e Storage Classes em Projetos Reais

Entendendo Armazenamento Persistente em Kubernetes Quando você trabalha com K...

GKE no GCP: Autopilot, Workload Identity e Cloud SQL Proxy: Do Básico ao Avançado
GKE no GCP: Autopilot, Workload Identity e Cloud SQL Proxy: Do Básico ao Avançado

GKE Autopilot: Gerenciamento Automático de Clusters Kubernetes O Google Kuber...

Redes em Docker: bridge, host, overlay e macvlan na Prática na Prática
Redes em Docker: bridge, host, overlay e macvlan na Prática na Prática

Entendendo as Redes no Docker: Uma Perspectiva Prática Quando você começa a t...