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?
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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With