In this blog, we are implementing monitoring for Docker containers using Docker images. We will use the following open-source options for the monitoring task:
To keep things simple, we will provide all the necessary tools via docker and only make very few adjustments.
Enable cgroups limit support
First let’s see if docker stats provides us with all information.
On my Rasperry Pi 4 the MEM usage was 0.00% for every container on the docker stats --no-stream
output.
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
234aaa99f2d0 gq-gmc-service_app_1 0.03% 0B / 0B 0.00% 5.32kB / 0B 10.5MB / 0B 1
Append cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1
in the /boot/cmdline.txt
to enable cgroup memory option.
Additionally, the following lines should be added to /etc/docker/daemon.json
.
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
If the file is not empty,these key, making sure that the resulting file is valid JSON. Be careful that every line ends with a comma (,) except for the last line.
Now Docker uses systemd as cgroupdriver.
After a reboot we can see the memory usage of the containers.
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
234aaa99f2d0 gq-gmc-service_app_1 0.02% 12.16MiB / 3.738GiB 0.32% 5.39kB / 0B 10.5MB / 0B 1
Docker container
Now we provide all necessary tools as a docker container using docker-compose.
Therefore we create the file docker-compose.yml
with the following content:
docker-compose.yml
version: '3.7'
services:
prometheus:
image: prom/prometheus
restart: always
ports:
- "9090:9090/tcp"
networks:
- front
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/data:rw
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/data'
- '--storage.tsdb.retention.time=30d'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
exporter:
image: prom/node-exporter
restart: always
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- --collector.filesystem.ignored-mount-points
- "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)"
network_mode: host
cadvisor:
image: zcube/cadvisor
restart: always
privileged: true
devices:
- /dev/kmsg
ports:
- "8080:8080/tcp"
command:
- '--docker_only'
- '--disable_metrics=disk,diskIO,tcp,udp,percpu,sched,process'
- '--housekeeping_interval=10s'
networks:
front:
aliases:
- cadvisor
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
grafana:
image: grafana/grafana
ports:
- "3000:3000/tcp"
networks:
- front
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_AUTH_ANONYMOUS_ENABLED=true
networks:
front:
driver: bridge
volumes:
prometheus_data:
grafana_data:
additionally we create a file prometheus.yml
with the following content in the same folder as the docker-compose.yml
:
prometheus.yml
scrape_configs:
- job_name: 'containeradvisor'
scrape_interval: 5s
static_configs:
- targets: ['X.X.X.X:8080']
- job_name: 'node-exporter'
scrape_interval: 5s
static_configs:
- targets: ['X.X.X.X:9100']
For the targets
please enter your Docker host IP or DNS name.
Now we can start our containers with the following command docker-compose up -d
.
Grafana
Now we can login to Grafana http://<DOCKERIP>:3000
with user User admin
and the passwort admin
.
add data source Prometheus to Grafana. The URL ist the one of oure Prometheus container.
We can now import a dashboard, by entering the ID 12831
or any other ID of one of Grafana’s dashboards provided on the Grafana Dashboard side.
now we have a quick overview of our Docker system load.