Docker - Create a Bridge and Shared Network
Sometimes I want to use Docker containers like regular VMs, creating a bridge on a Docker host, having containers on the same subnet, and then logging into them via port 22. (No port forwarding, please.) So here's how to do it.
On this example, I use Vagrant and VirtualBox on my MacBook and create containers with IP addresses shown on the table below. Once you go through these steps, you should be able to extend the idea into your on-premises network.
|Host | IP Address |
|:-------------------|:---------------|
| MacBook | 192.168.33.1 |
| host1(VirtualBox) | 192.168.33.10 |
| container1 | 192.168.33.11 |
| container2 | 192.168.33.12 |
| container3 | 192.168.33.13 |
Prerequisites
This example is done with these:
- Mac OS X 10.11.4
- VirtualBox v5.0.16
- Vagrant v1.8.1
- Docker Toolbox v1.10.3
Creating a Vagrantfile
You may want to go with docker-machine create -d virtualbox <hostname>
, but it is important to change the network Adapter Type
in order to make the network bridge work. It is easy on Vagrantfile
to do that, which looks like this:
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.hostname = "host1"
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.provider "virtualbox" do |v|
v.memory = "2048"
# Change the network adapter type and promiscuous mode
v.customize ['modifyvm', :id, '--nictype1', 'Am79C973']
v.customize ['modifyvm', :id, '--nicpromisc1', 'allow-all']
v.customize ['modifyvm', :id, '--nictype2', 'Am79C973']
v.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all']
end
# Install bridge-utils
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get -y install bridge-utils
SHELL
end
Creating a Docker machine
# Create a VM
$ vagrant up
# Setup the VM as your Docker machine
$ docker-machine create \
--driver "generic" \
--generic-ip-address 192.168.33.10 \
--generic-ssh-user vagrant \
--generic-ssh-key .vagrant/machines/default/virtualbox/private_key \
--generic-ssh-port 22 \
host1
Creating a bridge docker1
and shared network shared_nw
# Log in to the VM
$ vagrant ssh
# Delete the IP address from eth1
$ sudo ip addr del 192.168.33.10/24 dev eth1
# Create "shared_nw" with a bridge name "docker1"
$ sudo docker network create \
--driver bridge \
--subnet=192.168.33.0/24 \
--gateway=192.168.33.10 \
--opt "com.docker.network.bridge.name"="docker1" \
shared_nw
# Add docker1 to eth1
$ sudo brctl addif docker1 eth1
Note: You may want to use
docker-machine ssh host1
to log in to host1, but you need to usevagrant ssh
instead, because 192.168.33.10 will be once deleted in the process.
Running Containers
Go back to your MacBook, and launch containers:
$ eval $(docker-machine env host1) # Setup the environment
$ docker run --name container1 --net shared_nw --ip 192.168.33.11 -dt ubuntu
$ docker run --name container2 --net shared_nw --ip 192.168.33.12 -dt ubuntu
$ docker run --name container3 --net shared_nw --ip 192.168.33.13 -dt ubuntu
And now you should be able to reach the container's IP addresses:
$ ping -c 3 192.168.33.11
$ ping -c 3 192.168.33.12
$ ping -c 3 192.168.33.13
Making the network setting permanent
At this point, the network bridge will be detatched from eth1
if you
reboot the machine. So here are two more things to make the setting
permanent.
Update /etc/network/interfaces
like this:
auto eth1
iface eth1 inet manual
pre-up ifconfig $IFACE up
post-down ifconfig $IFACE down
And add the following command on /etc/rc.local
(before exit 0
):
brctl addif docker1 eth1
Cleaning up
After finishing your test, you can remove the containers and VM:
$ docker stop $(docker ps -aq) # Stop all containers
$ docker rm $(docker ps -aq) # Remove all containers
$ docker-machine rm host1 # Remove host1 from your machine list
$ vagrant destroy # Remove the VM
Where to go next
You may want to try Dockerizing an SSH daemon service.
References
The following links are really helpful to understand Docker's network, and highly recommended.
* Docker - Network Configuration
* Docker - network create
* Odd Bits - Four ways to connect a docker container to a local network
* Github - jpetazzo/pipework
* Stack Overflow - Assign static IP to Docker container
Written by Koji Tanaka
Related protips
1 Response
Hi Koji, Do you have to install docker on the vagrant machine?