Deploying Mesos to Vagrant - miroswan/vagrant_spec GitHub Wiki
The goal of the section is to deploy Apache Mesos to the mesos1, mesos2, and mesos3 Vagrant virtual machine instances. By the end of the section, you should have a basic understanding of the following:
- Ansible Playbooks
- Ansible Galaxy
- Ansible Inventory generation within Vagrant
Requiring Ansible Roles
Ansible is an automation tool that eases configuration management, application deployment, and orchestration. It uses simple YAML files to describe and declare the order of events required to stand up one to many systems and applications. While Ansible playbooks are single YAML files that sets variables and handlers, declares tasks, and even includes other playbooks, Ansible roles provide a clean directory and file structure similar to an application repository to compose more involved Ansible tasks.
To make things easier on Ansible developers, Ansible provides the notion of role inclusion and a role repository called Ansible Galaxy. Ansible Galaxy contains numerous Ansible roles for common systems administration tasks, such as installing and deploying Apache Mesos. In addition to Ansible Galaxy, roles can be retrieved from Github repositories, which we will do in this demo.
First, we will create a requirements.yml file within the root of our Vagrant directory that looks like this:
---
- src: https://github.com/AnsibleShipyard/ansible-mesos
version: v0.3.9
The single dash indicates that the following text is an item in an YAML Array. Next we create a YAML Hash as the first item to configure an Ansible Galaxy dependency. The source is set to a Github URL. The version is set to the latest tag present for this repository. This allows us to ensure that we use the same version each time we execute a deployment.
The following command will install the Ansible roles declared as dependencies in requirements.yml:
ansible-galaxy install -r requirements.yml
Configuring the Ansible Inventory
Now that the requisite role is installed, let's drive into some vagrant_spec configuration. Update your Vagrantfile to look like the following:
Vagrant.configure('2') do |config|
config.vm.box = 'ubuntu/trusty64'
config.hostmanager.enabled = true
config.hostmanager.manage_host = true
config.hostmanager.manage_guest = true
(1..3).each do |i|
name = "mesos#{i}"
config.vm.define name.to_sym do |node|
node.vm.hostname = name
node.vm.network(:private_network, ip: "192.168.33.#{i*10}")
end
end
config.spec.ansible_inventory = {
'mesos-masters' => %w(mesos1 mesos2 mesos3),
'zookeeper' => %w(mesos1 mesos2 mesos3)
}
end
The config.spec.ansible_inventory configuration within Vagrant allows us to dynamically generate the Ansible Inventory file so that we can work on each node with the correct SSH settings. The config.spec.ansible_inventory call is set to a Hash. Keys map to Ansible Groups. The nodes upon which Ansible Playbooks execute tasks are defined within groups in the Ansible Inventory file.
The values of the Hash take either an Array of strings representing Vagrant virtual machine names found in the Vagrantfile, or a Regexp object matching the virtual machine names found in the Vagrant file. With this configuration, we create a mesos-masters and zookeeper group, each with the same node set.
To generate the Ansible Inventory file named vagrantspec_inventory, run the following:
vagrant spec init
The contents of the file should look something like this:
[mesos-masters]
mesos1 ansible_host=127.0.0.1 ansible_port=2222 ansible_user=vagrant ansible_ssh_private_key_file=/Users/demitri/Vagrant/mesos_test/.vagrant/machines/mesos1/virtualbox/private_key
mesos2 ansible_host=127.0.0.1 ansible_port=2200 ansible_user=vagrant ansible_ssh_private_key_file=/Users/demitri/Vagrant/mesos_test/.vagrant/machines/mesos2/virtualbox/private_key
mesos3 ansible_host=127.0.0.1 ansible_port=2201 ansible_user=vagrant ansible_ssh_private_key_file=/Users/demitri/Vagrant/mesos_test/.vagrant/machines/mesos3/virtualbox/private_key
[zookeeper]
mesos1 ansible_host=127.0.0.1 ansible_port=2222 ansible_user=vagrant ansible_ssh_private_key_file=/Users/demitri/Vagrant/mesos_test/.vagrant/machines/mesos1/virtualbox/private_key
mesos2 ansible_host=127.0.0.1 ansible_port=2200 ansible_user=vagrant ansible_ssh_private_key_file=/Users/demitri/Vagrant/mesos_test/.vagrant/machines/mesos2/virtualbox/private_key
mesos3 ansible_host=127.0.0.1 ansible_port=2201 ansible_user=vagrant ansible_ssh_private_key_file=/Users/demitri/Vagrant/mesos_test/.vagrant/machines/mesos3/virtualbox/private_key
Note: If you see an error, it is likely that you're vagrant machines are not active. If this happens, try running the following:
vagrant up && vagrant spec init
The Ansible Playbook
Next, we will create a simple Ansible Playbook to deploy Apache Mesos and its Apache Zookeeper dependency to mesos1, mesos2, and mesos3. Create a file called site.yml and enter the following contents:
- name: Mesos Primaries
hosts: mesos-masters
sudo: yes
gather_facts: yes
vars:
zookeeper_hostnames: "{{ groups.zookeeper | join(':' + zookeeper_client_port + ',') }}:{{ zookeeper_client_port }}"
mesos_ip: "{{ ansible_all_ipv4_addresses[1] }}"
roles:
- { role: ansible-mesos, mesos_install_mode: master }
Let's break this down.
The Ansible Playbook is a YAML file that expects an Array of Hashes. Each Hash configures a given task. This simple playbook is comprised of a single task.
This task gathers facts about each system targeted by the value provided in the hosts key. These facts are often used to assist with configuration within Ansible Playbooks.
The task sets/overrides two variables: zookeeper_hostnames and mesos_ip. The value of zookeeper_hostnames uses Jinja2 templating to create a string based on the nodes within the zookeeper group and the default zookeeper client port provided within the zookeeper role. This allows the mesos role to properly configure zookeeper on each Mesos master instance. Additionally, the playbook overrides the mesos_ip variable. Setting it to the second network interface allows us to contact Mesos using the IP address we have configured within our Vagrantfile.
The task also brings in the ansible-mesos role and sets mesos_install_mode to master. This will effectively install and start apache mesos masters on mesos1, mesos2 and mesos3.
To run the playbook, execute the following:
ansible-playbook site.yml -i vagrantspec_inventory
The first parameter is the playbook we intend to execute. The -i flag accepts the desired inventory file. In this case, we want to use the Ansible Inventory file we've dynamically generated with vagrant_spec.
To manually verify if Mesos is running, navigate to mesos1:5050, mesos2:5050, or mesos3:5050 in your browser. You should see the web application running at either instance.