cAdvisor: métricas de containers Docker

    cAdvisor (Container Advisor) do Google coleta métricas em tempo real de cada container Docker — uso de CPU, memória, rede e I/O de disco. Integrado ao Prometheus, você monitora cada microserviço individualmente: quem está consumindo mais memória? qual container tem CPU throttling?

    Instalar cAdvisor com Docker Compose

    Adicionar cAdvisor ao stack de monitoramento:

    yaml
    # docker-compose.yml:
    services:
      cadvisor:
        image: gcr.io/cadvisor/cadvisor:latest
        container_name: cadvisor
        privileged: true           # necessário para acessar cgroups do host
        devices:
          - /dev/kmsg:/dev/kmsg
        volumes:
          - /:/rootfs:ro
          - /var/run:/var/run:ro
          - /sys:/sys:ro
          - /var/lib/docker:/var/lib/docker:ro
          - /cgroup:/cgroup:ro
        ports:
          - "127.0.0.1:8080:8080"
        restart: unless-stopped
        command:
          - '--housekeeping_interval=10s'   # intervalo de coleta (padrão: 1s — alto!)
          - '--docker_only=true'            # apenas containers Docker (pular VM/bare-metal)
          - '--store_container_labels=false'  # reduzir cardinalidade de labels
    
    # prometheus.yml — adicionar job cAdvisor:
    scrape_configs:
      - job_name: 'cadvisor'
        static_configs:
          - targets: ['cadvisor:8080']
        metric_relabel_configs:
          # Remover métricas de baixo valor para reduzir volume:
          - source_labels: [__name__]
            regex: 'container_(network_tcp_usage_total|tasks_state|cpu_load_average_10s)'
            action: drop

    Métricas do cAdvisor e queries PromQL

    As principais métricas e como consultá-las:

    bash
    # Métricas principais do cAdvisor:
    # container_cpu_usage_seconds_total  → CPU total usada pelo container
    # container_memory_usage_bytes       → Memória RSS do container
    # container_memory_limit_bytes       → Limite de memória configurado
    # container_network_receive_bytes_total  → Bytes recebidos na rede
    # container_network_transmit_bytes_total → Bytes enviados na rede
    # container_fs_reads_bytes_total     → I/O de leitura
    # container_fs_writes_bytes_total    → I/O de escrita
    
    # CPU usage % por container:
    sum by (name) (
      rate(container_cpu_usage_seconds_total{
        image!="",
        name!=""
      }[5m])
    ) * 100
    
    # Memória por container:
    container_memory_usage_bytes{image!="", name!=""}
    / 1024 / 1024  # converter para MB
    
    # % de memória usada em relação ao limite:
    container_memory_usage_bytes{image!="", name!=""}
    /
    container_memory_limit_bytes{image!="", name!=""} * 100
    
    # Network I/O por container (bytes/s):
    rate(container_network_receive_bytes_total{name!=""}[5m])
    
    # CPU throttling % (container limitado por CPU limit):
    rate(container_cpu_throttled_seconds_total{name!=""}[5m])
    / rate(container_cpu_usage_seconds_total{name!=""}[5m]) * 100

    Alertas para containers

    Regras de alerta para containers com alto consumo ou fora do ar:

    yaml
    # alerts/containers.yml:
    groups:
      - name: containers
        rules:
    
          # Container consumindo mais de 90% do limite de memória:
          - alert: ContainerMemoriaAlta
            expr: |
              container_memory_usage_bytes{name!=""}
              / container_memory_limit_bytes{name!=""} * 100 > 90
            for: 5m
            labels:
              severity: warning
            annotations:
              summary: "Container {{ $labels.name }} com memória acima de 90%"
              description: "Uso: {{ $value | printf "%.1f" }}% do limite"
    
          # Container reiniciando com frequência (possível crash loop):
          - alert: ContainerReiniciandoMuito
            expr: |
              increase(container_last_seen{name!=""}[1h]) < -2
            for: 5m
            labels:
              severity: critical
            annotations:
              summary: "Container {{ $labels.name }} reiniciou mais de 2x na última hora"
    
          # Container com CPU throttling alto:
          - alert: ContainerCpuThrottling
            expr: |
              rate(container_cpu_throttled_seconds_total{name!=""}[5m])
              / rate(container_cpu_usage_seconds_total{name!=""}[5m]) * 100 > 50
            for: 10m
            labels:
              severity: warning
            annotations:
              summary: "Container {{ $labels.name }} com CPU throttling acima de 50%"
              description: "Considere aumentar o cpu limit. Throttling atual: {{ $value | printf "%.1f" }}%"

    Dashboard Grafana para containers

    Importar dashboard pronto e criar painéis customizados:

    bash
    # Dashboard da comunidade Grafana para cAdvisor:
    # ID 14282 — Cadvisor exporter (bem detalhado)
    # ID 193   — Docker and system monitoring
    # Importar: Grafana → + → Import → inserir ID
    
    # Painel customizado: Top 5 containers por CPU:
    topk(5,
      sum by (name) (
        rate(container_cpu_usage_seconds_total{
          image!="",
          name!="",
          name!~"cadvisor|prometheus|grafana"
        }[5m])
      ) * 100
    )
    
    # Painel: Total de memória por stack (agrupando por compose project):
    sum by (container_label_com_docker_compose_project) (
      container_memory_usage_bytes{
        container_label_com_docker_compose_project!=""
      }
    ) / 1024 / 1024
    
    # Painel: Containers rodando vs parados:
    count by (name) (container_last_seen{name!=""} > time() - 30)
    
    # Variável de template no Grafana para selecionar container:
    # Label values query: label_values(container_cpu_usage_seconds_total{image!=""}, name)

    Reduzir cardinalidade do cAdvisor

    Controlar volume de métricas para não sobrecarregar o Prometheus:

    yaml
    # cAdvisor gera muitas métricas por padrão — ajustar para reduzir volume:
    
    # docker-compose.yml — flags de otimização:
    command:
      - '--housekeeping_interval=15s'         # coleta a cada 15s (não 1s)
      - '--docker_only=true'                  # apenas Docker (ignorar outros runtimes)
      - '--disable_metrics=accelerator,cpu_topology,disk,memory_numa,tcp,udp,percpu,sched,process,hugetlb,referenced_memory,resctrl,cpuset'
    
    # Manter apenas: cpu, memory, network, diskIO
    # --disable_metrics lista o que desabilitar:
    # accelerator, advtcp, cpu_topology, cpuset, disk, hugetlb
    # memory_numa, process, referenced_memory, resctrl, sched, tcp, udp
    
    # relabel no Prometheus para descartar séries desnecessárias:
    # prometheus.yml:
    metric_relabel_configs:
      # Manter apenas containers reais (não infra do Docker):
      - source_labels: [container_label_com_docker_swarm_service_name]
        regex: '.+'
        action: keep
      # Ou filtrar por nome:
      - source_labels: [name]
        regex: 'minha-api|postgres|redis|nginx'
        action: keep
    
    # Verificar número de séries ativas:
    curl -s 'http://localhost:9090/api/v1/query?query=count({job="cadvisor"})' | jq .

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

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

    Perguntas frequentes