Exercise 1.4 - CGroups

Return to Workshop

cgroups

CGroups

The Device Cgroup is primary in isolating and limiting containers to their own shares of CPU, memory, disk I/O, network, etc., other wise it will be denied.

Memory Limits

Docker uses Cgroups to control and limit the amount of system resources a container can use. This will help to protect a system runing from potential application memory leaks or Denial of Service DoS attacks that can consume all available memory and take down a system. By running containers with special docker flags we can restrict the amount of memory a container is able to consume even when a application is trying to consume more memory.

sudo docker run -d --name fedora1 fedora sleep 15m

We can check using the docker stats command and see that this instance fedora1 has no memory limits placed on it.

sudo docker stats --no-stream fedora1
CONTAINER           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O
fedora1             0.00%               2.601 MB / 1.927 GB   0.13%               648 B / 648 B       2.81 MB / 0 B

Now we can place a memory limit on this second container fedora2 with the docker flag --memory.

sudo docker run -d --name fedora2 --memory 150m fedora sleep 15m

Now lets check again using the docker stats command to see the memory restrictions it has placed on this new container.

sudo docker stats --no-stream fedora1 fedora2
CONTAINER           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O
fedora1             0.00%               2.601 MB / 1.927 GB   0.13%               1.296 kB / 648 B    2.81 MB / 0 B
fedora2             0.00%               2.597 MB / 157.3 MB   1.65%               648 B / 648 B       2.81 MB / 0 B

Now you know how to restrict the amount of memory a container is able to use.

Clean Up

Lets clean up for the next exercise.

Kill all running containers

sudo docker kill $(sudo docker ps -q)

Delete exited containers

sudo docker rm $(sudo docker ps -aqf status=exited)

Make sure everything is cleared out.

sudo docker ps -a

CPU Limits

By default, each container’s access to the host machine’s CPU cycles is unlimited. Various constraints can be set to limit a given container’s access to the host machine’s CPU cycles. Docker provides several flags for setting limits on how many shares of a processor a container is able to use. Previously we looked at memory restrictions and setting a maximum ceiling for memory usage, CPU limits are set by shares. We can define share weights for each container and slit the available shares between the containers for a single processor.

Lets run a container with 512 limit of CPU shares.

sudo docker run -d --name fedora1 --cpuset-cpus 0 --cpu-shares 512 dkuffner/docker-stress --cpu 10

Now lets see how many shares this container is using.

sudo docker stats --no-stream fedora1
CONTAINER           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O
fedora1             99.66%              3.088 MB / 1.927 GB   0.16%               648 B / 648 B       3.077 MB / 0 B

CPU shares are defined as a value between 0-1024, however when idle the container will use all available shares until another process needs to use the existing shares. Let’s run a example where another container needs to run and we divide up the shares equally.

sudo docker run -d --name fedora2 --cpuset-cpus 0 --cpu-shares 512 dkuffner/docker-stress --cpu 10

Now lets see how the processor shares get divided between the two.

sudo docker stats --no-stream fedora1 fedora2
CONTAINER           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O
fedora1             49.56%              3.092 MB / 1.927 GB   0.16%               1.296 kB / 648 B    3.06 MB / 0 B
fedora2             49.91%              3.088 MB / 1.927 GB   0.16%               648 B / 648 B       3.06 MB / 0 B

Now you know how to control the amount of CPU shares a container is able to use.

Clean Up

Lets clean up for the next exercise.

Kill all running containers

sudo docker kill $(sudo docker ps -q)

Delete exited containers

sudo docker rm $(sudo docker ps -aqf status=exited)

Make sure everything is cleared out.

sudo docker ps -a

Return to Workshop