Table of Contents

Overview

Vagrant allows you to configure several virtual machines using a simple parameter file (vagrant file) So let's configure a simple cluster with 3 servers with the following settings:

  1. Bridge IP
  2. 1 GB Ram
  3. Unique Name
  4. Centos 7

Create the Vagrant File

The vagrant file is a parameter file used by the vagrant engine to create the virtual machine(s)

So let's start building. Firstly, don't forget it is YML file so every space and tab means something, so be careful with the syntax. Firstly, we will add the distribution and unique name:

Add distribution

Vagrant.configure("2") do |config|
  config.vm.define "mgr1" do |mgr1|
    mgr1.vm.box = "centos/7"
    mgr1.vm.hostname = 'mgr1'
   end
end

This configuration will create a single machine called “mgr1” with Centos 7

So what after, well we have to add IP

Define Network

mgr1.vm.network "public_network", bridge: "Intel(R) Ethernet Connection (2) I219-V"

Bare in mind that, you might have different bridge setting, so please check yours from the ipconfig settings.

After that we can add the memory settings. Also note that the memory is provider configuration, so specific for virtual box:

Define Memory

   mgr1.vm.provider :virtualbox do |v|
      v.customize ["modifyvm", :id, "--memory", 1024]
      v.customize ["modifyvm", :id, "--name", "mgr1"]
    end

In the end, out vagrantfile, for one server and without the Docker config, will look something like that:

Full config without Docker

Vagrant.configure("2") do |config|
  config.vm.define "mgr1" do |mgr1|
    mgr1.vm.box = "centos/7"
    mgr1.vm.hostname = 'mgr1'
	mgr1.vm.network "public_network", bridge: "Intel(R) Ethernet Connection (2) I219-V"
    mgr1.vm.provider :virtualbox do |v|
      v.customize ["modifyvm", :id, "--memory", 1024]
      v.customize ["modifyvm", :id, "--name", "mgr1"]
    end
  end
end

If the network is set to: “public_network” and the bridge, then it will take it from the DHCP, you can specify the IP as well, if you are sure the IP is free.

To add the configuration for Docker, we have to create a small script:

Docker installation

$install_docker_script = <<SCRIPT
echo Installing Docker...
curl -sSL https://get.docker.com/ | sh
sudo usermod -aG docker root
SCRIPT

We can include that script in the configuration using the “shell” provision, as follows:

Docker shell provision

	mgr1.vm.provision "shell", inline: $install_docker_script, privileged: true

Implement all

So in the end, our vagrantfile with all 3 servers and all the configuration will look like that:

Full config with Docker config

$install_docker_script = <<SCRIPT
echo Installing Docker...
curl -sSL https://get.docker.com/ | sh
usermod -aG docker root
service docker start
SCRIPT

$manager_script = <<SCRIPT
echo Swarm Init...
docker swarm init --listen-addr 10.100.199.200:2377 --advertise-addr 10.100.199.200:2377
docker swarm join-token --quiet worker > /vagrant/worker_token
docker run -ti -d -p 5000:5000 -e HOST=localhost -e PORT=5000 -v /var/run/docker.sock:/var/run/docker.sock andonovj/httpserverdemo  
SCRIPT

$worker_script = <<SCRIPT
echo Swarm Join...
docker swarm join --token $(cat /vagrant/worker_token) 10.100.199.200:2377
SCRIPT

$allow_shell = <<SCRIPT
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config    
systemctl restart sshd.service
SCRIPT

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  config.vm.define "mgr1" do |mgr1|
    mgr1.vm.box = "centos/7"
    mgr1.vm.hostname = 'mgr1'
	mgr1.vm.synced_folder "./swarm_Config", "/vagrant", type: "virtualbox"
	mgr1.vm.network :private_network, ip: "10.100.199.200"
	mgr1.vm.network :forwarded_port, guest: 8080, host: 8080
    mgr1.vm.network :forwarded_port, guest: 5000, host: 5000
	mgr1.vm.provision "shell", inline: $install_docker_script, privileged: true
	mgr1.vm.provision "shell", inline: $manager_script, privileged: true
	mgr1.vm.provision "shell", inline: $allow_shell, privileged: true
    mgr1.vm.provider :virtualbox do |v|
      v.customize ["modifyvm", :id, "--memory", 1024]
      v.customize ["modifyvm", :id, "--name", "mgr1"]
    end
  end

	(1..2).each do |i|
    config.vm.define "worker0#{i}" do |worker|
      worker.vm.box = "centos/7"
      worker.vm.box_check_update = true
      worker.vm.network :private_network, ip: "10.100.199.20#{i}"
      worker.vm.hostname = "worker0#{i}"
      worker.vm.synced_folder "./swarm_Config", "/vagrant", type: "virtualbox"
      worker.vm.provision "shell", inline: $install_docker_script, privileged: true
      worker.vm.provision "shell", inline: $worker_script, privileged: true
	  worker.vm.provision "shell", inline: $allow_shell, privileged: true
      worker.vm.provider "virtualbox" do |vb|
        vb.name = "worker0#{i}"
        vb.memory = "1024"
      end
    end
  end
end