Skip to content

Instantly share code, notes, and snippets.

@dreamcat4
Created June 27, 2016 15:01
Show Gist options
  • Save dreamcat4/bc202ae175b367bcbe693da7a52851af to your computer and use it in GitHub Desktop.
Save dreamcat4/bc202ae175b367bcbe693da7a52851af to your computer and use it in GitHub Desktop.

There is a better and official driver now. See other answer on this page: http://stackoverflow.com/a/36470828/287510

Note:

This particular solution uses default bridge driver... It has an issue which is not simple to work around. There may be better ways now / soon.

This answer expands on Jerome's Bridge Driver solution. Main differences:

  • Assumes only 1 NIC on your computer, not 2 of them
  • Configure the external bridging to be persistent across reboots

Possible issue:

  • External bridging may break legacy docker0 bridge interfaces for WAN connectivity. Which in turn breaks the cmd docker build. The matter is under investigation over here.
  • Please comment @dreamcat4 if you did not experience a similar breakage of docker0 interface or docker build. Would like to know what I did wrong.

Steps as follows:

1. Set parameters

These parameters are determined by your router / LAN networking configuration:

_router_ip="192.168.1.1"
_lan_subnet_mask="16" # or 24, typically
_lan_subnet="192.168.0.0/$_lan_subnet_mask"
_nic_interface="eth0" # what we are bridging to

These parameters you may choose yourself:

_docker_bridge_ip="192.168.1.33" # this replaces eth0 on LAN
_docker_bridge_name="br0"
_docker_dns_tld="dkr"
_docker_network_name="$_docker_dns_tld" # AFAIK these 2 attributes cannot be set independantly

2. Configure bridge

We must make our external bridging persistent across system reboots. The actualy method will vary between different linux distros.

  • Shown here is the method for Ubuntu and Debian computers
  • We will modify the file /etc/network/interfaces to create the external bridging for us at boot time

a) DHCP method:

My /etc/network/interfaces file:

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback


# eth0 - disable automatic networking configuration
auto eth0
iface eth0 inet manual


# added for docker network bridge
auto br0
iface br0 inet dhcp
  hwaddress ether 01:02:03:04:05:06
  bridge_ports eth0

The essential line above is bridge_ports eth0. Certain other parameters are significant too. Above is the minimum configuration. This above config relies upon your LAN router's DHCP to read the hw MAC Address we set, and dole out a new UP address for the new bridge. Which you can configure your LAN router to do by either static or dynamic DHCP. Whichever you prefer.

Now eth0 essentially becomes unconfigured. As we specifically instructed to do nothing above, it just passes all packets to our new br0 bridge, which takes on the role of what eth0 was (plus more now).

b) Manual method:

If you didn't want to use DHCP method, you can input bridge networking parameters manually. Just its considerably more messy with lots more paramters to get right. And does not seem to work as well as the DHCP way (ie more flakey / buggy).

cat /etc/network/interfaces (manual method):

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback


# eth0 - disable automatic networking configuration
auto eth0
iface eth0 inet manual


# added for docker network bridge
auto br0
iface br0 inet static
  hwaddress ether 02:42:c0:a8:03:21
  address 192.168.1.33
  gateway 192.168.1.1
  netmask 255.255.0.0
  bridge_ports eth0
  up ifconfig eth0 up
  up brctl addif br0 eth0
  up route add default br0
  # dns-nameservers 192.168.1.1 # doesnt seem to work for br* interfaces

For example if DNS doesnt work on host by manual method. Some ubuntu bug probably. The workaround: manually add lines to resolv.conf instead, the recommended way is:

  echo "nameserver 192.168.1.1" >> /etc/resolvconf/resolv.conf.d/base

Pah. Dont like.

3. Reboot host computer

Reboot to check changes are persistent. Check the network connectivity to be certain that the host networking still works acceptably / OK now that the new external bridging is in place. Your new bridge br0 should have taken on the role of eth0 now.

To check that our new bridge is linked to eth0:

brctl show

and also try reaching google.com / whatever else:

ping -c1 google.com
route
ifconfig -a

4. Create docker network

Check that docker daemon service has also started up correctly and is still functioning OK as it was before:

service docker status

Notice:

At this point, the legacy docker0 bridge should still work. It was for me. However the next step will break WAN connectivity of the docker0 legacy bridge. Which we are probably not interested in, except that it in turn also breaks docker build cmd. Tracking issue on docker/docker. The problem remains under investigatation.

Create a new custom docker network, with same bridge parameters as our br0 external bridge:

docker network create --subnet $_lan_subnet \
  --aux-address "DefaultGatewayIPv4=$_router_ip" \
  --gateway=$_docker_bridge_ip \
  -o com.docker.network.bridge.name=$_docker_bridge_name \
    $_docker_network_name

Create a test container

docker run --rm -it --net $_docker_network_name --ip 192.168.55.55 nginx

Test new container works

ping -c1 192.168.55.55 && curl 192.168.55.55
  • for me it was a success! On docker-engine v1.10.3, ubuntu wily 15.10 host.

How to reverse all changes:

# Stop all running containers
docker stop $(docker ps -q)

# Remove our custom docker network
docker network rm $_docker_network_name

Then remove those extra lines we added to /etc/network/interfaces file. And reboot the host computer. Everything should be back to normal. Just barring any containers we modified to use the new docker run flags --net= and --ip- for our external bridge network.

Note 1:

Unlike Jerome's solution, we do not perform his step 3. and delete the bridge ip address. Because it is needed to setup new default route, to restore the host's WAN connection. Assuming we are connecting the bridge to our computer's primary NIC / only physical NIC. This would infer that Jerome's answer assumes a dual-NIC computer. Whereby 1 NIC is dedicated to docker, the other to the host machine. And both NICs are simultaneously connected to the same LAN subnet / physical network.

Note 2:

It also seem possible to get DNS resolution of containers on LAN too. Have done it now, at: https://hub.docker.com/r/dreamcat4/dockerdns/

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