Giter Site home page Giter Site logo

lukaszlach / docker-tc Goto Github PK

View Code? Open in Web Editor NEW
633.0 7.0 36.0 17 KB

:whale: :vertical_traffic_light: Docker Traffic Control - network rate limiting, emulating delays, losses, duplicates, corrupts and reorders of network packets using only container labels or a command-line interface.

Dockerfile 11.83% Makefile 7.80% Shell 80.37%
docker docker-network traffic-control network-emulation chaos-engineering

docker-tc's Introduction

Docker Traffic Control

Version Docker pulls Docker stars

Docker Traffic Control allows to set a rate limit on the container network and can emulate network conditions like delay, packet loss, duplication, and corrupt for the Docker containers, all that basing only on labels. HTTP API allows to fetch and pause existing rules and to manually overwrite them, command-line interface is also available. Project is written entirely in Bash and is distributed as a Docker image.

Running

First run Docker Traffic Control daemon in Docker. The container needs NET_ADMIN capability and the host network mode to manage network interfaces on the host system, /var/run/docker.sock volume allows to observe Docker events and query container details.

docker run -d \
    --name docker-tc \
    --network host \
    --cap-add NET_ADMIN \
    --restart always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /var/docker-tc:/var/docker-tc \
    lukaszlach/docker-tc

You can also pass HTTP_BIND and HTTP_PORT environment variables, which default to 127.0.0.1:4080.

This repository contains docker-compose.yml file in root directory, you can use it instead of manually running docker run command. Newest version of image will be pulled automatically and the container will run in daemon mode.

git clone https://github.com/lukaszlach/docker-tc.git
cd docker-tc
docker-compose up -d

When using docker-compose.yml configuration is stored in the .env file, also provided in this repository.

Usage

After the daemon is up it scans all running containers and starts listening for container:start events triggered by Docker Engine. When a new container is up (also a new Swarm service) and contains com.docker-tc.enabled label set to 1, Docker Traffic Control starts applying network traffic rules according to the rest of the labels from com.docker-tc namespace it finds.

Docker Traffic Control recognizes the following labels:

  • com.docker-tc.enabled - when set to 1 the container network rules will be set automatically, any other value or if the label is not specified - the container will be ignored
  • com.docker-tc.limit - bandwidth or rate limit for the container, accepts a floating point number, followed by a unit, or a percentage value of the device's speed (e.g. 70.5%). Following units are recognized:
    • bit, kbit, mbit, gbit, tbit
    • bps, kbps, mbps, gbps, tbps
    • to specify in IEC units, replace the SI prefix (k-, m-, g-, t-) with IEC prefix (ki-, mi-, gi- and ti-) respectively
  • com.docker-tc.delay - length of time packets will be delayed, accepts a floating point number followed by an optional unit:
    • s, sec, secs
    • ms, msec, msecs
    • us, usec, usecs or a bare number
  • com.docker-tc.loss - percentage loss probability to the packets outgoing from the chosen network interface
  • com.docker-tc.duplicate - percentage value of network packets to be duplicated before queueing
  • com.docker-tc.corrupt - emulation of random noise introducing an error in a random position for a chosen percent of packets

Read the tc command manual to get detailed information about parameter types and possible values.

Run the busybox container on custom network to create virtual network interface, specify all possible labels and try to ping google.com domain.

docker network create test-net
docker run -it \
	--net test-net \
	--label "com.docker-tc.enabled=1" \
	--label "com.docker-tc.limit=1mbps" \
	--label "com.docker-tc.delay=100ms" \
	--label "com.docker-tc.loss=50%" \
	--label "com.docker-tc.duplicate=50%" \
	--label "com.docker-tc.corrupt=10%" \
	busybox \
	ping google.com

You should see output similar to shown below, ping correctly reports duplicates, packets are delayed and some of them lost.

PING google.com (216.58.215.78): 56 data bytes
64 bytes from 216.58.215.78: seq=0 ttl=54 time=1.010 ms
64 bytes from 216.58.215.78: seq=1 ttl=54 time=101.031 ms
64 bytes from 216.58.215.78: seq=2 ttl=54 time=101.045 ms
64 bytes from 216.58.215.78: seq=3 ttl=54 time=101.011 ms
64 bytes from 216.58.215.78: seq=4 ttl=54 time=101.028 ms
64 bytes from 216.58.215.78: seq=5 ttl=54 time=101.060 ms
64 bytes from 216.58.215.78: seq=5 ttl=54 time=154.685 ms (DUP!)
64 bytes from 216.58.215.78: seq=6 ttl=54 time=101.084 ms
64 bytes from 216.58.215.78: seq=8 ttl=54 time=101.085 ms
64 bytes from 216.58.215.78: seq=8 ttl=54 time=1001.130 ms (DUP!)
64 bytes from 216.58.215.78: seq=11 ttl=54 time=102.218 ms
64 bytes from 216.58.215.78: seq=15 ttl=54 time=114.437 ms
64 bytes from 216.58.215.78: seq=16 ttl=54 time=101.471 ms
64 bytes from 216.58.215.78: seq=17 ttl=54 time=101.068 ms
64 bytes from 216.58.215.78: seq=17 ttl=54 time=1001.162 ms (DUP!)
64 bytes from 216.58.215.78: seq=19 ttl=54 time=101.104 ms
^C
--- google.com ping statistics ---
20 packets transmitted, 13 packets received, 3 duplicates, 35% packet loss
round-trip min/avg/max = 1.010/152.299/1001.162 ms

HTTP API

API available via HTTP allows you to manage network control rules manually on chosen container.

If you have running containers already or do not want to add Docker Traffic Control labels, you can use the POST endpoint to set the rules manually or in an automated process.

HTTP was chosen for local management instead of docker exec so that you can still easily control Docker Traffic Control on Swarm Nodes, utilize any service discovery and manage remotely using any HTTP client.

GET

GET /<container-id|container-name> HTTP/1.1

Get traffic control rules for a single container.

curl localhost:4080/221517ae59d1
curl localhost:4080/my-container-name

LIST

LIST /<container-id|container-name> HTTP/1.1

List all traffic control rules for all running containers.

curl -X LIST localhost:4080

DELETE

DELETE /<container-id|container-name> HTTP/1.1

Delete all container's traffic control rules. Container is also added to the ignore list to prevent further changes whether it has proper labels set or not.

curl -X DELETE localhost:4080/my-container-name

PUT

PUT /<container-id|container-name> HTTP/1.1

Put back the container to the scanning poll and remove it from the ignore list.

curl -X PUT localhost:4080/221517ae59d1

POST

POST /<container-id|container-name> HTTP/1.1
<rate|delay|loss|corrupt|duplicate>=<value>&...

Update container's traffic control rules. Container does not have to have any labels set, it can be any running container. All previous rules for this container are removed.

curl -d'delay=300ms' localhost:4080/my-container-name
curl -d'rate=512kbps' localhost:4080/221517ae59d1
curl -d'rate=1mbps&loss=10%' localhost:4080/my-container-name

Command-line

Set up a command that may be available for all users...

echo 'curl -sSf -X "$1" "localhost:4080/$2?$3"' > /usr/bin/docker-tc
chmod +x /usr/bin/docker-tc

... or set up a local command alias:

alias docker-tc='curl -sSf -X "$1" "localhost:4080/$2?$3"'

Usage

docker-tc get 221517ae59d1
docker-tc list
docker-tc delete my-container-name
docker-tc put 221517ae59d1
docker-tc set my-container-name 'delay=300ms&rate=1000kbps'

Build

git clone https://github.com/lukaszlach/docker-tc.git
cd docker-tc
make
docker images | grep docker-tc

Supported platforms

Docker Traffic Control only works on Linux distributions like Debian, Ubuntu, CentOS or Fedora.

  • MacOS - not supported due to lack of host network mode support
  • Windows - not supported due to separate network stack between Linux and Windows containers

Deploy on Swarm

Warning: Although this project is prepared for Docker Swarm you will not be able to deploy it as a service because of the moby/moby#25885 issue. This section is theoretical.

Create a global service named docker-tc that will scan all containers and other services that are currently running or will start in the future.

docker service create \
    --name docker-tc \
    --mode global \
    --restart-condition any \
    --network host \
    --cap-add NET_ADMIN \
    --mount "type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock" \
    --mount "type=bind,src=/var/docker-tc,dst=/var/docker-tc" \
    lukaszlach/docker-tc

/var/docker-tc directory has to exist on Docker Swarm nodes before deploying the service

Contributors

Licence

MIT License

Copyright (c) 2018-2019 Łukasz Lach [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

docker-tc's People

Contributors

blabdouze avatar lukaszlach avatar silcet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker-tc's Issues

Project Status / Project Transfer

Hello @lukaszlach

Several folks have made comments recently on docker-tc but there hasnt been any activity from you on this repo for several years. Do plan to keep maintaining this project or should be considered abandoned? Would you be interested in transfering it?

Thanks!

not working in docker compose mode

My container is created by docker compose up -d, and i have add labels into docker-compose.yml as follows:

version: "2.3"
services:
  emby:
    image: lovechen/embyserver:latest
    container_name: emby
    network_mode: host
    environment:
      - UID=1000 # The UID to run emby as (default: 2)
      - GID=1000 # The GID to run emby as (default 2)
      - GIDLIST=1000 # A comma-separated list of additional GIDs to run emby as (default: 2)
    volumes:
      - /root/docker/emby/config:/config
      - /root/media/rclone/myAlist:/movie
    deploy:
      labels:
        com.docker-tc.enabled: 1
        com.docker-tc.limit: 100mbps
    restart: unless-stopped

The container id is 356c6968c23e.
However, it does not work, and the log is as follows:

2022/12/13 09:29:32 Thanks for using hapttic v1.0.0
2022/12/13 09:29:32 Listening on 127.0.0.1:4080
2022/12/13 09:29:32 Forwarding requests to /docker-tc/bin/httpd.sh
2022/12/13 09:29:32 Logging errors to stderr
[2022-12-13T09:29:33+00:00] [07aa0054ceab] Notice: Skipping container, no valid labels found
[2022-12-13T09:29:33+00:00] [18758b8daca1] Notice: Skipping container, service was disabled by label
[2022-12-13T09:29:34+00:00] [9f60ccdfcf86] Notice: Skipping container, no valid labels found
[2022-12-13T09:29:34+00:00] [a7981804c7ad] Notice: Skipping container, no valid labels found
[2022-12-13T09:30:29+00:00] [85be2c3272d4] Notice: Skipping container, no valid labels found
[2022-12-13T09:30:38+00:00] [1f9db4f5eb18] Notice: Skipping container, no valid labels found
[2022-12-13T09:30:43+00:00] [f6ae6c0fe610] Notice: Skipping container, no valid labels found
[2022-12-13T09:42:55+00:00] [6a3a1e5a96fe] Notice: Skipping container, no valid labels found
2022/12/13 09:45:25 Executing /docker-tc/bin/httpd.sh
2022/12/13 09:45:40 Executing /docker-tc/bin/httpd.sh
[2022-12-13T09:56:42+00:00] [356c6968c23e] Notice: Skipping container, no valid labels found

docker-tc configures settings on the wrong veth's

For a handson tutorial at a conference (MySQLDays, a FOSDEM Fringe conf, presenting about MySQL InnoDB Cluster/ReplicaSet), I was using docker-tc to simulate network issues.
However, during the class, I found that weird things happened when I tried to network partition a single host. Other hosts seemed to be affected too.

in the examples I have a docker-tc wrapper that contains:

$ curl -sSf -X "$1" "localhost:4080/$2?$3"

Here's the state of the containers before doing anything:

$ docker-tc list
# id=e1b59d438067 name=mysqltutorial_router_3
qdisc noqueue 0: root refcnt 2 
# id=fce32b583115 name=mysqltutorial_router_2
qdisc noqueue 0: root refcnt 2 
# id=0f16b00c62a9 name=mysqltutorial_router_5
qdisc noqueue 0: root refcnt 2 
# id=21bf74c760fd name=mysqltutorial_router_4
qdisc noqueue 0: root refcnt 2 
# id=1b491649ba7f name=mysqltutorial_router_1
qdisc noqueue 0: root refcnt 2 
# id=044954e67ea2 name=mysqltutorial_app_run_1ce5130790c3
qdisc noqueue 0: root refcnt 2 
# id=898e634ecbeb name=mysqltutorial_mysqlsh_run_8882df05c8be
qdisc noqueue 0: root refcnt 2 
# id=acc4be45b9bd name=mysqltutorial_server_1_1
qdisc noqueue 0: root refcnt 2 
# id=765692e6d3cf name=mysqltutorial_server_2_1
qdisc noqueue 0: root refcnt 2 
# id=7cd13e68ff62 name=mysqltutorial_server_3_1
qdisc noqueue 0: root refcnt 2 
qdisc noqueue 0: root refcnt 2 
qdisc noqueue 0: root refcnt 2 
qdisc noqueue 0: root refcnt 2 
qdisc noqueue 0: root refcnt 2 
# id=308522eccfac name=mysqltutorial_registrator_1
qdisc noqueue 0: root refcnt 2 
qdisc noqueue 0: root refcnt 2 
qdisc noqueue 0: root refcnt 2 
# id=1e8d4ce2351e name=docker-tc
# id=582876fe7a4b name=mysqltutorial_consul_1
qdisc noqueue 0: root refcnt 2 

Then I network partition a single container by adding loss=100%:

$ docker-tc post mysqltutorial_server_3_1 loss=100%
Set loss=100% on veth3795593
Controlling traffic of the container /mysqltutorial_server_3_1 on veth3795593
Set loss=100% on veth6015f81
Controlling traffic of the container /mysqltutorial_server_3_1 on veth6015f81
Set loss=100% on vethfeda243
Controlling traffic of the container /mysqltutorial_server_3_1 on vethfeda243
Set loss=100% on vethd9de0b8
Controlling traffic of the container /mysqltutorial_server_3_1 on vethd9de0b8
Set loss=100% on veth23ae4cf
Controlling traffic of the container /mysqltutorial_server_3_1 on veth23ae4cf

When I then look at the configuration, you can see that various other servers now also have loss=100%:

$ docker-tc list
# id=e1b59d438067 name=mysqltutorial_router_3
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
# id=fce32b583115 name=mysqltutorial_router_2
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
# id=0f16b00c62a9 name=mysqltutorial_router_5
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
# id=21bf74c760fd name=mysqltutorial_router_4
qdisc noqueue 0: root refcnt 2 
# id=1b491649ba7f name=mysqltutorial_router_1
qdisc noqueue 0: root refcnt 2 
# id=044954e67ea2 name=mysqltutorial_app_run_1ce5130790c3
qdisc noqueue 0: root refcnt 2 
# id=898e634ecbeb name=mysqltutorial_mysqlsh_run_8882df05c8be
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
# id=acc4be45b9bd name=mysqltutorial_server_1_1
qdisc noqueue 0: root refcnt 2 
# id=765692e6d3cf name=mysqltutorial_server_2_1
qdisc noqueue 0: root refcnt 2 
# id=7cd13e68ff62 name=mysqltutorial_server_3_1
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
# id=308522eccfac name=mysqltutorial_registrator_1
qdisc noqueue 0: root refcnt 2 
qdisc noqueue 0: root refcnt 2 
qdisc netem 1: root refcnt 2 limit 1000 loss 100%
# id=1e8d4ce2351e name=docker-tc
# id=582876fe7a4b name=mysqltutorial_consul_1
qdisc noqueue 0: root refcnt 2 

Bandwidth Limiter does not work

Does this project no longer work with newer versions of docker? I'm trying to use the traffic limiter but it is not working at all even though tc shows it's limiting the bandwidth to what is being set by the label.

How to specify network interface ?

If I have a container with multiple internal networks - how do I specify which interface tc will attach itself to ? the README for the .loss alludes to the capability when it says "...outgoing from the chosen network interface"... so it must be possible - but there is no com.docker-tc. parameter for it.

Docker-tc cannot update network interface after a container restarts

When I run a new container and add the label for limit, the docker-tc can find it and set the limit successfully.

However, after the container restarts, the network interface changes. For example, docker-tc sets limit on vethd104b6f. After restarting my container, it changed to vethffc7586. But docker-tc seems not to realize it, so the limit doesn't work.

MacOS support related??? - Cannot talk to rtnetlink: Operation not supported

OS version: OSx 13.5 (22G74)
Docker version: Docker version 24.0.2, build cb74dfcd85

Tried to run following README example and get this error...

I ran like this:

#start docker-tc container
docker run -d \
    --name docker-tc \
    --network host \
    --cap-add NET_ADMIN \
    --restart always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /var/docker-tc:/var/docker-tc \
    lukaszlach/docker-tc
# run busybox
docker network create test-net
docker run -it \
	--net test-net \
	--label "com.docker-tc.enabled=1" \
	--label "com.docker-tc.limit=1mbps" \
	--label "com.docker-tc.delay=100ms" \
	--label "com.docker-tc.loss=50%" \
	--label "com.docker-tc.duplicate=50%" \
	--label "com.docker-tc.corrupt=10%" \
	busybox \
	ping google.com

Enter in loop with this error:

 ____          _              _____         ___ ___ _        _____         _           _
|    \ ___ ___| |_ ___ ___   |_   _|___ ___|  _|  _|_|___   |     |___ ___| |_ ___ ___| |
|  |  | . |  _| '_| -_|  _|    | | |  _| .'|  _|  _| |  _|  |   --| . |   |  _|  _| . | |
|____/|___|___|_,_|___|_|      |_| |_| |__,|_| |_| |_|___|  |_____|___|_|_|_| |_| |___|_|

Starting Docker Traffic Control 18.12
https://github.com/lukaszlach/docker-tc

2023/08/02 14:20:49 Thanks for using hapttic v1.0.0
2023/08/02 14:20:49 Listening on 127.0.0.1:4080
2023/08/02 14:20:49 Forwarding requests to /docker-tc/bin/httpd.sh
2023/08/02 14:20:49 Logging errors to stderr
[services.d] done.
[2023-08-02T14:20:50+00:00] [b9959fae58fe] Notice: Skipping container, service was disabled by label
[2023-08-02T14:20:59+00:00] [4695a75c5a96] Set delay=100ms, loss=50%, corrupt=10%, duplicate=50% on veth04cba01
Cannot talk to rtnetlink: Operation not supported
 ____          _              _____         ___ ___ _        _____         _           _
|    \ ___ ___| |_ ___ ___   |_   _|___ ___|  _|  _|_|___   |     |___ ___| |_ ___ ___| |
|  |  | . |  _| '_| -_|  _|    | | |  _| .'|  _|  _| |  _|  |   --| . |   |  _|  _| . | |
|____/|___|___|_,_|___|_|      |_| |_| |__,|_| |_| |_|___|  |_____|___|_|_|_| |_| |___|_|

Starting Docker Traffic Control 18.12
https://github.com/lukaszlach/docker-tc

[2023-08-02T14:21:06+00:00] [4695a75c5a96] Set delay=100ms, loss=50%, corrupt=10%, duplicate=50% on veth04cba01
Cannot talk to rtnetlink: Operation not supported

Problem in parameters with Docker-TC

Hello,
I use this work for a project for the University of Klagenfurt in Austria. If I'm coming to you its because I have a problem with it : when I try to change only one parameter, the delay for example, it works but then when I change a second one, the first one is reset. Also when I try to change two parameters in one command, it doesn't works. I send you a screenshot of this, it will be easier to understand I think.
So, I'm asking your help for this, if you have any explications or any ways to solve this.
I remain at your disposal if you need more informations,
Thank you very much.

Valentin Brard

Screenshot

Support for specific ports

Hi, can you add support for tc of specific ports of the containers?
I have a setup where I would like to intercept commucation on just one port, and not all
Thanks so much in adv

using docker-tc with kubernetes

For my master thesis i was looking for a light weight traffic control implementation working with docker container inside a kubernetes cluster. So i was trying to use docker-tc on my kubernetes nodes. First it didn't work properly because it is not possible to setup custom networks for the docker container on the nodes created within kubernetes.
For tc to work as a network traffic controller each docker container needs its own network interface on the host and not especially a custom network. Therefore i changed some code in the httpd-post.sh to look directly for the network interface instead of getting the network interface from the custom docker network:

#!/usr/bin/env bash
. /docker-tc/bin/docker-common.sh
. /docker-tc/bin/http-common.sh
. /docker-tc/bin/tc-common.sh
. /docker-tc/bin/core.sh
CONTAINER_ID=$(http_safe_param "$1")
QUERY="$2"
if ! docker_container_is_running "$CONTAINER_ID"; then
    http_response 400 "$CONTAINER_ID is not running"
fi
CONTAINER_ID=$(docker_container_get_short_id "$CONTAINER_ID")
NETM_OPTIONS=
TBF_OPTIONS=
OPTIONS_LOG=
while read QUERY_PARAM; do
    FIELD=$(echo "$QUERY_PARAM" | cut -d= -f1)
    VALUE=$(echo "$QUERY_PARAM" | cut -d= -f2-)
    FIELD=$(http_safe_param "$FIELD")
    VALUE=$(echo "$VALUE" | sed 's/[^a-zA-Z0-9%-_]//g')
    case "$FIELD" in
        delay|loss|corrupt|duplicate|reorder)
            NETM_OPTIONS+="$FIELD $VALUE "
            ;;
        rate)
            TBF_OPTIONS+="$FIELD $VALUE "
            ;;
        *)
            echo "Error: Invalid field $FIELD"
            exit 1
            ;;
    esac
    OPTIONS_LOG+="$FIELD=$VALUE, "
done < <(echo "$QUERY" | tr '&' $'\n')
if [ -z "$NETM_OPTIONS" ] && [ -z "$TBF_OPTIONS" ]; then
    echo "Notice: Nothing to do"
    exit 0
fi
OPTIONS_LOG=$(echo "$OPTIONS_LOG" | sed 's/[, ]*$//')
CONTAINER_NETWORKS=$(docker_container_get_networks "$CONTAINER_ID")
CONTAINER_NETWORK_INTERFACES=$(docker_container_get_interfaces "$CONTAINER_ID")

while read CONTAINER_NETWORK_INTERFACE; do

    if [ -z "$CONTAINER_NETWORK_INTERFACE" ]; then
        continue
    fi
    tc_init
    qdisc_del "$CONTAINER_NETWORK_INTERFACE"
    if [ ! -z "$NETM_OPTIONS" ]; then
        qdisc_netm "$CONTAINER_NETWORK_INTERFACE" $NETM_OPTIONS
    fi
    if [ ! -z "$TBF_OPTIONS" ]; then
        qdisc_tbf "$CONTAINER_NETWORK_INTERFACE" $TBF_OPTIONS
    fi
    echo "Set ${OPTIONS_LOG} on $CONTAINER_NETWORK_INTERFACE"
    echo "Controlling traffic of the container $(docker_container_get_name "$CONTAINER_ID") on $CONTAINER_NETWORK_INTERFACE"
done < <(echo -e "$CONTAINER_NETWORK_INTERFACES")

#while read NETWORK_ID; do
#    NETWORK_INTERFACE_NAMES=$(docker_container_interfaces_in_network "$CONTAINER_ID" "$NETWORK_ID")
#
#    if [ -z "$NETWORK_INTERFACE_NAMES" ]; then
#        continue
#    fi
#    while IFS= read -r NETWORK_INTERFACE_NAME; do
#        tc_init
#        qdisc_del "$NETWORK_INTERFACE_NAME"
#        if [ ! -z "$NETM_OPTIONS" ]; then
#            qdisc_netm "$NETWORK_INTERFACE_NAME" $NETM_OPTIONS
#        fi
#        if [ ! -z "$TBF_OPTIONS" ]; then
#            qdisc_tbf "$NETWORK_INTERFACE_NAME" $TBF_OPTIONS
#        fi
#        echo "Set ${OPTIONS_LOG} on $NETWORK_INTERFACE_NAME"
#        echo "Controlling traffic of the container $(docker_container_get_name "$CONTAINER_ID") on $NETWORK_INTERFACE_NAME"
#    done < <(echo -e "$NETWORK_INTERFACE_NAMES")
#done < <(echo -e "$CONTAINER_NETWORKS")

block "$CONTAINER_ID"
http_response 200

With this change i was able to use docker-tc's with the web api to act as a traffic controller in my kubernetes cluster. If this is kind a helpful for anyone maybe you can just apply this change.

Docker-tc fails with multiple containers in same network

When a new container is started, docker-tc finds out the network device of the container without any issue and everything works. When a second container is started in the same network, the docker_network_get_interface() function returns both network devices separated by a space. This return value makes any other function that tries to use it fail.
Test with 2 busybox containers pinging google.com:

$ NETWORK_ID=$(docker network inspect --format '{{ .Id }}' "test-net")
$ echo $NETWORK_ID
b8c595e522ccdfbd75be7543eaa214f97603274a79e3f1d86269fb59ddd627c8
$ SHORT_NETWORK_ID=$(echo -n "$NETWORK_ID" | head -c 12)
$ echo $SHORT_NETWORK_ID
b8c595e522cc
$ NETWORK_INTERFACE_NAME=$(ip a | grep -E "veth.*br-$SHORT_NETWORK_ID" | grep -o 'veth[^@]*' || :)
$ echo $NETWORK_INTERFACE_NAME
veth756b15f vethcea04c9

Memory leak in docker-tc.sh

The command "docker events" continues listening for new events every time it is called, spawning a persistent new process in every loop of the main while in docker-tc.sh. After using the container for a while it ends up eating all the RAM of the host computer.

Bandwith limit not working properly

Bandwitch limit is not working as expected, the expirimented limit is much higher than the value I setted via the label. Here some examples:

  • Without limitation, as you can see, we get 10Gbps.
$ docker run -it mlabbe/iperf3     iperf3 -c 172.20.35.249
Connecting to host 172.20.35.249, port 5201
[  5] local 172.17.0.2 port 49944 connected to 172.20.35.249 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  1.28 GBytes  11.0 Gbits/sec   12   3.06 MBytes
[  5]   1.00-2.00   sec  1.20 GBytes  10.3 Gbits/sec    0   3.06 MBytes
[  5]   2.00-3.00   sec  1.29 GBytes  11.1 Gbits/sec    0   3.06 MBytes
[  5]   3.00-4.00   sec  1.33 GBytes  11.4 Gbits/sec    0   3.06 MBytes
[  5]   4.00-5.00   sec  1.33 GBytes  11.4 Gbits/sec    0   3.06 MBytes
[  5]   5.00-6.00   sec  1.27 GBytes  10.9 Gbits/sec    0   3.06 MBytes
[  5]   6.00-7.00   sec  1.19 GBytes  10.2 Gbits/sec    0   3.06 MBytes
[  5]   7.00-8.00   sec  1.13 GBytes  9.68 Gbits/sec    0   3.06 MBytes
[  5]   8.00-9.00   sec  1.02 GBytes  8.75 Gbits/sec    0   3.06 MBytes
[  5]   9.00-10.00  sec   882 MBytes  7.40 Gbits/sec    0   3.06 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  11.9 GBytes  10.2 Gbits/sec   12             sender
[  5]   0.00-10.04  sec  11.9 GBytes  10.2 Gbits/sec                  receiver
  • With the limit setted at 1mbps (which actually means 1 MB/s), we get around 230 Mbps
$ docker network create test5-net
7c5df3e208dd7a1faccc909848292c7bd93d24e6c871858fa10ede948f30c54f
$ docker run -it \
    --net test5-net \
    --label "com.docker-tc.enabled=1" \
    --label "com.docker-tc.limit=1mbps" \
    --label "com.docker-tc.delay=100ms" \
    --label "com.docker-tc.loss=10%" \
    --label "com.docker-tc.duplicate=5%" \
    --label "com.docker-tc.corrupt=1%" \
    mlabbe/iperf3 \
    iperf3 -c 172.20.35.249
Connecting to host 172.20.35.249, port 5201
[  5] local 172.23.0.2 port 37802 connected to 172.20.35.249 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  1.13 GBytes  9.67 Gbits/sec   12   3.10 MBytes
[  5]   1.00-2.00   sec  1.10 GBytes  9.50 Gbits/sec    0   3.10 MBytes
[  5]   2.00-3.00   sec  31.2 MBytes   263 Mbits/sec    1   2.32 MBytes
[  5]   3.00-4.00   sec  23.8 MBytes   199 Mbits/sec    0   2.51 MBytes
[  5]   4.00-5.00   sec  26.2 MBytes   220 Mbits/sec    0   2.67 MBytes
[  5]   5.00-6.00   sec  27.5 MBytes   231 Mbits/sec    0   2.79 MBytes
[  5]   6.00-7.00   sec  27.5 MBytes   231 Mbits/sec    0   2.89 MBytes
[  5]   7.00-8.00   sec  27.5 MBytes   231 Mbits/sec    0   2.96 MBytes
[  5]   8.00-9.00   sec  28.8 MBytes   241 Mbits/sec    0   3.02 MBytes
[  5]   9.00-10.00  sec  30.0 MBytes   252 Mbits/sec    0   3.02 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  2.45 GBytes  2.11 Gbits/sec   13             sender
[  5]   0.00-10.04  sec  2.45 GBytes  2.10 Gbits/sec                  receiver
  • With the limit setted at 256kbps (which actually means 256 MB/s), we get around 230Mbps
$ docker network create test7-net
f91ccaaf402391584ba6afb17dfd1260d91df04f24b76df272c62520a1c520f1
$ docker run -it \
    --net test7-net \
    --label "com.docker-tc.enabled=1" \
    --label "com.docker-tc.limit=256kbps" \
    --label "com.docker-tc.delay=100ms" \
    --label "com.docker-tc.loss=10%" \
    --label "com.docker-tc.duplicate=5%" \
    --label "com.docker-tc.corrupt=1%" \
    mlabbe/iperf3 \
    iperf3 -c 172.20.35.249
Connecting to host 172.20.35.249, port 5201
[  5] local 172.25.0.2 port 49744 connected to 172.20.35.249 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  1.10 GBytes  9.44 Gbits/sec   12   3.02 MBytes
[  5]   1.00-2.00   sec   806 MBytes  6.76 Gbits/sec    1   3.02 MBytes
[  5]   2.00-3.00   sec  28.8 MBytes   241 Mbits/sec    0   3.02 MBytes
[  5]   3.00-4.00   sec  28.8 MBytes   241 Mbits/sec    0   3.02 MBytes
[  5]   4.00-5.00   sec  30.0 MBytes   252 Mbits/sec    0   3.02 MBytes
[  5]   5.00-6.00   sec  27.5 MBytes   231 Mbits/sec    0   3.02 MBytes
[  5]   6.00-7.00   sec  27.5 MBytes   231 Mbits/sec    0   3.02 MBytes
[  5]   7.00-8.00   sec  28.8 MBytes   241 Mbits/sec    0   3.02 MBytes
[  5]   8.00-9.00   sec  30.0 MBytes   252 Mbits/sec    0   3.02 MBytes
[  5]   9.00-10.00  sec  28.8 MBytes   241 Mbits/sec    0   3.02 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  2.11 GBytes  1.81 Gbits/sec   13             sender
[  5]   0.00-10.04  sec  2.11 GBytes  1.80 Gbits/sec                  receiver

Do you know where is the problem? I created a new network for each container, I don't know if that's right. I'm using the docker compose YAML to run docker-tc. I'm using Ubuntu Server 18.04 and Docker 19.03.8.

Thanks,
Xoán

Limiting upload speed

Is there an option to just limit the upload speed then limiting download and upload.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.