Resources in devices and infrastructure is limited and always valuable, some of them could be
- File size
- Disk space
- Network usage
- Disk I/O utilization
- Network I/O utilization
- Processes amount
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 www.linuxatemyram.com 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.
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