Monitor the workload of Docker containers and simulate their workload with docker stats

A web server running in a container can hold a limited load of requests. In this article, we simulate an increase in load and follow the load on the container Docker.

For that, we first create a container Docker nginx which display a web page, the default one quite simply.

Then, we create a second container Docker based on ApacheBench which allows to simulate requests to a website.

And finally, we follow the impact of these requests on the nginx container thanks to the docker stats command.

Then the command docker stats allows to display statistics on a container. We display the help:

docker stats --help

The output:

Usage:	docker stats [OPTIONS] [CONTAINER...]Display a live stream of container(s) resource usage statisticsOptions:
-a, --all Show all containers (default shows just running)
--format string Pretty-print images using a Go template
--no-stream Disable streaming stats and only pull the first result
--no-trunc Do not truncate output

We see that to use it, just type docker stats then the identifier or the name of one or more Docker containers. Now, we are going to create the container nginx, which allows to run a website. So we do a docker run to create the container which we name nginx, which we run in the background and to which we map port 80, so on which turns nginx in the container, to host port 8080.

docker run --name nginx -d -p 8080:80 nginx

The output:

Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
98bc0356: Pulling fs layer
60073b6f: Pulling fs layer
Digest: sha256:b2d89d0a210398b4d1120b3e3a7672c16a4ba09c2c4a0395f18b9f7999b768f2
Status: Downloaded newer image for nginx:latest
2fb028513a879f7f6a558d1ee0fef652ed80dac5f5718333be739d3ce04befc7

We check that the container is up, that it turns.

docker ps -a

The output:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
2fb028513a87 nginx "nginx -g 'daemon of…" 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp nginx

There, he’s been up for five seconds. We now check that the website in the container responds well, that it displays the default page of nginx, therefore Welcome to nginx:

curl 127.0.0.1:8080

The output:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

So now we’re going to do a first exercise. We display the statistics of the container nginx to find out a little what it displays:

docker stats nginx

The output:

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
2fb028513a87 nginx 0.00% 1.844MiB / 1.952GiB 0.09% 1.46kB / 1.27kB 0B / 0B 2

So in fact docker stats display an array of lines, and on each line there is a container. So there, we specified a single container, nginx, so there is a single line.

  • The first two columns actually correspond to the identifier and the name of the container.
  • CPU%: it is the percentage of CPU resources used.
  • MEM USAGE: it is the amount of RAM used.
  • MEM LIMIT: it is the consumption limit of the RAM.
  • MEM%: it is the percentage of RAM that the container is allowed to use.
  • NET I/O: it is the total incoming and outgoing bandwidth of the container.

These statistics are updated in real time. Since it has no activity on the web server, the values do not change.

So, we are going to exit by pressing this Ctrl + C.

Now we are going to create a container sending a million requests to the monitored container, so nginx, using ApacheBench (https://httpd.apache.org/docs/2.2/programs/ab.html). For that, we simply type the command docker run. We name this container ab for ApacheBench. We are going to run it in background and we are going to link it to the nginx container. Then, we specify the name of the image.

Then, we launch the ab command for ApacheBench. We simply ask it to activate keep alive HTTP. So with the -k argument. We tell him the number of requests, so a million. And we are going to ask him to launch five requests at the same time. And then the address of the web server, of the website. It's important to put a / at the end. And nginx actually be automatically translated by Docker to link to the container with the same name. And that is thanks to the attribute, to the argument which is --link=nginx, that we used. So we launch the command.

docker run \
-d \
--name=ab \
--link=nginx \
russmckendrick/ab ab -k -n 100000 -c 5 http://nginx/

The output:

Unable to find image 'russmckendrick/ab:latest' locally
latest: Pulling from russmckendrick/ab
ade4980c: Pulling fs layer
62d62214: Pulling fs layer
1651be00: Pulling fs layer
Digest: sha256:7a6591c92a8dfa4a7adf836b3859ddf7606cfddbff47e2701f6ab8c403734945
Status: Downloaded newer image for russmckendrick/ab:latest
99d5526b69194f92ce25143d7ff463eeaf88b52bc50418fcca6c97959e7cb001

We immediately launch docker stats on the nginx and ab containers:

docker stats nginx ab

The output:

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
2fb028513a87 nginx 80.62% 1.973MiB / 1.952GiB 0.10% 10.8MB / 46.1MB 0B / 0B 2
99d5526b6919 ab 74.90% 2.258MiB / 1.952GiB 0.11% 45.8MB / 10.8MB 0B / 0B 1

We see that the statistics are changing. With the docker stats command, we can therefore ensure that no docker container is overloaded, and with the image of ApacheBench, we can simulate an increase in load on a web server.

You can see all that in action in video in my Youtube channel.

More articles on my blog http://www.DevOpsTestLab.com.

My DevOpsTestLab Youtube channel.

My LinkedIn profile: https://fr.linkedin.com/in/brunodelb

Written by

Interests in the full lifecycle: design, Agile Coaching, development, testing, DevOps, Cloud, Management 3.0, ITIL. It defines me.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store