41

I have a physical host machine with Ubuntu 14.04 running on it. It has 100G disk and 100M network bandwidth. I installed Docker and launched 10 containers. I would like to limit each container to a maximum of 10G disk and 10M network bandwidth.

After going though the official documents and searching on the Internet, I still can't find a way to allocate specified size disk and network bandwidth to a container.

I think this may not be possible in Docker directly, maybe we need to bypass Docker. Does this means we should use something "underlying", such as LXC or Cgroup? Can anyone give some suggestions?


Edit:

@Mbarthelemy, your suggestion seems to work but I still have some questions about disk:

1) Is it possible to allocate other size (such as 20G, 30G etc) to each container? You said it is hardcoded in Docker so it seems impossible.

2) I use the command below to start the Docker daemon and container:

docker -d -s devicemapper
docker run -i -t training/webapp /bin/bash

then I use df -h to view the disk usage, it gives the following output:

Filesystem                  Size  Used Avail Use% Mounted on
/dev/mapper/docker-longid   9.8G  276M  9.0G   3% /
/dev/mapper/Chris--vg-root   27G  5.5G   20G  22% /etc/hosts

from the above I think the maximum disk a container can use is still larger than 10G, what do you think ?

Daniel Serodio
  • 4,229
  • 5
  • 37
  • 33
Chris.Huang
  • 545
  • 1
  • 4
  • 9

4 Answers4

28

I don't think this is possible right now using Docker default settings. Here's what I would try.

  • About disk usage: You could tell Docker to use the DeviceMapper storage backend instead of AuFS. This way each container would run on a block device (Devicemapper dm-thin target) limited to 10GB (this is a Docker default, luckily enough it matches your requirement!).

    According to this link, it looks like latest versions of Docker now accept advanced storage backend options. Using the devicemapperbackend, you can now change the default container rootfs size option using --storage-opt dm.basesize=20G (that would be applied to any newly created container).

    To change the storage backend: use the --storage-driver=devicemapper Docker option. Note that your previous containers won't be seen by Docker anymore after the change.

  • About network bandwidth : you could tell Docker to use LXC under the hoods : use the -e lxcoption.

    Then, create your containers with a custom LXC directive to put them into a traffic class :

    docker run --lxc-conf="lxc.cgroup.net_cls.classid = 0x00100001" your/image /bin/stuff

    Check the official documentation about how to apply bandwidth limits to this class. I've never tried this myself (my setup uses a custom OpenVswitch bridge and VLANs for networking, so bandwidth limitation is different and somewhat easier), but I think you'll have to create and configure a different class.

Note : the --storage-driver=devicemapperand -e lxcoptions are for the Docker daemon, not for the Docker client you're using when running docker run ........

mbarthelemy
  • 12,465
  • 4
  • 41
  • 43
  • mbarthelemy , I supplement my question about the disk , can you help to look into ? – Chris.Huang Jun 25 '14 at 08:24
  • Your root FS volume is the first one (`|9.8G |276M| 9.0G | 3% |/`). The size is, as expected, 10GB. The other line is a bind-mount. – mbarthelemy Jun 25 '14 at 09:29
  • your suggestion is a good way to limit disk size . But I think there is another approach to implement this . I decide to add another user to specified group in container , then I then limit the disk size of that group by using "Quota" in Linux.About the bandwidth , it is too complex for me ,I am still trying ,maybe will ask you something later. – Chris.Huang Jun 26 '14 at 03:30
  • @mbarthelemy could you please give me some details about how you make OpenVswitch bridge and VLAN work with Docker? I'm very interested in Docker work with SDN. Thanks a lot! – harryz Oct 13 '14 at 07:59
  • I have tried to use `docker daemon --storage-opt dm.basesize=20G`, but it is not working, doesn't limit disc sapce. –  Nov 18 '15 at 08:42
  • 1
    official documentation was changed to `https://www.kernel.org/doc/Documentation/cgroup-v1/net_cls.txt` – Windsooon Oct 24 '16 at 09:44
5

New releases version has --device-read-bps and --device-write-bps.

You can use:

docker run --device-read-bps=/dev/sda:10mb

More info here:

https://blog.docker.com/2016/02/docker-1-10/

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
moylop260
  • 1,288
  • 2
  • 13
  • 20
  • 1
    It should be noted that this is only for block devices. Interface traffic hasn't been added. [4763](https://github.com/docker/docker/issues/4763) is still open – Matt Aug 09 '16 at 02:40
  • Link is out of date – jtlz2 Feb 20 '23 at 10:40
4

If you have access to the containers you can use tc for bandwidth control within them.

eg: in your entry point script you can add: tc qdisc add dev eth0 root tbf rate 240kbit burst 300kbit latency 50ms

to have a bandwidth of 240kbps, burst 300kbps and 50 ms latency.

You also need to pass the --cap-add=NET_ADMIN to the docker run command if you are not running the containers as root.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
Vijay47
  • 337
  • 5
  • 13
0

1) Is it possible to allocate other size (such as 20G, 30G etc) to each container? You said it is hardcoded in Docker so it seems impossible.

to answer this question please refer to Resizing Docker containers with the Device Mapper plugin

toolchainX
  • 1,998
  • 3
  • 27
  • 43