How to rate-limit upload from docker container?

2019-03-26 04:59发布

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?

1条回答
Ridiculous、
2楼-- · 2019-03-26 05:27

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).

查看更多
登录 后发表回答