network-programmingdockervirtualizationbridge

how to connect Docker containers without a bridge?


I'm having some experiments to do with Docker container technology.

I need for a specific reason to connect two veth container interfaces together without using a bridge, Docker creates a bridge by default, so I do not want to use it.

I'm confused and want to know if it is right to do that way. Anyone can give advices and point me out some links or methods ? I will appreciate.

Thank you so much.

+--------------+     +--------------+
|              |     |              |
| Container X  |     | Container Y  |
|              |     |              |
+--------------+     +--------------+
       ^ veth               ^ veth    
       |                    |
       +--------------------+

Solution

  • Sure, it's possible, although you won't be able to get Docker to do it for you automatically. Begin by creating your two containers with no networking:

    # docker run --net=none --name container_x ...
    # docker run --net=none --name container_y ...
    

    Now create a veth pair:

    # ip link add c_x_eth0 type veth peer name c_y_eth0
    

    Assign each side of the veth pair to a container. You will need to know the PID of the container to do this, which you can get with, for example:

    docker inspect --format '{{.State.Pid}}' container_x
    

    I'm going to assume you've stuck this in a shell script named docker-pid. Set the name space on the first veth link:

    # ip link set netns $(docker-pid container_x) dev c_x_eth0
    

    And on the second:

    # ip link set netns $(docker-pid container_y) dev c_y_eth0
    

    Now you will need to configure the link inside each container. If you haven't started your containers with --privileged, you will need to do this using nsenter:

    # nsenter -t $(docker-pid container_x) -n ip link set c_x_eth0 up
    # nsenter -t $(docker-pid container_y) -n ip link set c_y_eth0 up
    

    And then assign them ip addresses:

    # nsenter -t $(docker-pid container_x) -n ip addr add 10.10.10.1/24 dev c_x_eth0
    # nsenter -t $(docker-pid container_y) -n ip addr add 10.10.10.2/24 dev c_y_eth0
    

    And you should be all set.

    Update

    If nsenter is unavailable...

    The easiest solution really is just to install nsenter on your system; if you are able to create new veth interfaces and start Docker containers you should have all the privileges you need.

    You could accomplish the above without nsenter if you run your containers in privileged mode (docker run --privileged...). This will allow your containers to do things -- such as run network configuration commands -- that are normally prohibited. In this case, you would just run the ip link and ip addr commands in the container, either from a shell you started with docker run or using something like docker exec. You should be aware that running a container in privileged mode removes many of the restrictions normally placed on containers, and so it is not something you want to do if anyone else has access to those containers.