tylertreat / comcast

Simulating shitty network connections so you can build better systems.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Docker container

hugorodrigues opened this issue · comments

commented

Any plans to make this tool work inside a docker container?

I understand that this is a docker issue and not a comcast issue, but i'm curious to know if anyone has already made it happen or if we plan to support docker containers in the future.

There is a fork (https://github.com/docker-in-practice/docker-comcast) that have some patches to make it run under a docker host.

Thanks :)

(disclaimer: i'm terrible at docker)

From discussions from people smarter than me, it appears this wouldn't be useful. Docker containers don't have their own kernel level network interfaces, they are just bridged with the host. So even comcast runs in the docker container, it would be modifying the host's network interfaces.

I think that's what the docker-comcast creator meant here.

I think @paulirish is correct. That said, I accept PRs if there are useful changes folks have. I'm just not doing any active development on this myself at the moment.

@paulirish its definitely possible to control the network inside a docker container.
yes, docker uses the host kernel
but docker actually creates a virtual network interface for each container which given the right permission (--cap-add=NET_ADMIN) can be manipulated with tc like any other interface.

some factors do need to be taken into account like whether the host kernel supports ifb and the kernel capabilities in general, but overall - it works.

Rereading my original comment on the linked issue, it wasn't particularly clear for anyone who hadn't spent a while wading through docker network interface details. So:

  • if you want to use comcast in a container to 'self-configure' a container, you can use comcast as-is since it should 'just work' for configuring the virtual interfaces
  • if you want to use comcast in a container to configure other containers, that's exactly what docker-comcast does

I'm not sure what change would be appropriate to merge into comcast really or I'd have made a PR already - my patch is just some docker-specific code (for container veth peerfinding).

My 'Hmm' in the other issue (and quotes around 'just work') is that generally you want your Docker containers to be small...but if you want to install comcast to self-configure containers, you need to install the dependencies of comcast. And you may also need Docker network privileges (I haven't actually tried so can't confirm). So 'just work' starts sounding a lot like 'works with effort', and you end up giving random containers extra permissions which isn't great. I've mentioned another possible solution at docker-in-practice/docker-comcast#1 (comment)

@aidanhs: I'd be interested.

This maybe should be in a new thread, but it feels related. If I try to setup the following docker image to try out a container regulating itself:

FROM alpine:3.2

RUN apk update && \
  apk add go git ethtool ipfw iptables iproute2 sudo && \
  export GOPATH=$(pwd)/gopath && \
  go get github.com/tylertreat/comcast && \
  ln -s $(pwd)/gopath/bin/comcast /usr/bin/

CMD sh

Built locally and run as: docker run -it --rm --cap-add=NET_ADMIN comcast.

When I then try to use comcast in the container:

$ comcast --device eth0 --target-bw=10 --default-bw=10
$ curl google.com
curl: (6) Couldn't resolve host 'google.com'

It seems the entire network in the container stops working, until comcast is stopped. This is Docker 17.0.6 on OSX. Installing comcast on the host (which is OSX) appears to work just fine. Am I missing something?

@joshzamor I think it will not work if your Docker container is a Linux flavour and you run on OS X. Comcast will try run tc but on the host, and that will not work. If your host is a Linux flavour I think it can work, but maybe you be you need to run modprobe outside the container first.

I'm using this command to affect only the network conditions of one container:

sudo nsenter -t PID -n comcast --latency=2000 --target-port=9200