Skip to content

Add container option to tc to apply docker container-level traffic control#331

Open
mininny wants to merge 2 commits intoethpandaops:masterfrom
mininny:feat/mininny/tc-to-container
Open

Add container option to tc to apply docker container-level traffic control#331
mininny wants to merge 2 commits intoethpandaops:masterfrom
mininny:feat/mininny/tc-to-container

Conversation

@mininny
Copy link
Contributor

@mininny mininny commented Mar 21, 2025

This change allows the traffic-control setup to apply changes to a specific container:

  1. Linking the Container’s Network Namespace:
    The script retrieves the container’s PID using docker inspect and then creates a symbolic link (in /var/run/netns/) that points to the container’s network namespace. This allows us to run network commands inside the container’s namespace via ip netns exec.

  2. Conditional Creation of a Virtual Interface:
    I've noticed that in the original script, if the helper interface (here, ifbeth0) already exists in the container’s network namespace, it errors. So I added a check to make sure it doesn't exist before adding the interface.

This option can be enabled like:

 traffic_control_rules:
  - interface: eth0
    container: beacon
    rate_upload: 10mbit
    rate_download: 10mbit
    latency: 100ms

I've tested the setup locally and verified that the tc is applied to the specific container

@skylenet skylenet self-requested a review March 21, 2025 12:51
@skylenet
Copy link
Member

This is nice. Thanks @mininny !

But there's a problem if we recreate containers, which would require the script to be rerun due to changing PIDs.

@mininny
Copy link
Contributor Author

mininny commented Mar 21, 2025

This is nice. Thanks @mininny !

But there's a problem if we recreate containers, which would require the script to be rerun due to changing PIDs.

@skylenet Thank you! Yea, that is a problem...

I looked up some things, and it seems like docker offers system events, so we could use that in the script like this:

docker events --filter 'event=start' --filter 'container=container' | while read event; do
    echo "Detected start event for container"
    container_pid=$(docker inspect -f '{{.State.Pid}}' container)
    rm -f /var/run/netns/container_ns
    ln -sfT /proc/$container_pid/ns/net /var/run/netns/container_ns
    echo "Updated network namespace for container"
done &

Since we're running the script in systemd, stopping the systemd will also stop this event process.
What do you think about this approach?

@skylenet
Copy link
Member

I looked up some things, and it seems like docker offers system events, so we could use that in the script like this:

docker events --filter 'event=start' --filter 'container=container' | while read event; do
    echo "Detected start event for container"
    container_pid=$(docker inspect -f '{{.State.Pid}}' container)
    rm -f /var/run/netns/container_ns
    ln -sfT /proc/$container_pid/ns/net /var/run/netns/container_ns
    echo "Updated network namespace for container"
done &

Since we're running the script in systemd, stopping the systemd will also stop this event process. What do you think about this approach?

I think this could work. But we have to make sure that we resubscribe to the event stream if the connection is dropped for whatever reason. (e.g. docker engine restart)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants