RetroDash // SATURAÇÃO

GUIASaturação de recursos: CPU, memória, disco e rede

Tema

Requisitos

Para métricas de saturação você precisa:

Notas de Compatibilidade

Variável $job_node

Todas as queries de node_cpu_seconds_total, node_memory_* e node_filesystem_* são filtradas pela variável de dashboard $job_node (padrão: node-exporter). Se o seu node_exporter é coletado com um nome de job diferente, atualize a variável em Configurações do Dashboard → Variables.

Valores baixos de saturação em homelabs

As métricas de saturação refletem sua carga de trabalho real. Em um homelab típico com uso leve, é completamente normal ver a CPU em 2–10%, a memória em 30–50% e o I/O de disco próximo a zero. Valores baixos não são sinal de configuração incorreta — indicam que sua infraestrutura tem capacidade disponível. Os limites estão calibrados para cargas de trabalho de produção; sinta-se à vontade para reduzir os limites de aviso/crítico para adequá-los à linha de base do seu homelab.

Mapa de Painéis

┌────────────────────────────────────────┐
│   SATURAÇÃO — ESGOTAMENTO RECURSO     │
├────────────────────────────────────────┤
│  CPU %   │  Memória %  │  Disco %  │Net│
│  (gauge) │  (gauge)    │  (gauge) │(g)│
├────────────────────────────────────────┤
│  CPU + Memória Série Temporal [12 col]│
│  (evolução com limiares)               │
├────────────────────────────────────────┤
│  I/O Disco [6 cols] │ Disco Livre [6] │
│  (ops leitura/escri)│ (por mount)     │
├────────────────────────────────────────┤
│  Recurso por Nó [12 cols]              │
│  (tabela: CPU, mem, disco por host)    │
├────────────────────────────────────────┤
│  Requisições vs Limiares [12 cols]     │
│  (desglose de demanda atual vs limite) │
└────────────────────────────────────────┘

Personalização por Painel

CPU % Gauge

Porcentagem de CPU em uso (excluindo idle).

100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Por instância específica:

100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle",instance="server1:9100"}[5m])) * 100)

Excluir modos específicos (excluir iowait, steal):

100 - (avg(rate(node_cpu_seconds_total{mode=~"idle|iowait"}[5m])) * 100)

Limiares recomendados: 70% amarelo, 85% vermelho

Memória % Gauge

Porcentagem de memória em uso.

Usando disponível (recomendado):

100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))

Usando livre (menos preciso):

100 * (1 - (node_memory_MemFree_bytes / node_memory_MemTotal_bytes))

Por nó:

100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) by (instance)

Limiares: 80% amarelo, 90% vermelho (deixe buffer para cache)

Disco % Gauge

Porcentagem de disco utilizado (por ponto de montagem).

Padrão (partição raiz):

100 * (node_filesystem_used_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})

Excluir tmpfs e sistemas virtuais:

100 * (node_filesystem_used_bytes{fstype!~"tmpfs|devtmpfs|fuse.*",mountpoint!~"/sys.*|/proc.*"}
/ node_filesystem_size_bytes{fstype!~"tmpfs|devtmpfs|fuse.*"}) by (device)

Por ponto de montagem:

sum by (mountpoint) (100 * (node_filesystem_used_bytes / node_filesystem_size_bytes))

Limiares: 80% amarelo, 90% vermelho

Saturação de Rede

Porcentagem de largura de banda saturada.

Usando velocidade de interface (se disponível):

100 * ((rate(node_network_transmit_bytes_total[5m]) * 8)
/ (node_network_speed_bytes * 1000000000))

Sem speed (normalizar por histórico):

rate(node_network_transmit_bytes_total[5m]) /
  avg_over_time(rate(node_network_transmit_bytes_total[5m])[1h:1m])

Por direção (in/out):

sum by (device) (rate(node_network_receive_bytes_total[5m]))

CPU + Memória Série Temporal

Gráfico de linhas com evolução de ambos os recursos.

Query CPU:

100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Query Memória:

100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))

Desglose por nó:

100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Adicione linhas de limiar: No painel → Alerts → 70% (aviso), 85% (crítico)

I/O Disco

Operações de leitura/escrita por segundo.

Ops de leitura/sec:

rate(node_disk_reads_completed_total{device="sda"}[5m])

Ops de escrita/sec:

rate(node_disk_writes_completed_total{device="sda"}[5m])

Mudar dispositivo: sdanvme0n1 (NVMe), vda (virtual), etc

Utilização %:

rate(node_disk_io_time_seconds_total{device="sda"}[5m]) * 100

Nota: > 30% I/O wait indica contenção de disco

Disco Livre por Montagem

Espaço disponível por ponto de montagem.

node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / 1024 / 1024 / 1024

Mostrar por ponto de montagem:

sum by (mountpoint) (node_filesystem_avail_bytes) / 1024 / 1024 / 1024

Porcentagem disponível:

100 * (node_filesystem_avail_bytes / node_filesystem_size_bytes) by (mountpoint)

Recurso por Nó (Tabela)

Tabela dinâmica com CPU, memória e disco por nó.

Estrutura JSON para tabela multi-métrica:

sum by (instance) (100 - (rate(node_cpu_seconds_total{mode="idle"}[5m]) * 100)) // CPU
sum by (instance) (100 * (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) // Memory
sum by (instance, device) (100 * node_filesystem_used_bytes / node_filesystem_size_bytes) // Disk

Filtrar nós de produção:

sum by (instance) (...) {instance=~"prod.*"}

Requisições vs Limiares

Comparativa de recursos requisitados vs limiares no K8s.

Requisições CPU:

sum by (namespace, pod) (kube_pod_container_resource_requests_cpu_cores)

Limiares CPU:

sum by (namespace, pod) (kube_pod_container_resource_limits_cpu_cores)

Memória (em bytes):

sum by (namespace, pod) (kube_pod_container_resource_limits_memory_bytes) / 1024 / 1024

Filtrar por namespace:

sum by (namespace, pod) (...) {namespace!~"kube-system|kube-.*"}

Mudar Tema de Cor

Tema OK (<70%) Aviso (70-85%) Crítico (>85%)
GREEN #33FF00 #FFCC00 #FF4444
AMBER #FFB000 #FF8C00 #FF4500
BLUE #00BFFF #FFD700 #FF1493

Limiares de gauge em JSON:

"thresholds": {
  "mode": "absolute",
  "steps": [
    { "color": "green", "value": null },
    { "color": "yellow", "value": 70 },
    { "color": "red", "value": 85 }
  ]
}

Adaptar à sua Resolução

Tipo Largura Stat Card Altura Gráfico Altura Tabela
Mobile 6 (stack vertical) 10 12
Tablet 10.9" 12 (largura completa) 12 14
iPad Pro 12.9" 12 (largura completa) 14 16
Desktop 1920×1080 6 (4 cols) 10 12

Importar no Grafana

  1. Exporte painel SATURAÇÃO como JSON
  2. Dashboards → Import
  3. Cole JSON
  4. Selecione datasource Prometheus
  5. Verifique métricas de node_exporter disponíveis
  6. Se faltar métricas, revise que node_exporter está rodando com as flags corretas
  7. Salve e personalize limiares conforme sua infraestrutura

Dicas Avançadas

Detecção de pico de CPU

rate(node_cpu_seconds_total{mode!="idle"}[5m]) >
  avg_over_time(rate(node_cpu_seconds_total{mode!="idle"}[5m])[1h:5m]) * 1.5

Alerta se CPU se eleva 50% acima do promédio de 1h.

Pressão de Memória (usando swap)

(node_memory_SwapFree_bytes / node_memory_SwapTotal_bytes) < 0.3

Alerta se usa > 70% de swap (indicador de pressão de memória severa).

Projeção de esgotamento de disco

predict_linear(node_filesystem_avail_bytes{mountpoint="/"}[1h], 86400)

Prevê espaço disponível em 24h. Se < 10GB, alerte proativamente.

Correlacionar saturação com latência

histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) * 1000
+ (node_load1 / count(node_cpu_seconds_total{mode="idle"}) * 100)

Suaviza latência por fator de carga (mostra impacto de saturação).