Fun with resource limits in docker containers

April 26, 2015
Development Docker Devops

Resources in devices and infrastructure is limited and always valuable, some of them could be

Today we’ll set up to tinker with memory limits and get a new oversight this brave and not-so-new world of containers.


For memory usage we’ll be using a little tool found in that’ll just gobble up memory as possible and then exit.

$ ./eatram.bin
Allocated 1 MB
Allocated 2 MB

Classical linux process limiting

There’s a well known utlity for setting limits in a current shell called ulimit, it allow us to set the maximum resources allowed for programs running under a shell.

It handles two types of limits, soft limits and hard limits (also defined for the pam_limits module usually under /etc/security/limits.conf).

Soft limits should always be limited by the hard limits and are allowed to be raised and lowered by a normal user. Hard limits can be raised only by the root user.

The usage for limiting the virtual memory to 20480KiB

$ (ulimit -v 20480; ./eatram.bin) 

After some playing around we can find the minimal memory required in the current setup to print at least 1MiB of allocated memory, any number under this will stop printing or fail loading necessary libraries (if dynamically linked) or even the shell itself.

$ (ulimit -v 2043; ./eatram.bin) 

So in order to print the aproximated 20480KiB allocated before we would need.

$ (ulimit -v 22523; ./eatram.bin)
Allocated 17 MB
Allocated 18 MB
Allocated 19 MB
Allocated 20 MB

This without taking into account the possibility of using linux cgroups directly.

Docker limiting container memory

Building our test image

In order to play around with docker memory limits we’ll need to create a image wrapping our test binary.

FROM scratch
ADD eatram.bin /
CMD ["/eatram.bin"]

Building our image

$ docker build -t eatram_exp .

Running a container

Now time to run our test with some memory limits

$ docker run -it -m 64m --memory-swap=80m  eatram_exp
WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.

As we can see there’s something odd, in Archlinux default kernel 3.19.3-3 x86_64 and probably in most distributions swap limitations aren’t by default (which seems to be enabled from GRUB command line).

Yet it seems to finish very close to our 64MiB limits

Allocated 61 MB
Allocated 62 MB
Allocated 63 MB

After enabling our kernel to manage swap through cgroups adding to our grub command line.

cgroup_enable=memory swapaccount=1

We run again our test and get exactly the results we were looking for

docker run -it -m 260m --memory-swap=1500m  eatram_exp
Allocated 1491 MB
Allocated 1492 MB
Allocated 1493 MB
comments powered by Disqus