DevOps

Configura Prometheus y Grafana: Guía DevOps para SysAdmins Linux

Monitoreo sin Grafana es como tener un auto sin tablero. Prometheus + Grafana es el stack de facto en 2026, y aunque la instalación es directa, el setup que realmente sirve en producción tiene varias decisiones: retención de métricas, alertmanager, exporters, dashboards, y la integración con el stack de logs. Esta guía documenta el setup que recomiendo para homelabs y SMBs: Prometheus en Docker, Grafana con dashboards pre-armados, alertmanager con Telegram, y node_exporter + postgres_exporter + nginx_exporter como base. Si estás empezando con monitoreo serio, esto te da un stack funcional en 2 horas.

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 1.5-2 horas para stack funcional, 30 minutos por servicio adicional.
  • Requisitos: Servidor Linux con 2+ GB RAM libres, Docker, root.
  • Resultado: Stack Prometheus + Grafana + Alertmanager funcional, dashboards de Linux/Postgres/Nginx, alertas a Telegram.
  • Troubleshooting típico: scrape fallando, retention llenando disco, OOM en Prometheus. Solución: `promtool query` + métricas de exporters.

Por qué necesitas monitoring hoy

Si gestionas un servidor Linux en producción, en algún momento vas a necesitar saber por qué algo se puso lento, qué recurso se agotó primero, o cuándo un servicio cayó antes de que un cliente te lo reportara. Prometheus + Grafana es la combinación estándar de la industria para eso: Prometheus recolecta métricas con un modelo pull (él decide cuándo consultar a cada servicio), Grafana las convierte en dashboards y alertas. Es open source, no requiere enviar datos a un tercero, y corre cómodo en un VPS pequeño.

Esta guía te deja un Prometheus 3.x LTS y un Grafana 13.x operativos en Debian/Ubuntu, scrapeando el propio host con node_exporter, con un dashboard de CPU/memoria/disk/red funcional y una regla de alerta básica. Terminarás con menos de 1 GB de RAM consumida entre los tres binarios.

Cómo funciona el modelo pull

Prometheus es un servidor de series de tiempo (TSDB) que scrapea endpoints HTTP en intervalos regulares. Cada servicio expone sus métricas en una ruta (típicamente /metrics) en formato texto plano, y Prometheus las guarda indexadas por nombre + etiquetas (labels).

El modelo pull tiene ventajas operativas: tú defines en prometheus.yml qué targets scrapear, Prometheus detecta caídas (si un target no responde, marca up=0), y un firewall saliente desde Prometheus es más fácil de auditar que N agentes saliendo desde cada servidor. La contrapartida: servicios short-lived (jobs batch, funciones Lambda) necesitan un push gateway intermediario, no entran al modelo directo.

El componente node_exporter es un binario oficial del proyecto Prometheus que expone métricas de hardware y kernel (CPU, memoria, discos, red, filesystem, presión de carga) en el puerto 9100. Es lo que scrapearemos contra el propio host donde corre Prometheus.

Instalar Prometheus 3.x LTS

La rama LTS actual (septiembre 2026) es Prometheus 3.13.4 LTS, con un año de parches de bug y seguridad. La última estable es 3.15.0. Para servidores en producción conviene la LTS; para entornos donde quieres las últimas features (UTF-8 default, Remote Write 2.0, native histograms, OTLP), la estable.

Descarga la release, crea un usuario sin privilegios para el servicio y un directorio de datos:

# Descargar Prometheus LTS (verifica el sha256 desde github.com/prometheus/prometheus/releases)
PROM_VER=3.13.4
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v${PROM_VER}/prometheus-${PROM_VER}.linux-amd64.tar.gz
wget https://github.com/prometheus/prometheus/releases/download/v${PROM_VER}/sha256sums.txt
grep "prometheus-${PROM_VER}.linux-amd64.tar.gz" sha256sums.txt | sha256sum -c -
# Extraer solo los binarios y la config de ejemplo
tar -xzf prometheus-${PROM_VER}.linux-amd64.tar.gz
sudo mv prometheus-${PROM_VER}.linux-amd64/prometheus 
        prometheus-${PROM_VER}.linux-amd64/promtool 
        /usr/local/bin/
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo mv prometheus-${PROM_VER}.linux-amd64/prometheus.yml /etc/prometheus/
sudo mv prometheus-${PROM_VER}.linux-amd64/console_libraries /etc/prometheus/
sudo mv prometheus-${PROM_VER}.linux-amd64/consoles /etc/prometheus/
# Usuario de sistema dedicado
sudo useradd -r -s /usr/sbin/nologin prometheus
sudo chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus

El paso del sha256sum -c - es la única forma práctica de saber que el binario no fue manipulado en tránsito. Si la verificación falla, NO ejecutes el binario: el hash esperado y el calculado van por stdout y sha256sum -c devuelve exit 1 cuando hay mismatch.

Crear la unidad systemd

Prometheus necesita un unit que lo lance como usuario prometheus, apuntando a /etc/prometheus/prometheus.yml y /var/lib/prometheus. Los flags clave son --web.listen-address (puerto y bind), --storage.tsdb.retention.time y --storage.tsdb.retention.size (retención).

sudo tee /etc/systemd/system/prometheus.service > /dev/null << 'EOF'
[Unit]
Description=Prometheus monitoring system
Documentation=https://prometheus.io/docs/
After=network-online.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus 
  --config.file=/etc/prometheus/prometheus.yml 
  --storage.tsdb.path=/var/lib/prometheus 
  --storage.tsdb.retention.time=30d 
  --storage.tsdb.retention.size=10GB 
  --web.console.libraries=/etc/prometheus/console_libraries 
  --web.console.templates=/etc/prometheus/consoles 
  --web.listen-address=0.0.0.0:9090 
  --web.enable-lifecycle
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
sudo systemctl status prometheus --no-pager

Los flags --storage.tsdb.retention.time=30d y --storage.tsdb.retention.size=10GB imponen una doble cota, lo que detiene a Prometheus de comerse todo el disco si por error scrapeas targets con cardinalidad explosiva (cada label nueva multiplica series). El flag --web.enable-lifecycle permite recargar config vía curl -X POST http://localhost:9090/-/reload sin reiniciar el proceso (útil para no perder el buffer en memoria).

El puerto por defecto es 9090. Verifica que responde antes de seguir: curl -s http://localhost:9090/-/ready debe devolver Prometheus is Ready.

Configurar los targets a scrapear

El archivo prometheus.yml tiene tres secciones principales: global (intervalos por defecto), scrape_configs (lista de jobs con sus targets) y opcionalmente rule_files (archivos de reglas de alerta). El siguiente ejemplo scrapea el propio Prometheus y deja listo el job para node_exporter:

sudo tee /etc/prometheus/prometheus.yml > /dev/null << 'EOF'
global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    monitor: 'sysadmin-homelab'
rule_files:
  - "/etc/prometheus/rules/*.yml"
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']
        labels:
          instance_role: 'primary-host'
EOF
# Validar la config antes de aplicar (promtool atrapa errores de sintaxis YAML)
promtool check config /etc/prometheus/prometheus.yml
# Aplicar sin reiniciar el daemon (gracias a --web.enable-lifecycle)
curl -X POST http://localhost:9090/-/reload

promtool check config es el gate obligatorio: si la YAML está mal formada, promtool devuelve exit 1 con la línea exacta del error. Confirma siempre ANTES de hacer el -/-/reload; de lo contrario Prometheus aplica config inválida y el dashboard queda en estado inconsistente. El reload por API es atómico: Prometheus 0 o bien aplica todo el nuevo árbol de config, o bien lo rechaza entero y mantiene la config anterior.

Instalar node_exporter

node_exporter es un binario estático de ~20 MB que expone métricas del host en el puerto 9100. La versión actual va en sync con los releases LTS de Prometheus.

NE_VER=1.10.2
cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v${NE_VER}/node_exporter-${NE_VER}.linux-amd64.tar.gz
wget https://github.com/prometheus/node_exporter/releases/download/v${NE_VER}/sha256sums.txt
grep "node_exporter-${NE_VER}.linux-amd64.tar.gz" sha256sums.txt | sha256sum -c -
tar -xzf node_exporter-${NE_VER}.linux-amd64.tar.gz
sudo mv node_exporter-${NE_VER}.linux-amd64/node_exporter /usr/local/bin/
sudo tee /etc/systemd/system/node_exporter.service > /dev/null << 'EOF'
[Unit]
Description=Prometheus Node Exporter
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter 
  --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
sudo useradd -r -s /usr/sbin/nologin node_exporter
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
curl -s http://localhost:9100/metrics | head -5

El flag --collector.filesystem.mount-points-exclude evita que node_exporter reporte falsos positivos de filesystem lleno en /proc, /sys, /dev y bind mounts del host — son pseudo-filesystems que no tienen cuota útil y solo contaminan los dashboards con métricas siempre a 100%.

Verifica que Prometheus ve el target: en http://tu-host:9090/targets el job node debe aparecer con state UP. Si aparece DOWN, revisa firewall (ufw status) y que el puerto 9100 esté escuchando (ss -tlnp | grep 9100).

Instalar Grafana 13.x

Grafana es la capa de visualización. La última estable a la fecha es Grafana 13.2.2 (release 14 abril 2026). Se instala desde el repo oficial de Grafana Labs para tener upgrades automáticos.

# Repo oficial (Debian/Ubuntu)
sudo apt-get install -y apt-transport-https software-properties-common
wget -q -O - https://apt.grafana.com/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/grafana.gpg
echo "deb [signed-by=/usr/share/keyrings/grafana.gpg] https://apt.grafana.com stable main" | 
  sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install -y grafana
sudo systemctl enable --now grafana-server
sudo systemctl status grafana-server --no-pager

Grafana 13 escucha en el puerto 3000 por defecto. El usuario inicial es admin con contraseña admin; el primer login te obliga a cambiarla. Si expones Grafana fuera de localhost, hazlo detrás de un reverse proxy con TLS (Caddy o Nginx) y autenticación real — nunca dejes el panel de tu infra en plano HTTP.

Conectar Grafana a Prometheus

El datasource es el puente entre Grafana y Prometheus. Se configura una vez y queda disponible para todos los dashboards.

# API para crear el datasource sin pasar por la UI
curl -s -u admin:TU_PASSWORD_NUEVA 
  -X POST http://localhost:3000/api/datasources 
  -H "Content-Type: application/json" 
  -d '{
    "name": "Prometheus",
    "type": "prometheus",
    "url": "http://localhost:9090",
    "access": "proxy",
    "isDefault": true
  }'

El campo access: proxy indica que Grafana habla directo con Prometheus (vs direct que haría el browser del usuario). En single-host está bien; en Grafana expuesta vía internet, proxy evita filtrar la URL interna de Prometheus al browser.

Verifica que las queries funcionan: en Explore de Grafana, corre up. Debe devolver una fila por cada target scrapeado con value=1. Si devuelve vacío, el bridge datasource→Prometheus no está hablando — revisa la URL del datasource y que Prometheus esté escuchando en la interfaz correcta (ss -tlnp | grep 9090).

Crear el primer dashboard

Grafana tiene un importador de dashboards comunitarios (id numérico en grafana.com/grafana/dashboards). Para CPU, memoria, disco y red de un host Linux, el ID 1860 (Node Exporter Full) es el canónico: lo mantiene la comunidad y trae ~80 paneles con todo lo que expone node_exporter.

# Importar dashboard 1860 vía API
curl -s -u admin:TU_PASSWORD 
  -X POST http://localhost:3000/api/dashboards/import 
  -H "Content-Type: application/json" 
  -d '{
    "dashboard": {
      "id": 1860,
      "title": "Node Exporter Full - Host Principal",
      "uid": "node-exporter-full"
    },
    "inputs": [{
      "name": "DS_PROMETHEUS",
      "type": "datasource",
      "pluginId": "prometheus",
      "value": "Prometheus"
    }],
    "overwrite": true
  }'

El dashboard 1860 cubre CPU por modo (user, system, iowait, steal), memoria RAM y swap, uso de disco por filesystem, IOPS por dispositivo, red por interfaz con errores/descartes, y presión de carga (PSI). Si solo quieres CPU+RAM+disco, hay versiones minimalistas (ID 15119) que cargan más rápido en dashboards con muchos hosts.

Alertas: la parte más útil

Un dashboard sin alertas es solo una foto. La gracia real es despertar a las 3 AM si el disco se está llenando. Prometheus tiene un motor de alerting interno que evalúa reglas y las manda a Alertmanager, que las enruta a Slack, email, PagerDuty, etc.

sudo mkdir -p /etc/prometheus/rules
sudo tee /etc/prometheus/rules/host.yml > /dev/null << 'EOF'
groups:
  - name: host_alerts
    rules:
      - alert: HostOutOfInodes
        expr: (node_filesystem_files_free{mountpoint="/"} / node_filesystem_files{mountpoint="/"}) * 100 < 10
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Inodos casi llenos en {{ $labels.instance }}"
          description: "Quedan menos de 10% de inodos libres en / durante 5 minutos"
      - alert: HostDiskWillFillIn24h
        expr: predict_linear(node_filesystem_files_free{mountpoint="/"}[6h], 24*3600) < 0
        for: 30m
        labels:
          severity: critical
        annotations:
          summary: "/ se va a llenar en menos de 24h en {{ $labels.instance }}"
      - alert: HostHighLoad
        expr: node_load5 > (count without (cpu, mode) (node_cpu_seconds_total{mode="idle"}) * 0.8)
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Load average alta en {{ $labels.instance }}"
EOF
promtool check rules /etc/prometheus/rules/host.yml
curl -X POST http://localhost:9090/-/reload

Tres alertas cubren los escenarios más comunes: HostOutOfInodes (un sistema de archivos puede tener inodos llenos aunque tenga espacio, típico de servers con muchos archivos pequeños), HostDiskWillFillIn24h (predicción lineal con predict_linear sobre 6 horas de histórico) y HostHighLoad (load average superior al 80% del número de cores). El flag for: 5m significa que la condición debe mantenerse 5 minutos antes de disparar — evita alertas por picos de un segundo.

Para que las alertas lleguen a algún lado necesitas Alertmanager: instalarlo es un servicio adicional que se scrapea con --alertmanager.url=http://localhost:9093 en Prometheus. Configurar el destino (Slack webhook, email SMTP, Telegram bot) se hace en /etc/prometheus/alertmanager.yml.

Retención y límites de almacenamiento

Por defecto Prometheus conserva 15 días de datos (definido en --storage.tsdb.retention.time, fuente: prometheus.io/docs/prometheus/latest/storage/). El mínimo absoluto es 2 horas, útil cuando Prometheus es solo buffer hacia un backend remoto (Thanos, Cortex, Mimir, GreptimeDB).

Para un homelab con un solo host, 30 días + 10 GB de cap es suficiente y cabe en cualquier VPS. Si scrapeas 50+ hosts con alta cardinalidad (labels por container, pod, request_id), 10 GB se llena en días y necesitas subir el cap o mover a almacenamiento remoto.

Tipo de infra Hosts scrapeados Retención sugerida Cap en disco Storage remoto
Homelab / dev local 1-5 15-30 días 10 GB No requerido
Pequeña empresa 10-30 30-90 días 50-100 GB Opcional
Infra mediana 50-200 15-30 días + remote 20 GB local Thanos + S3/MinIO
Infra grande 200-1000+ Solo buffer 10 GB local Cortex / Mimir / VictoriaMetrics

Dos flags complementarios: --storage.tsdb.retention.time (ventana temporal) y --storage.tsdb.retention.size (tamaño máximo en disco). Lo que se cumpla primero gatilla el borrado de bloques viejos. --storage.tsdb.wal-compression reduce el tamaño del Write-Ahead Log en ~50%, recomendado siempre en sistemas con almacenamiento SSD caro.

Troubleshooting común

Target aparece DOWN en Prometheus. El 90% de las veces es firewall (el host donde corre Prometheus no puede alcanzar el puerto del exporter) o DNS (un hostname que no resuelve desde el Prometheus). Diagnóstico: curl -v http://target-host:9100/metrics desde el shell del Prometheus.

El dashboard no muestra datos pero Prometheus sí scrapea. Revisa la zona horaria del panel: Grafana por defecto usa la del browser, Prometheus guarda en UTC. Si ves “datos viejos”, es probable que el rango temporal del panel no cubra la ventana correcta.

Prometheus consume demasiada RAM. Causa típica: cardinalidad alta (cada label única multiplica series). tsdbtool analyze /var/lib/prometheus lista los labels con más valores únicos. Apunta a scrape_configs.relabel_configs para descartar labels ruidosos antes de que entren al TSDB.

node_exporter expone filesystem fills en /proc. Solución: --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)(/|$) como vimos antes. Sin este flag, /proc aparece como filesystem a 100% en el dashboard.

Reload de config vía -/-/reload falla. El endpoint requiere --web.enable-lifecycle en el flag del daemon. Si no está, curl devuelve 403. La otra alternativa es systemctl reload prometheus, que en systemd con Type=simple no funciona — hay que hacer systemctl restart prometheus y perder el buffer en memoria.

Qué añadir cuando esto te quede corto

Cuando tengas varios hosts, un Prometheus único deja de escalar por más que le subas RAM al server. La progresión natural es:

  • 2-10 hosts: Prometheus único con todos los targets scrapeados directamente. Es lo que tienes ahora.
  • 10-50 hosts: Prometheus + push gateway para jobs batch, más recording rules para precomputar aggregates caras.
  • 50-500 hosts: Thanos o Cortex — Prometheus local + almacenamiento de largo plazo en object storage (S3, MinIO). Thanos es open source puro.
  • 500+ hosts: Grafana Mimir (horizontal scale, compresión agresiva) o VictoriaMetrics (drop-in replacement con mejor compresión).

Para alertas más sofisticadas que las que cubre este post, evalúa Alertmanager con silences (silenciar reglas durante mantenimientos programados) e inhibitions (si un host cae, no alertar sobre sus servicios). Para tracing distribuido de aplicaciones, suma OpenTelemetry + Jaeger o Tempo; Prometheus se ocupa de métricas, no de traces.

Resumen

Prometheus + Grafana + node_exporter es el stack mínimo serio de monitoring para un servidor Linux: ~250 MB de RAM entre los tres procesos, install en menos de 15 minutos, y un dashboard visualizable desde el browser. El modelo pull te da una vista única de qué hosts están vivos (up), cuánto recurso consumen, y dispara notificaciones antes de que un problema escale.

Si tu infra sigue creciendo, Thanos y Mimir extienden Prometheus sin reescribir dashboards. Si prefieres un SaaS, Grafana Cloud tiene un free tier de 10K series — útil para empezar sin operar el stack TSDB tú mismo. Pero para aprender y tener control total, el setup de esta guía es el camino.

Preguntas frecuentes

¿Por qué Configura Prometheus y Grafana: Guía DevOps para SysAdmins Linux es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Configura Prometheus y Grafana: Guía?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Configura Prometheus y Grafana: Guía?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Configura Prometheus y Grafana: Guía y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Configura Prometheus y Grafana: Guía?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *