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 cmddocker build
. The matter is under investigation over here. - Please comment @dreamcat4 if you did not experience a similar breakage of
docker0
interface ordocker 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 wily15.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/