Node Exporter: métricas de sistema com Prometheus

    Node Exporter é o agente do Prometheus para métricas do sistema operacional — CPU, memória, disco, rede, filesystems e dezenas de outras. Roda como daemon leve no servidor e expõe um endpoint /metrics que o Prometheus coleta a cada 15 segundos. É o ponto de partida para monitoramento de qualquer VPS Linux.

    Instalar Node Exporter como serviço systemd

    Instalação direta no host (não em container) para métricas mais precisas:

    bash
    # Baixar a versão mais recente do Node Exporter:
    NODE_EXPORTER_VERSION="1.8.2"
    wget "https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz"
    tar xf "node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz"
    sudo cp "node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter" /usr/local/bin/
    sudo chmod +x /usr/local/bin/node_exporter
    
    # Criar usuário dedicado (sem shell, sem home):
    sudo useradd -rs /bin/false node_exporter
    
    # Criar serviço systemd:
    sudo tee /etc/systemd/system/node_exporter.service << 'EOF'
    [Unit]
    Description=Prometheus Node Exporter
    After=network.target
    
    [Service]
    User=node_exporter
    Group=node_exporter
    Type=simple
    ExecStart=/usr/local/bin/node_exporter   --web.listen-address=127.0.0.1:9100   --collector.filesystem.mount-points-exclude='^/(sys|proc|dev|host|etc)($|/)'   --collector.systemd   --collector.processes
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    sudo systemctl daemon-reload
    sudo systemctl enable --now node_exporter
    
    # Verificar que está respondendo:
    curl -s http://127.0.0.1:9100/metrics | head -20

    Configurar scrape no Prometheus

    Adicionar Node Exporter ao prometheus.yml:

    yaml
    # prometheus.yml — adicionar job do Node Exporter:
    scrape_configs:
      - job_name: 'node'
        static_configs:
          - targets:
              - 'localhost:9100'     # mesmo servidor do Prometheus
              - '10.0.0.2:9100'     # outros servidores (IPs internos)
              - '10.0.0.3:9100'
        relabel_configs:
          # Usar hostname como label instance:
          - source_labels: [__address__]
            target_label: instance
            regex: '([^:]+)(?::\d+)?'
    
      # Para múltiplos servidores com descoberta por arquivo:
      - job_name: 'node-file-sd'
        file_sd_configs:
          - files:
              - '/etc/prometheus/targets/*.yml'
            refresh_interval: 1m
    
    # /etc/prometheus/targets/servers.yml:
    # - targets: ['10.0.0.2:9100', '10.0.0.3:9100']
    #   labels:
    #     env: production
    #     datacenter: sp01
    
    # Recarregar Prometheus após mudança:
    curl -X POST http://localhost:9090/-/reload

    Alertas de sistema com Node Exporter

    Regras de alerta para CPU, memória e disco cheio:

    yaml
    # alerts/sistema.yml:
    groups:
      - name: sistema
        rules:
    
          # CPU alta por mais de 5 minutos:
          - alert: CpuUsageAlta
            expr: |
              100 - (avg by (instance) (
                rate(node_cpu_seconds_total{mode="idle"}[5m])
              ) * 100) > 85
            for: 5m
            labels:
              severity: warning
            annotations:
              summary: "CPU acima de 85% em {{ $labels.instance }}"
              description: "Uso atual: {{ $value | printf "%.1f" }}%"
    
          # Memória livre abaixo de 10%:
          - alert: MemoriaLivreBaixa
            expr: |
              (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100) < 10
            for: 5m
            labels:
              severity: critical
            annotations:
              summary: "Memória livre abaixo de 10% em {{ $labels.instance }}"
              description: "Livre: {{ $value | printf "%.1f" }}%"
    
          # Disco quase cheio (aviso aos 80%, crítico aos 90%):
          - alert: DiscoQuaseCheioCritico
            expr: |
              (
                node_filesystem_size_bytes{mountpoint="/", fstype!="tmpfs"}
                - node_filesystem_free_bytes{mountpoint="/", fstype!="tmpfs"}
              ) / node_filesystem_size_bytes{mountpoint="/", fstype!="tmpfs"} * 100 > 90
            for: 1m
            labels:
              severity: critical
            annotations:
              summary: "Disco acima de 90% em {{ $labels.instance }}"
    
          # Servidor não responde (sem métricas):
          - alert: ServidorForaDoAr
            expr: up{job="node"} == 0
            for: 2m
            labels:
              severity: critical
            annotations:
              summary: "Servidor {{ $labels.instance }} inacessível"

    Coletar métricas de serviços systemd

    Monitorar status de serviços com o collector systemd:

    yaml
    # O flag --collector.systemd habilita métricas de serviços systemd.
    # Métricas disponíveis:
    # node_systemd_unit_state{name="nginx.service", state="active"} 1
    # node_systemd_unit_state{name="postgresql.service", state="failed"} 1
    
    # Alertas para serviços críticos fora do ar:
    # alerts/servicos.yml:
    groups:
      - name: servicos-systemd
        rules:
          - alert: ServicoFalhou
            expr: |
              node_systemd_unit_state{
                name=~"nginx.service|postgresql.service|node-api.service|redis.service",
                state="failed"
              } == 1
            for: 1m
            labels:
              severity: critical
            annotations:
              summary: "Serviço {{ $labels.name }} falhou em {{ $labels.instance }}"
    
          - alert: ServicoParado
            expr: |
              node_systemd_unit_state{
                name=~"nginx.service|postgresql.service",
                state="active"
              } == 0
            for: 2m
            labels:
              severity: critical
            annotations:
              summary: "Serviço {{ $labels.name }} não está ativo"
    
    # Verificar métricas do systemd:
    curl -s http://localhost:9100/metrics | grep node_systemd_unit_state | grep -v "^#"

    Node Exporter via Docker Compose

    Usar Node Exporter em container (com acesso ao host via volumes):

    yaml
    # docker-compose.yml — Node Exporter em container com acesso ao host:
    services:
      node-exporter:
        image: prom/node-exporter:latest
        container_name: node-exporter
        pid: host          # necessário para métricas de processo do host
        network_mode: host # usar rede do host para latência mínima
        volumes:
          - /proc:/host/proc:ro
          - /sys:/host/sys:ro
          - /:/rootfs:ro
        command:
          - '--path.procfs=/host/proc'
          - '--path.rootfs=/rootfs'
          - '--path.sysfs=/host/sys'
          - '--web.listen-address=127.0.0.1:9100'
          - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($|/)'
        restart: unless-stopped
    
    # ATENÇÃO: com network_mode: host, o container usa a rede do host diretamente.
    # O port não precisa ser mapeado — já está em localhost:9100
    
    # Verificar que coleta métricas do host (não do container):
    docker exec node-exporter wget -qO- http://127.0.0.1:9100/metrics |   grep node_memory_MemTotal_bytes

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o VPS Linux em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes