cAdvisor (Container Advisor) is a container monitoring tool that provides resource usage and performance data for containers. As a tool with access to container internals and Docker daemon, cAdvisor requires careful security configuration to prevent information disclosure and unauthorized access. This guide covers security measures for production cAdvisor deployments.
cAdvisor architecture includes these security-sensitive components:
Key security concerns include Docker socket access, web UI exposure, API security, container information disclosure, and host system access.
Configure firewall rules for cAdvisor:
# cAdvisor web UI and API (default port 8080)
ufw allow from 10.0.0.0/8 to any port 8080 proto tcp
ufw allow from 10.0.0.0/8 to any port 8443 proto tcp # HTTPS
# Prometheus metrics (if using separate port)
ufw allow from 10.0.1.0/24 to any port 8080 proto tcp
# Block external access
ufw deny from any to any port 8080 proto tcp
ufw deny from any to any port 8443 proto tcp
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: cadvisor-network-policy
spec:
podSelector:
matchLabels:
app: cadvisor
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
- podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 8080
Configure cAdvisor binding:
# Run cAdvisor with specific binding
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--volume=/dev/disk/:/dev/disk:ro \
--publish=127.0.0.1:8080:8080 \
--detach=true \
--name=cadvisor \
gcr.io/cadvisor/cadvisor:latest \
--housekeeping_interval=30s \
--max_housekeeping_interval=60s
For Kubernetes DaemonSet:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: cadvisor
spec:
template:
spec:
containers:
- name: cadvisor
image: gcr.io/cadvisor/cadvisor:latest
args:
- --housekeeping_interval=30s
- --max_housekeeping_interval=60s
ports:
- containerPort: 8080
hostPort: 8080
hostIP: 127.0.0.1 # Bind to localhost
Configure authentication via reverse proxy:
Nginx with Basic Auth:
location / {
auth_basic "cAdvisor Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Nginx with OAuth2:
location / {
auth_request /oauth2/auth;
error_page 401 =200 /oauth2/start;
proxy_pass http://localhost:8080;
}
Configure RBAC for cAdvisor in Kubernetes:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cadvisor
rules:
- apiGroups: [""]
resources: ["pods", "nodes", "nodes/stats"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cadvisor
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cadvisor
subjects:
- kind: ServiceAccount
name: cadvisor
namespace: monitoring
Restrict API access:
# cAdvisor doesn't have built-in authentication
# Use reverse proxy or network policies
# Limit API endpoints via reverse proxy
location /api/ {
auth_basic "API Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:8080;
}
# Allow metrics endpoint without auth for Prometheus
location /metrics {
allow 10.0.1.0/24;
deny all;
proxy_pass http://localhost:8080;
}
Secure service account in Kubernetes:
apiVersion: v1
kind: ServiceAccount
metadata:
name: cadvisor
namespace: monitoring
automountServiceAccountToken: false
---
# Create separate token for Prometheus scraping
apiVersion: v1
kind: Secret
metadata:
name: cadvisor-prometheus
namespace: monitoring
annotations:
kubernetes.io/service-account.name: cadvisor
type: kubernetes.io/service-account-token
Configure TLS via reverse proxy:
# /etc/nginx/sites-available/cadvisor
server {
listen 443 ssl http2;
server_name cadvisor.company.com;
ssl_certificate /etc/nginx/certs/cadvisor.crt;
ssl_certificate_key /etc/nginx/certs/cadvisor.key;
ssl_trusted_certificate /etc/nginx/certs/ca-bundle.crt;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
location / {
auth_basic "cAdvisor Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Metrics endpoint for Prometheus
location /metrics {
allow 10.0.1.0/24;
deny all;
proxy_pass http://localhost:8080;
}
}
Some cAdvisor builds support native TLS:
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--publish=127.0.0.1:8443:8443 \
gcr.io/cadvisor/cadvisor:latest \
--tls_cert_file=/etc/ssl/certs/cadvisor.crt \
--tls_key_file=/etc/ssl/private/cadvisor.key
Secure Prometheus scraping:
# Prometheus scrape config
scrape_configs:
- job_name: 'cadvisor'
scheme: https
tls_config:
ca_file: /etc/prometheus/certs/ca.crt
cert_file: /etc/prometheus/certs/client.crt
key_file: /etc/prometheus/certs/client.key
insecure_skip_verify: false
static_configs:
- targets: ['cadvisor.monitoring:8443']
Secure Docker socket access:
# Never mount Docker socket without restrictions
# Use Docker socket proxy instead
# Run socket proxy
docker run -d \
--name docker-socket-proxy \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e CONTAINERS=1 \
-e INFO=1 \
-e SYSTEM=1 \
tecnativa/docker-socket-proxy
# Mount proxy socket in cAdvisor
docker run \
--volume=$(pwd)/docker.sock:/var/run/docker.sock:ro \
gcr.io/cadvisor/cadvisor:latest
Limit cAdvisor’s container access:
# Run cAdvisor with read-only root filesystem
docker run \
--read-only \
--tmpfs /tmp \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=127.0.0.1:8080:8080 \
gcr.io/cadvisor/cadvisor:latest
Restrict API endpoint access:
| Endpoint | Risk Level | Access Control |
|---|---|---|
/metrics |
Low | Prometheus only |
/api/v1/containers |
Medium | Authenticated |
/api/v1/subcontainers |
Medium | Authenticated |
/api/v1/machine |
Medium | Authenticated |
/api/v1/version |
Low | Public |
/containers/ |
High | Admin only |
Configure via reverse proxy:
# Allow metrics for Prometheus
location /metrics {
allow 10.0.1.0/24;
deny all;
proxy_pass http://localhost:8080;
}
# Require auth for API
location /api/ {
auth_basic "API Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:8080;
}
# Require auth for web UI
location /containers/ {
auth_basic "cAdvisor Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:8080;
}
Limit exposed information:
# Disable machine info if not needed
docker run \
gcr.io/cadvisor/cadvisor:latest \
--disable_metrics=percpu,sched,hugetlb,referenced_memory,resctrl
Prevent sensitive data exposure:
# Disable sensitive metrics
docker run \
gcr.io/cadvisor/cadvisor:latest \
--disable_metrics=process,cpuLoad,referenced_memory
Secure cAdvisor logs:
# Configure log driver
docker run \
--log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
gcr.io/cadvisor/cadvisor:latest
Run cAdvisor securely:
# Kubernetes security context
securityContext:
runAsNonRoot: false # cAdvisor needs root for some metrics
runAsUser: 0
capabilities:
add:
- SYS_ADMIN # Required for some metrics
readOnlyRootFilesystem: true
Set resource limits:
# Kubernetes resource limits
resources:
requests:
cpu: 100m
memory: 200Mi
limits:
cpu: 500m
memory: 500Mi
Enable logging:
docker run \
gcr.io/cadvisor/cadvisor:latest \
--logtostderr \
--v=2 # Log level
Configure reverse proxy access logging:
# /etc/nginx/sites-available/cadvisor
access_log /var/log/nginx/cadvisor_access.log combined;
error_log /var/log/nginx/cadvisor_error.log warn;
Monitor cAdvisor for security events:
# Prometheus alerting rules
groups:
- name: cadvisor-security
rules:
- alert: CAdvisorHighRequestRate
expr: rate(container_network_receive_bytes_total[5m]) > 100000000
for: 5m
labels:
severity: warning
annotations:
summary: "High network traffic from cAdvisor"
- alert: CAdvisorContainerRestart
expr: changes(container_last_seen[1h]) > 5
for: 5m
labels:
severity: warning
annotations:
summary: "cAdvisor container restarting frequently"
Forward logs to SIEM:
# Configure Fluentd or similar for log forwarding
# Example Fluentd config for cAdvisor logs
<match cadvisor.**>
@type forward
<server>
host siem.company.com
port 24224
</server>
</match>