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
aptpordnf) - 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
/metricsde cada target noscrape_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étrica | Descrição |
|---|---|
node_cpu_seconds_total | Tempo de CPU por modo (user, system, idle) — usar com rate() |
node_memory_MemAvailable_bytes | Memória disponível (inclui cache recuperável) |
node_memory_MemTotal_bytes | Memória física total |
node_filesystem_avail_bytes | Espaço livre em disco |
node_network_receive_bytes_total | Bytes recebidos por interface — usar com rate() |
node_load1 / node_load5 / node_load15 | Médias de carga do sistema |
node_disk_io_time_seconds_total | Tempo 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ção | Propó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
| Recurso | Prometheus | Zabbix | Nagios | Datadog | Netdata |
|---|---|---|---|---|---|
| Modelo | Pull (scrape) | Push/Pull | Pull | Push (agente) | Push |
| Armazenamento | TSDB local | PostgreSQL/MySQL | Arquivos planos | SaaS cloud | BD próprio |
| Linguagem de consulta | PromQL (poderosa) | Custom + SQL | Nenhuma | DogStatsD | Custom |
| Dashboards | Grafana (externo) | Integrado | Não nativo | Integrado | Integrado |
| Custo | Grátis / open-source | Grátis (enterprise pago) | Grátis (enterprise pago) | SaaS | Grátis (cloud pago) |
| Curva de aprendizado | Moderada (PromQL) | Íngreme | Íngreme | Baixa | Muito 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
/metricsem um intervalo configurável - O Node Exporter expõe métricas de hardware e SO na porta 9100
- PromQL com
rate(),increase()ehistogram_quantile()forma a base de consultas úteis - Escreva regras de alerta com cláusula
forpara 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.timeou--storage.tsdb.retention.size - Sempre coloque o Prometheus atrás de um proxy reverso com TLS e restrinja acesso direto às portas