What does docker mean when it says "Memory limited without swap"

Docker

Docker Problem Overview


I'm getting a warning when I run docker:

> WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.

I'm trying to work out what this means, particularly the phrase "Memory limited without swap."

Does this mean that the container can use more memory than you would normally allow it by using the swap space of the host machine? Or does it mean that the container can't use the swap space, even when the host runs out of memory completely? Is it caused by having no swap space configured? Is it irrelevant if you aren't using swap anyway?

Note: I'm not interested in how to fix it - there are lots of results about that on google. I'm interested in what it means, and why it matters.

Docker Solutions


Solution 1 - Docker

Here's what I found.

Swap isn't used by default. You can check this on Ubuntu/Debian containers at /sys/fs/cgroup/memory/memory.stat. Check the swap value, you'll see it's set to 0 (bytes). No swap usage.

You can enable and limit swap usage with the --memory and --memory-swap flags typically, and here's where this WARNING seems like it would get you. From Docker's documentation regarding a very similar warning:

> If you don’t need these capabilities, you can ignore the warning. You can enable these capabilities on Ubuntu or Debian by following these instructions.

tl;dr: swap is disabled by default. If the cgroup is disabled or container swap limits are otherwise compromised like this warning indicates, you won't be able to set those limits.

Solution 2 - Docker

Docker daemon relies on the following virtual files to implement memory and swap limits:

/sys/fs/cgroup/memory/memory.limit_in_bytes
/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes

If your kernel does not support swap memory limit, the second file won't be there, and docker run won't impose any limitations on the use of the swap space. That way the container is even allowed to use more swap than the -m, --memory setting, as if --memory-swap had been set to -1. Obviously, the container can't use more swap space than you have configured on your system.

However, the warning message is also trying to say that option -m, --memory will still take effect, and the maximum amount of user memory (including file cache) will be set as intended.


The mentioned cgroup mount point may differ, consult /proc/self/mounts.

Solution 3 - Docker

For above issue, Docker installation on Ubuntu 16.04 we not be capable of setting limits. This is because cgroups swapping is disabled by default.

When attempting to set limits you will be given the following error.

>root@ubuntuserver:# docker container run -d -ti --hostname testcontainer -- name testubuntu2 --restart=always --memory="50m" --memory-swap=0 --cpus="0.5" ubuntu:16.04 WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. 1fb75aba88e61cf4ca7c96fdd6db939b474d80c0d923233bcb176bf81224dc44 root@ubuntuserver:#

In order resolve the above issue, update the grub file with below entry:

root@ubuntuserver:~# cat /etc/default/grub |grep GRUB_CMDLINE_LINUX
GRUB_CMDLINE_LINUX_DEFAULT="maybe-ubiquity"
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"

Now update-grub:

root@ubuntuserver:~# update-grub
Sourcing file `/etc/default/grub'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.15.0-74-generic
Found initrd image: /boot/initrd.img-4.15.0-74-generic
done
root@ubuntuserver:~#

Reboot machine once has done and create container with memory limit:

root@ubuntuserver:~# docker container run -d -ti --hostname testcontainer -- 
name testubuntu2 --restart=always --memory="50m" --memory-swap=0 --cpus="0.5" 
ubuntu:16.04
93969354be0445f3458999259747d82231b4084728c3ccf8801dc89be8aadaa3
root@ubuntuserver:~#

Solution 4 - Docker

I found the solution for Docker is the following:

On your docker build machine, create a sysctl.conf file with the following entry:

vm.nr_hugepages=128 

(128 is what I chose, you can change accordingly)

Next in your Dockerfile - add the following into the process.

COPY /folderlocation/sysctl.conf /etc/sysctl.conf

This will copy the sysctl file into the correct directory in the docker image.

This worked for my docker XMRig solution.

Solution 5 - Docker

One impact of fixing this warning is stated in the docker post-install documentation: > Memory and swap accounting incur an overhead of about 1% of the total available memory and a 10% overall performance degradation, even if Docker is not running.

> If you don’t need these capabilities, you can ignore the warning.

This answer states > cgroup swap limit is important if you are using swap and want to enforce memory limit that includes both memory and swap.

That sounds to me like the warning means that a container could still use "unlimited" amounts of memory. Once it reaches the imposed --memory= limit, it starts swapping to swap space. And if that is full, it stops. But by "fixing" this warning, we would also be able to give it limited swap space.
That would be useful in the case where we need to guarantee available swap space to other programs as well.

Solution 6 - Docker

If you're not using swap, and are just concerned about RAM limits, I can confirm that on ubuntu 18.04, processes within a container will be killed off once its specified memory limit is reached, even without the kernel settings.

In my test where I exec'd into the container alongside its normal processes and ran something memory-intensive, just the large process was killed off: I was expecting the whole container to be restarted. This was in docker swarm using resource limits set in the compose file.

I don't know whether cgroup_enable=memory would make this better in some way... Perhaps it would cause the combined memory of all processes in the container to be monitored as a group more efficiently?

Solution 7 - Docker

It may be because you used the -m flag here:

docker build \
  --build-arg commit_datavana="$commit_sha" \
  --build-arg CACHE_BUST="$(date)" \
  -m 8g \     # hurrrr
  -t "$name_tag" .

maybe remove the -m flag if it's not needed

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrjmunroView Question on Stackoverflow
Solution 1 - DockerbluescoresView Answer on Stackoverflow
Solution 2 - DockerdarwView Answer on Stackoverflow
Solution 3 - Dockersudhams reddyView Answer on Stackoverflow
Solution 4 - DockerShawn StreifView Answer on Stackoverflow
Solution 5 - DockerlucidbrotView Answer on Stackoverflow
Solution 6 - DockerQuentin Stafford-FraserView Answer on Stackoverflow
Solution 7 - Dockeruser11810894View Answer on Stackoverflow