Skip to content

using docker-tc with kubernetes #7

@TSchellien

Description

@TSchellien

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions