Creating a Local Docker Swarm with VirtualBox

Docker Swarm is the container orchestration tool built into Docker, and while it isn’t nearly as popular as Kubernetes, it still has a lot going for it. It uses mostly the same syntax as Docker, so you can leverage your existing knowledge. It’s fast, nimble, and can support some pretty hefty workloads.

I like to play (and destroy, and then play some more) and local VMs (virtual machines) with VirtualBox is a good tool for such things. However, getting the networking just right can be a bit of a pain (Google it and you’ll see people asking how-to about internal combined with external networking in VirtualBox for 10+ years!)

To make a Swarm cluster in VirtualBox we’ll need three VMs that a) can talk to each other, b) can be accessed from your local computer, and c) can get to the Internet. (This tutorial assumes you know what VirtualBox is, how to get it, and the basics of how to use it, but if not, check out this article.)

Set up the first VM

I like 2048 for memory, but if your computer has 8GB RAM or less, you’ll need to go with 1024MB.

Take the default of “Create a virtual hard disk now” here:

Again, the default (VirtualBox Disk Image):

Here, I prefer “Fixed size” as “Dynamically allocated,” as the name suggests, expands the usable disk as its needed… and that affects performance.

The thing about the fixed disk, however, is you only have the space that you give it! Since we’re just building these for test purposes, we’re probably not going to need a lot of space; the default of 10GB should be enough, but I went with 20GB for mine just in case:

Now that you’ve created the VM, edit the “Network” settings. The screenshot of “Adapter 1” below is the default, and we’re going to keep it.

We’re also going to use a “Host only” network, and that requires another setup step. In the VirtualBox top menu, select “File,” “Host network manager”:

Create a new “Host only” network like this:

Now you can go back to the “Network” settings for your VirtualBox and add an “Adapter 2” as follows:

What we’ve done here is created a VM with two virtual NICs (Network Interface Cards). The first, NAT (Network Address Translation) lets your VM get to the internet, so you can do handy things like download software and updates. This will be the default interface when we install Ubuntu. The second virtual NIC gives you the ability to connect to the VM from the other two VMs we’re going to set up, plus the ability to access the VMs from your computer.

Set up the other two VMs

Make two other VMs just like the first. We could clone the first one after installing Ubuntu but I’m not sure that’s any faster. Ubuntu installs pretty quickly in a VM, especially from a local .iso and you’ll still have to edit the Netplan (see below) so I just run all three installs at once.

Just to recap:

  • Download and install VirtualBox (if you don’t already have it);
  • Create a “Host only” network via File -> Host network manager;
  • Create three VMs with NAT and Host-only networks;
  • Download and install Ubuntu (I used 18.04 LTS for this) on all three VMs.

Now let’s finish configuring the network.

Ubuntu 18 Network Configuration

After installing Ubuntu, your default network – the NAT – should have come up as enp0s3. The second network interface, enp0s8, should be there but not yet be up.

Create a file in /etc/netplan/ — I called mine 01-network-config.yaml. (The name doesn’t matter but start it with “01” and make the extension .yaml.) Here’s the content of one of mine:

            dhcp4: true
            dhcp4: false
            addresses: []
    version: 2

I’m allowing enp0s3 (our NAT network) to use DHCP (i.e. to get it’s own IP address). For enp0s8, however, we want to set an IP address. Notice that the first three octets match the range configured for my host-only network; I went with .111 for the first node (and .112 and .113 for the second and third). The “addresses” field expects a ranged format, hence the /24 on the end.

Save this and then run: sudo netplan apply. This should result in enp0s8 — the host-only network – coming up, allowing the VMs to access one another and for you to reach them from your PC/laptop. This means, among other things, you can stop using the terminal that comes with VirtualBox and instead SSH from your computer’s terminal (I prefer iTerm2).

At last, we’re ready for Docker.

Installing Docker

Docker is in the Ubuntu repository, but we want the latest-and-greatest, so hop on the command line of all three of your VMs and run:

curl -fsSL | sudo apt-key add - && \
sudo add-apt-repository "deb [arch=amd64] $(lsb_release -cs) stable" && \
sudo apt-get update && sudo apt-get install -y docker-ce && \
sudo systemctl status docker

Note that that’s all one command, strung together, which ends in systemctl status docker so you should see something like this:

Next, add your user to the docker group so you can run Docker commands without sudo: sudo usermod -aG docker ${USER} (Exit and log back in to pick this up.)

Although not used in this walk-through, you might want to go ahead and install Docker Compose as well:

sudo curl -L "$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose && \
docker-compose --version

Initializing the Swarm

On the VM that you want to serve as your Swarm manager node (I used the first of the three), run the following command (make sure to use the IP address of the node from which you’re running):

docker swarm init --advertise-addr

(Note that the IP address here is the one you associated with enp0s8 … the one with a static IP address.)

The output from swarm init will be the command that you need to use on the other two VMs so that they can join the Swarm as workers. I’m showing an example below but don’t use my example; you need the one with the hash key generated by your swarm manager.

docker swarm join --token SWMTKN-1-4m7eavry88i0do2xh0b72co9p6recu702lfeg2pr1r57svucd3-6h18e88axo1k3m7gobvvsjokr

Paste the output of your docker swarm join command into the command lines of your other two VMs. Viola, you’ve set up a functional Docker Swarm environment that you can use for testing.

In an upcoming post, I’ll talk more about using Docker Swarm.

Leave a Reply

Your email address will not be published. Required fields are marked *