TL;DR — Resumo Rápido

Configure o Prometheus com Node Exporter para monitorar servidores Linux. PromQL, regras de alerta, Alertmanager, ajuste de armazenamento e segurança.

Prometheus é o padrão de fato para monitoramento de infraestrutura open-source. Combinado com o Node Exporter, oferece visibilidade profunda em cada servidor Linux da sua frota — uso de CPU, pressão de memória, saturação de disco, taxa de transferência de rede e médias de carga — tudo consultável com uma linguagem de expressão poderosa e alertável pelo Alertmanager. Este guia cobre desde o início até um stack de monitoramento pronto para produção.

Pré-requisitos

  • Ubuntu 22.04 ou Debian 12 (idêntico no RHEL/Rocky substituindo apt por dnf)
  • Acesso root ou sudo
  • Portas 9090 (Prometheus), 9100 (Node Exporter) e 9093 (Alertmanager) abertas no firewall
  • Familiaridade básica com systemd e YAML

Visão Geral da Arquitetura

O Prometheus usa um modelo pull: ele coleta endpoints HTTP chamados targets em um intervalo configurável e armazena os dados de séries temporais localmente em um banco de dados colunar (TSDB).

┌─────────────────────────────────────────────────────────┐
│                   Servidor Linux                         │
│                                                          │
│   Node Exporter :9100  ←  Prometheus :9090  →  Grafana  │
│         ↑                      ↓                         │
│   /proc /sys              TSDB em disco                  │
│                                ↓                         │
│                          Alertmanager :9093              │
│                          (email/Slack/PD)                │
└─────────────────────────────────────────────────────────┘

Conceitos-chave:

  • Scrape — O Prometheus busca /metrics de cada target no scrape_interval
  • TSDB — Banco de dados de séries temporais local; cada métrica é um float64 com timestamp e labels
  • PromQL — Linguagem de consulta para fatiar, agregar e calcular taxas sobre séries temporais
  • Alertmanager — Processo separado que recebe alertas do Prometheus e roteia notificações

Passo 1: Instalar o Prometheus

Criar usuário do sistema e diretórios

sudo useradd --system --no-create-home --shell /bin/false prometheus

sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus /var/lib/prometheus

Baixar e instalar o binário

PROM_VERSION="2.51.2"
cd /tmp
wget "https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/prometheus-${PROM_VERSION}.linux-amd64.tar.gz"
tar xzf prometheus-${PROM_VERSION}.linux-amd64.tar.gz
cd prometheus-${PROM_VERSION}.linux-amd64

sudo cp prometheus promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus /usr/local/bin/promtool
sudo cp -r consoles console_libraries /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus/consoles /etc/prometheus/console_libraries

Escrever prometheus.yml

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    environment: "production"

rule_files:
  - /etc/prometheus/rules/*.yml

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["localhost:9093"]

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: "node"
    static_configs:
      - targets: ["localhost:9100"]
    labels:
      instance: "web-01"
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
promtool check config /etc/prometheus/prometheus.yml

Criar a unidade systemd

[Unit]
Description=Sistema de Monitoramento Prometheus
After=network.target

[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --storage.tsdb.retention.time=30d \
  --web.listen-address=0.0.0.0:9090 \
  --web.enable-lifecycle

Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/prometheus

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
sudo systemctl status prometheus

Passo 2: Instalar o Node Exporter

O Node Exporter expõe métricas de hardware e SO a partir de /proc e /sys na porta 9100.

NODE_VERSION="1.7.0"
cd /tmp
wget "https://github.com/prometheus/node_exporter/releases/download/v${NODE_VERSION}/node_exporter-${NODE_VERSION}.linux-amd64.tar.gz"
tar xzf node_exporter-${NODE_VERSION}.linux-amd64.tar.gz

sudo useradd --system --no-create-home --shell /bin/false node_exporter
sudo cp node_exporter-${NODE_VERSION}.linux-amd64/node_exporter /usr/local/bin/
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
[Unit]
Description=Prometheus Node Exporter
After=network.target

[Service]
Type=simple
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter \
  --collector.systemd \
  --collector.processes

Restart=on-failure
NoNewPrivileges=true
ProtectSystem=strict

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
curl -s http://localhost:9100/metrics | head -20

Métricas-Chave do Node Exporter

MétricaDescrição
node_cpu_seconds_totalTempo de CPU por modo (user, system, idle) — usar com rate()
node_memory_MemAvailable_bytesMemória disponível (inclui cache recuperável)
node_memory_MemTotal_bytesMemória física total
node_filesystem_avail_bytesEspaço livre em disco
node_network_receive_bytes_totalBytes recebidos por interface — usar com rate()
node_load1 / node_load5 / node_load15Médias de carga do sistema
node_disk_io_time_seconds_totalTempo em I/O — usar rate() para saturação

Fundamentos de PromQL

Abra a UI do Prometheus em http://seu-servidor:9090 para experimentar.

Uso de CPU em porcentagem

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

Uso de memória em porcentagem

(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

Uso de disco em porcentagem

(1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / node_filesystem_size_bytes)) * 100

Principais funções do PromQL

FunçãoPropósito
rate()Taxa por segundo em média sobre um intervalo
increase()Incremento total em um intervalo
histogram_quantile()Latência P99 de uma métrica de histograma
avg by()Média em uma dimensão
topk()As N séries mais altas por valor
predict_linear()Prevê o valor em N segundos

Regras de Alerta

# /etc/prometheus/rules/alerts.yml
groups:
  - name: node_alerts
    interval: 30s
    rules:

      - alert: AltoCPU
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Alto uso de CPU em {{ $labels.instance }}"
          description: "Uso de CPU: {{ $value | printf \"%.1f\" }}% por mais de 5 minutos."

      - alert: PoucoEspacoEmDisco
        expr: (node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / node_filesystem_size_bytes) * 100 < 15
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Pouco espaço em disco em {{ $labels.instance }}"
          description: "Partição {{ $labels.mountpoint }} tem {{ $value | printf \"%.1f\" }}% livre."

      - alert: InstanciaFora
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Instância {{ $labels.instance }} inacessível"
          description: "{{ $labels.job }}/{{ $labels.instance }} está inacessível há 1 minuto."

      - alert: AltoUsoMemoria
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Alto uso de memória em {{ $labels.instance }}"
          description: "Uso de memória: {{ $value | printf \"%.1f\" }}%."
sudo mkdir -p /etc/prometheus/rules
sudo chown -R prometheus:prometheus /etc/prometheus/rules
promtool check rules /etc/prometheus/rules/alerts.yml
sudo systemctl reload prometheus

Configuração do Alertmanager

Instalar o Alertmanager

AM_VERSION="0.27.0"
cd /tmp
wget "https://github.com/prometheus/alertmanager/releases/download/v${AM_VERSION}/alertmanager-${AM_VERSION}.linux-amd64.tar.gz"
tar xzf alertmanager-${AM_VERSION}.linux-amd64.tar.gz

sudo useradd --system --no-create-home --shell /bin/false alertmanager
sudo mkdir -p /etc/alertmanager /var/lib/alertmanager
sudo cp alertmanager-${AM_VERSION}.linux-amd64/alertmanager /usr/local/bin/
sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager /etc/alertmanager /var/lib/alertmanager

Configurar rotas de notificação

# /etc/alertmanager/alertmanager.yml
global:
  slack_api_url: "https://hooks.slack.com/services/SEU/WEBHOOK/AQUI"

route:
  group_by: ["alertname", "instance"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: "equipe-ops"
  routes:
    - match:
        severity: critical
      receiver: "pagerduty"

receivers:
  - name: "equipe-ops"
    slack_configs:
      - channel: "#alertas"
        send_resolved: true

  - name: "pagerduty"
    pagerduty_configs:
      - routing_key: "SUA_CHAVE_PAGERDUTY"
        send_resolved: true

inhibit_rules:
  - source_match:
      severity: critical
    target_match:
      severity: warning
    equal: ["alertname", "instance"]
sudo systemctl daemon-reload
sudo systemctl enable --now alertmanager

Regras de Gravação

As regras de gravação pré-calculam expressões PromQL custosas e armazenam o resultado como uma nova métrica, acelerando dashboards com muitos nós.

# /etc/prometheus/rules/recording.yml
groups:
  - name: node_recording
    interval: 1m
    rules:
      - record: instance:node_cpu_usage:percent
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

      - record: instance:node_memory_usage:percent
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

      - record: instance:node_filesystem_usage:percent
        expr: (1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|devtmpfs"} / node_filesystem_size_bytes)) * 100

Ajuste de Armazenamento

O TSDB do Prometheus comprime eficientemente — aproximadamente 1-2 bytes por amostra. Um servidor com 1.000 métricas a cada 15 segundos acumula cerca de 2 GB por mês.

# Flags no ExecStart do serviço prometheus:
--storage.tsdb.retention.time=90d
--storage.tsdb.retention.size=20GB
--storage.tsdb.wal-compression
du -sh /var/lib/prometheus/

Segurança

Autenticação básica

# /etc/prometheus/web.yml
basic_auth_users:
  admin: "$2y$10$seu-hash-bcrypt-aqui"

Proxy reverso com nginx

server {
    listen 443 ssl;
    server_name prometheus.exemplo.com;
    ssl_certificate /etc/letsencrypt/live/prometheus.exemplo.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/prometheus.exemplo.com/privkey.pem;
    auth_basic "Prometheus";
    auth_basic_user_file /etc/nginx/.prometheus-htpasswd;
    location / {
        proxy_pass http://127.0.0.1:9090;
    }
}

Regras de firewall

sudo ufw deny 9090
sudo ufw deny 9093
sudo ufw allow from 10.0.0.5 to any port 9100

Tabela Comparativa

RecursoPrometheusZabbixNagiosDatadogNetdata
ModeloPull (scrape)Push/PullPullPush (agente)Push
ArmazenamentoTSDB localPostgreSQL/MySQLArquivos planosSaaS cloudBD próprio
Linguagem de consultaPromQL (poderosa)Custom + SQLNenhumaDogStatsDCustom
DashboardsGrafana (externo)IntegradoNão nativoIntegradoIntegrado
CustoGrátis / open-sourceGrátis (enterprise pago)Grátis (enterprise pago)SaaSGrátis (cloud pago)
Curva de aprendizadoModerada (PromQL)ÍngremeÍngremeBaixaMuito baixa

Stack de Produção

Servidor Prometheus (2 vCPU / 4 GB RAM):
  - /var/lib/prometheus → volume de dados separado (100 GB+)
  - Retenção: 30d tempo OU 20 GB tamanho

Node Exporter (em cada servidor):
  - Serviço systemd, porta 9100
  - Firewall: permitir 9100 apenas do IP do Prometheus

Alertmanager:
  - Slack para warnings, PagerDuty para critical
  - Regras de inibição: suprimir warnings quando critical está ativo

Grafana (recomendado):
  - docker run -d -p 3000:3000 grafana/grafana
  - Importar dashboard ID 1860 (Node Exporter Full)

Armadilhas e Casos Extremos

rate() requer pelo menos duas amostras. Se um contador se reinicia (reinício do processo), rate() lida com isso corretamente. Use rate() para regras de alerta, não irate().

Explosão de cardinalidade. Nunca use labels de alta cardinalidade como user_id ou request_url. Cada combinação única cria uma série temporal separada.

A cláusula for previne alarmes falsos. Um alerta com for: 5m deve estar disparando continuamente por 5 minutos antes de enviar uma notificação.

As regras de gravação não têm dados históricos. Após adicionar uma regra de gravação, a nova métrica só existe a partir desse momento.

O timeout de scrape deve ser menor que o intervalo. Se scrape_timeout exceder scrape_interval, o Prometheus registrará erros.


Resumo

  • O Prometheus usa um modelo pull — coleta endpoints /metrics em um intervalo configurável
  • O Node Exporter expõe métricas de hardware e SO na porta 9100
  • PromQL com rate(), increase() e histogram_quantile() forma a base de consultas úteis
  • Escreva regras de alerta com cláusula for para evitar alarmes falsos; roteie pelo Alertmanager
  • As regras de gravação pré-calculam agregações custosas — críticas para dashboards multinó
  • Ajuste a retenção de armazenamento com --storage.tsdb.retention.time ou --storage.tsdb.retention.size
  • Sempre coloque o Prometheus atrás de um proxy reverso com TLS e restrinja acesso direto às portas

Artigos Relacionados