This guide provides a complete Ansible playbook to install cAdvisor using the official Google Docker image with proper configuration for container resource monitoring and metrics export.
Current cAdvisor version: 0.49.1 (Docker image)
Create a file named cadvisor.yml:
---
- name: Install and Configure cAdvisor
hosts: cadvisor
become: true
vars:
cadvisor_version: "v0.49.1"
cadvisor_port: 8080
cadvisor_data_dir: "/opt/cadvisor/data"
tasks:
- name: Create cAdvisor directories
file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: '0755'
loop:
- "{{ cadvisor_data_dir }}"
- name: Create Docker Compose file
copy:
dest: "{{ cadvisor_data_dir }}/docker-compose.yml"
owner: root
group: root
mode: '0644'
content: |
version: '3.8'
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:{{ cadvisor_version }}
container_name: cadvisor
restart: unless-stopped
ports:
- "{{ cadvisor_port }}:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
devices:
- /dev/kmsg
privileged: true
expose:
- 8080
environment:
- CADVISOR_ENABLE_PROMETHEUS=true
command:
- -housekeeping_interval=30s
- -docker_only=true
- -prometheus_endpoint=/metrics
- -port=8080
- name: Start cAdvisor container
community.docker.docker_compose:
project_src: "{{ cadvisor_data_dir }}"
state: present
build: false
pull: true
- name: Wait for cAdvisor to start
wait_for:
port: "{{ cadvisor_port }}"
delay: 5
timeout: 120
- name: Configure firewall (UFW)
ufw:
rule: allow
port: "{{ cadvisor_port }}"
proto: tcp
comment: "cAdvisor metrics"
when: ansible_os_family == "Debian"
failed_when: false
- name: Configure firewall (firewalld)
firewalld:
port: "{{ cadvisor_port }}/tcp"
permanent: true
immediate: true
state: enabled
when: ansible_os_family == "RedHat"
failed_when: false
- name: Verify cAdvisor is running
uri:
url: "http://localhost:{{ cadvisor_port }}/healthz"
method: GET
status_code: 200
register: health_check
retries: 3
delay: 5
until: health_check.status == 200
- name: Verify Prometheus metrics endpoint
uri:
url: "http://localhost:{{ cadvisor_port }}/metrics"
method: GET
status_code: 200
register: metrics_check
changed_when: false
failed_when: false
- name: Display cAdvisor status
debug:
msg: |
cAdvisor {{ cadvisor_version }} installed successfully!
Web Interface: http://{{ ansible_default_ipv4.address | default(ansible_host) }}:{{ cadvisor_port }}
Prometheus Metrics: http://{{ ansible_default_ipv4.address | default(ansible_host) }}:{{ cadvisor_port }}/metrics
Data directory: {{ cadvisor_data_dir }}
---
cadvisor:
hosts:
cadvisor-server:
ansible_host: 192.168.1.114
ansible_user: ansible
ansible_become: true
# Test connectivity
ansible all -i inventory.yml -m ping
# Run the cAdvisor playbook
ansible-playbook -i inventory.yml cadvisor.yml
# Check container status
ssh cadvisor-server "docker ps | grep cadvisor"
# View container logs
ssh cadvisor-server "docker logs cadvisor"
# Test health endpoint
curl http://cadvisor-server:8080/healthz
# Test metrics endpoint
curl http://cadvisor-server:8080/metrics | head -20
# Access web UI
# http://cadvisor-server:8080
- name: Configure cAdvisor for production
hosts: cadvisor
become: true
vars:
cadvisor_data_dir: "/opt/cadvisor/data"
cadvisor_port: 8080
tasks:
- name: Update Docker Compose for production
copy:
dest: "{{ cadvisor_data_dir }}/docker-compose.yml"
owner: root
group: root
mode: '0644'
content: |
version: '3.8'
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.49.1
container_name: cadvisor
restart: unless-stopped
ports:
- "127.0.0.1:{{ cadvisor_port }}:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
devices:
- /dev/kmsg
privileged: true
command:
- -housekeeping_interval=30s
- -docker_only=true
- -prometheus_endpoint=/metrics
- -port=8080
- -store_container_labels=false
- -whitelisted_container_labels=io.kubernetes.pod.name,io.kubernetes.pod.namespace,io.kubernetes.container.name
- -disable_metrics=advtcp,cpu_topology,cpuset,hugetlb,memory_numa,process,referenced_memory,resctrl,sched,tcp,udp
- name: Restart cAdvisor
community.docker.docker_compose:
project_src: "{{ cadvisor_data_dir }}"
state: present
restarted: true
- name: Add cAdvisor to Prometheus configuration
hosts: prometheus
become: true
vars:
cadvisor_servers:
- "cadvisor-server-1:8080"
- "cadvisor-server-2:8080"
tasks:
- name: Add cAdvisor scrape config
blockinfile:
path: /etc/prometheus/prometheus.yml
marker: "# {mark} CADVISOR CONFIG"
block: |
- job_name: 'cadvisor'
static_configs:
- targets:
{% for server in cadvisor_servers %}
- {{ server }}
{% endfor %}
metrics_path: /metrics
scrape_interval: 30s
- name: Reload Prometheus
systemd:
name: prometheus
state: reloaded
- name: Import cAdvisor Grafana dashboard
hosts: grafana
become: true
tasks:
- name: Download cAdvisor dashboard
get_url:
url: https://grafana.com/api/dashboards/14282/revisions/latest/download
dest: /etc/grafana/dashboards/cadvisor.json
owner: grafana
group: grafana
mode: '0640'
failed_when: false
- name: Restart Grafana
systemd:
name: grafana-server
state: restarted
- name: Configure cAdvisor to monitor specific containers
hosts: cadvisor
become: true
vars:
cadvisor_data_dir: "/opt/cadvisor/data"
container_prefix: "myapp"
tasks:
- name: Update Docker Compose with container filter
copy:
dest: "{{ cadvisor_data_dir }}/docker-compose.yml"
owner: root
group: root
mode: '0644'
content: |
version: '3.8'
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.49.1
container_name: cadvisor
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
devices:
- /dev/kmsg
privileged: true
command:
- -housekeeping_interval=30s
- -docker_only=true
- -port=8080
- -docker_env_metadata_whitelist=^CONTAINER_.*
- -container_env_metadata_whitelist=^CONTAINER_.*
- name: Restart cAdvisor
community.docker.docker_compose:
project_src: "{{ cadvisor_data_dir }}"
state: present
restarted: true
- name: Backup cAdvisor configuration
hosts: cadvisor
become: true
vars:
cadvisor_data_dir: "/opt/cadvisor/data"
backup_dir: "/backup/cadvisor"
tasks:
- name: Create backup directory
file:
path: "{{ backup_dir }}"
state: directory
mode: '0755'
- name: Backup Docker Compose file
copy:
src: "{{ cadvisor_data_dir }}/docker-compose.yml"
dest: "{{ backup_dir }}/docker-compose-{{ ansible_date_time.date }}.yml"
remote_src: true
- name: Clean up old backups (keep 7 days)
find:
paths: "{{ backup_dir }}"
patterns: "*.yml"
age: 7d
register: old_backups
- name: Remove old backups
file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_backups.files }}"
# Check container logs
docker logs cadvisor
# Check container status
docker ps -a | grep cadvisor
# Check permissions
ls -la /var/lib/docker/
# Check if Docker socket is accessible
docker exec cadvisor ls -la /var/run/docker.sock
# Test metrics endpoint
curl http://localhost:8080/metrics | head -50
# Check Docker containers
docker exec cadvisor curl -s http://localhost:8080/containers
# Reduce housekeeping interval
# Edit docker-compose.yml: -housekeeping_interval=60s
# Disable unnecessary metrics
# Add: -disable_metrics=advtcp,cpu_topology,cpuset
# Restart container
docker-compose -f /opt/cadvisor/data/docker-compose.yml restart
# Check device permissions
ls -la /dev/kmsg
# Verify privileged mode
docker inspect cadvisor | grep Privileged
# Restart with correct permissions
docker-compose -f /opt/cadvisor/data/docker-compose.yml up -d
We develop tailored automation solutions for:
Let’s discuss your requirements: office@linux-server-admin.com | Contact