Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rate-limit upload from docker container?

I need to prevent a long-running multiterabyte upload from eating all of my network's bandwidth, but I can only constrain its bandwidth usage on a process level (meaning that slowing down the whole machine's network interface or slowing down this user's network traffic won't work). Fortunately, the upload is containerized with Docker. What can I do to slow down the docker container's outbound traffic?

like image 907
Christopher Waldon Avatar asked Nov 04 '16 18:11

Christopher Waldon


People also ask

How do I find my Docker pull rate limit?

Pull rates limits are based on individual IP address. For anonymous users, the rate limit is set to 100 pulls per 6 hours per IP address. For authenticated users, it is 200 pulls per 6 hour period. Users with a paid Docker subscription get up to 5000 pulls per day.

What is leverage caching in Docker?

Leverage build cache As each instruction is examined, Docker looks for an existing image in its cache that it can reuse, rather than creating a new (duplicate) image. If you do not want to use the cache at all, you can use the --no-cache=true option on the docker build command.


1 Answers

Thanks to this question I realized that you can run tc qdisc add dev eth0 root tbf rate 1mbit latency 50ms burst 10000 within a container to set its upload speed to 1 Megabit/s.

Here's an example Dockerfile that demonstrates this by generating a random file and uploading it to /dev/null-as-a-service at an approximate upload speed of 25KB/s:

FROM ubuntu

# install dependencies
RUN apt-get update
RUN apt-get install -y iproute curl

# create a large random file to upload
RUN head -c 2M </dev/urandom > /upload.data

# rate-limit the network interface and
# upload the data when docker image is run
RUN echo "#!/bin/bash" >> /upload.sh
RUN echo "tc qdisc add dev eth0 root tbf rate 25kbps latency 50ms burst 2500" >> /upload.sh
RUN echo "curl -d @/upload.data http://devnull-as-a-service.com/dev/null" >> /upload.sh
RUN chmod a+x /upload.sh

ENTRYPOINT exec /upload.sh

Assuming that you have this Dockerfile inside of a directory called ratelimit that is in your current working directory, you can run it with:

docker build ratelimit -t ratelimit && docker run --cap-add=NET_ADMIN ratelimit

The option --cap-add=NET_ADMIN gives the container permission to modify its network interface. You can find the documentation here.

The Dockerfile first installs the dependencies that it needs. iproute provides the tc tool, and curl allows us to make the request that we rate-limit. After installing our dependencies, we generate a 2MB random file to upload. The next section builds a script file that will configure the rate-limit and start an upload. Finally, we specify that script as the action to take when the container is run.

This container adds a Token Bucket Filter to the network interface to slow down the connection to 25KB/s. The documentation of the options provided to the Token Bucker Filter can be found here.

This Dockerfile could be modified to perform any other network task by removing the call to cURL and performing the upload in its place (after installing whatever tools the upload requires, of course).

like image 142
Christopher Waldon Avatar answered Oct 26 '22 23:10

Christopher Waldon