Apache Mesos on Apache CloudStack

Apache Mesos on Apache CloudStack


Mesos is an abstract layer for CPU, memory and storage resources. Its intended to be somewhat of a datacenter operating system (DCOS). Mesos is absolutely awesome and I wanted to mix it up with some other awesome technologies like CloudStack and Docker.

Mesos can utilize virtual and physical machine resources. Since I don’t have a large number of physical I’m using virtual instances in CloudStack. I’ll also show how to get Docker working in Mesos.

Requirements:

  • Apache CloudStack
  • Ubuntu 14.04 template

Now assuming you already have CloudStack and a ubuntu 14.04 template with cloud-init so lets start. Below is an example of the environment I intend to setup.

 

wpid-mesosoncloudstack

VM Deployment using Terraform

To create the vm instances I’m going to use Terraform. Terraform makes it extremely easy to deploy vm instances on multiple providers by describing your complete infrastructure as code. I’ll give a simple example of how to use it with CloudStack.

# Configure the CloudStack Provider
provider "cloudstack" {
api_url = "http://192.168.2.18:8080/client/api"
api_key = "4ZPW01xanuLdGS4vVkoDhFrMt1nFDRawQzuHVDU7zM7rFz7faxMJ3MCt-OetEyQqnCs_v_pEusHC5EUz9-oCdQ"
secret_key = "haQcv36itRund5JZpyTqSn1hpSFBiVrp8TUCnXIGQ2y2BsjTNZAxbslxJuAUsAzaWuYgl5zKhZQl__fxuqLQxQ"
}

# Create the Mesos masters
resource "cloudstack_instance" "mesos-master" {
name = "mesosmaster-${count.index}"
display_name = "mesosmaster-${count.index}"
service_offering= "4gb-2cpu"
network = "defaultGuestNetwork"
template = "ubuntu07302015"
zone = "zone"
expunge = "true"
count = "3"
}

# Create the Mesos slaves
resource "cloudstack_instance" "mesos-slave" {
name = "mesosslave-${count.index}"
display_name = "mesosslave-${count.index}"
service_offering= "8gb-4cpu"
network = "defaultGuestNetwork"
template = "ubuntu07302015"
zone = "zone"
expunge = "true"
count = "4"
}

# Output the names and ip addresses of the mesos masters
output "mesos-master-ips" {
value = "${join(",", cloudstack_instance.mesos-master.*.name)}:${join(",", cloudstack_instance.mesos-master.*.ipaddress)}"
}

# Output the names and ip addresses of the mesos slaves
output "mesos-slave-ips" {
value = "${join(",", cloudstack_instance.mesos-slave.*.name)}:${join(",", cloudstack_instance.mesos-slave.*.ipaddress)}"
}

This should be simple enough to understand. First we define the provider that terraform will use which in this case is CloudStack. This is where I’ve defined the “api_url”, “api_key” and “secret_key”. Then terraform creates the virtual instances that will be used as Mesos masters using the ubuntu template. Name, template and zone are required by the provider but as you can see I’ve added a few optional arguments like count, expunge and service_offering. The next section creates the mesos slaves. Notice that I’ve provided different values for a few of the arguments. Lastly I output the name and ip for all the virtual instances.

With that said, nothing happens by just defining what you need. Now lets drop down to the command line. First lets run:

terraform plan

wpid-terraformplan

 

This will show what’s going to happen before it happens. This way there are no surprises. Next lets go ahead and deploy the vm instances.

terraform apply

 

wpid-terraformapply

Terraform starts deploying the vm instances as you defined. This can be watched over in the CloudStack management portal. This process should not take long unless it’s your first time deploying a vm using the template. Wait till all the vm instances are running then we can install Mesos.

wpid-cloudstackinstances

 

Open the firewall up in CloudStack

Before running the installation make sure that the firewall is not blocking your ports to the vm instances. In this case to make it easy add an ingress rule for tcp ports 0–65535 and cidr 0.0.0.0/0. I shouldn’t have to say it but I will, this is not the most secure way to set this up.

wpid-cloudstackfirewall

 

Install Mesos, Marathon, Zookeeper and Docker using Ansible

Once the vm instances are created we can take the ip addresses from the terraform output and add them into an ansible hosts file as shown below.

[zookeepers]
192.168.2.148 zoo_id=1
192.168.2.191 zoo_id=2
192.168.2.184 zoo_id=3

[mesos_masters]
192.168.2.148
192.168.2.191
192.168.2.184

[marathon]
192.168.2.148
192.168.2.191
192.168.2.184

[mesos_slaves]
192.168.2.186
192.168.2.122
192.168.2.141
192.168.2.138

In this scenario I’m installing Mesos, Marathon and Zookeeper on the same vm instances which are designated as the mesos masters. The mesos slave will also get Docker installed and configured as a containerizer in Mesos. Now with the hosts file populated correctly its time to run the ansible playbook. The playbook runs through and installs the roles (5) accordingly.

Because my ubuntu has my user and ssh-key added to it, I can just run the following.

ansible-playbook --ask-sudo-pass site.yml

If there were no ssh keys added to the vm instances you’ll have to provide the “-k” switch so that your prompted for the password.

ansible-playbook --ask-sudo-pass site.yml -k

Ansible will do its thing and when it’s finished provide a status summary as shown below.

wpid-ansibleoutput

 

Verify it working

To verify that the installation of Mesos completed success open a browser and go to one of the mesos master urls on port 5050. If you go to the Mesos url and it’s not the master you’ll be redirected to the master.

Mesos Url: http://192.168.2.148:5050

wpid-mesosmaster

 

To verify that the installation of Marathon completed success open a browser and go to one of the mesos master urls on port 8080. To make marathon highly available use a load-balancer.

Marathon Url: http://192.168.2.148:8080

wpid-marathon

 

So now what?

I’ll get into what’s next in a follow-up post.