Archive for March, 2015

Tutorial: Setting up a Docker Swarm on Your Laptop Using VirtualBox

This tutorial shows you one method you can use to test out Docker Swarm on a single physical machine, like your laptop. We’ll create 3 VMs: two Swarm worker nodes and one Swarm manager.

Setting Up VMs with NAT Network

First, create three VirtualBox VMs, each with 1gb RAM and 1 CPU. Set up each one with Bridged Networking, meaning that your Linksys/Airport/whatever router will assign them each an IP on the same subnet.

In this example, I’ll use three Ubuntu machines with the hostnames below, plus static DHCP in the router to force them to always have the same IPs:

DockerManager = 10.0.0.100 (runs swarm manager, doesn’t run any containers)
DockerNode1 = 10.0.1.101 (first worker node, runs containers)
DockerNode2 = 10.0.1.102 (second worker node, runs containers)

Alternate method: if you don’t want your VMs to be exposed directly on your LAN, you can use “internal networking” in VirtualBox. This will put all three VMs on the same virtual LAN within your laptop. Turn it on by doing this on the host:

$ VBoxManage natnetwork add -t nat-int-network -n “192.168.15.0/24” -e
$ VBoxManage natnetwork start -t nat-int-network

Then change networking in each VM to use “NAT Network” and select new option “nat-int-network”

Now reboot the VMs. Each should have a unique IP of the form: 192.168.15.xxx

ping one machine from the other. Or test like this:
nc -l 192.168.15.4 12345 (one machine A)
echo “bananas” | nc 192.168.15.4 12345 (on machine B)

Basic Installs On Each Machine

You’ll need to install Docker on each machine. I won’t cover that here. Afterward, do this:

docker pull swarm

to retrieve the Swarm container, which is the same container for both the Swarm nodes and the master.

The container, by the way, just contains a single Go binary called swarm. If you re-build the binary, you can just run it directly without docker building it into a new container. I won’t cover that more advanced scenario here, though.

Running Swarm

On any machine, do this one-time operation:

docker run --rm swarm create
# gives back some token like 372cd183a188848c3d5ef0e6f4d7a963

On DockerNode1, start the Docker daemon bound to 0.0.0.0:2375:

sudo stop docker
sudo docker -d -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
(leave daemon running and open a new terminal tab)
docker -H tcp://10.0.1.101:2375 run -d --name node1 swarm join --addr=10.0.1.101:2375 token://372cd183a188848c3d5ef0e6f4d7a963
docker -H tcp://10.0.1.101:2375 ps
# now you see agent running on DockerNode1

Note: if you do `export DOCKER_HOST=tcp://10.0.1.101:2375` you can omit the “-H tcp://…” part.

On DockerNode2, follow the same procedure as on DockerNode1 above, except the join command will look like this:

docker -H tcp://10.0.1.102:2375 run -d --name node1 swarm join --addr=10.0.1.102:2375 token://372cd183a188848c3d5ef0e6f4d7a963

Now you can list the nodes from any machine. For instance, from DockerManager you could do:

docker run --rm swarm list token://372cd183a188848c3d5ef0e6f4d7a963

If you have built your own swarm binary, you can also use it to list the nodes without a container:

./swarm list token://372cd183a188848c3d5ef0e6f4d7a963

Now start the swarm manager. On DockerManager:

docker run -d -p 3375:2375 swarm manage token://372cd183a188848c3d5ef0e6f4d7a963

Υοu can now do commands like this on ANY machine:

docker -H tcp://10.0.1.100:3375 info
docker -H tcp://10.0.1.100:3375 run -it --rm ubuntu bash
docker -H tcp://10.0.1.100:3375 run -it --rm ubuntu bash
docker -H tcp://10.0.1.100:3375 run -it --rm ubuntu bash
docker -H tcp://10.0.1.100:3375 run -it --rm ubuntu bash
[...repeat as many times as you like...]

Now go back to DockerNode1 and try:

docker -H tcp://10.0.1.101:2375 ps

And this on Docker2:

docker -H tcp://10.0.1.102:2375 ps

You can see different bash processes being allocated to the two machines.

Leave a Comment