Most configuration files and scripts discussed here can be found in the code repository for this project: https://github.com/ggeorgovassilis/cloudmatrix
This post is a work in progress, I’ll be updating it as I progress more.
Overview
My current job at AMOS is about PaaS and – all benefits regarding efficiency, performance and availability put aside – I value the substantial simplification of cloud resource provisioning as opposed to ordering resources from an internal department. Whereas requesting a new (virtual) server or extra storage space can easily become an exercise of patience in large enterprises, cloud infrastructure provisions virtual resources in minutes with added benefits such as isolation for extra security. Thus, the main goal of this exercise is to develop a platform that simplifies container allocation to the maximum possible extent.
Here’s an all-in-one picture of the cloud’s ingredients and how network traffic is routed between them:
Varnish for routing HTTP traffic from the outside world to applications running in the various VMs. It’s important to get version 4 because of its ability to declare backend groups programmatically – version 3 is default in Ubuntu 14.04.
Creating the virtual machines
Setting up the manager
/etc/network/interfaces:
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet static
address 10.10.10.1
netmask 255.255.255.0
/etc/hosts:
/etc/dnsmasq.conf:
interface=eth1
domain=matrix,10.10.10.0/24
dhcp-range=10.10.10.2,10.10.10.255,255.255.255.0,12h
enable-ra
log-queries
log-dhcp
Now let’s create a local SSH key:
ssh-keygen
We’ll later copy this key to the node VMs.
/etc/default/docker:
DOCKER_OPTS="--insecure-registry matrix-manager.matrix:5000"
docker run -d -p 5000:5000 --restart=always --name registry registry:2
Setting up the node VMs
/etc/default/docker: DOCKER_OPTS="--insecure-registry matrix-manager.matrix:5000"
Now let’s copy our SSH key over to the node VM: ssh-copy-id cloud@matrix-manager.matrix where “cloud” is my local ubuntu account, your’s is probably called differently. Also, I’d like the node VM to get its host name from DHCP. This script will do it (with some minor modifications): https://nullcore.wordpress.com/2011/12/09/setting-the-system-hostname-from-dhcp-in-ubuntu-11-10/
#!/bin/sh
# Filename: /etc/dhcp/dhclient-exit-hooks.d/hostname
# Purpose: Used by dhclient-script to set the hostname of the system
# to match the DNS information for the host as provided by
# DHCP.
#
# Do not update hostname for virtual machine IP assignments
if [ "$interface" != "eth0" ] && [ "$interface" != "wlan0" ]
then
return
fi
if [ "$reason" != BOUND ] && [ "$reason" != RENEW ] \
&& [ "$reason" != REBIND ] && [ "$reason" != REBOOT ]
then
return
fi
echo dhclient-exit-hooks.d/hostname: Dynamic IP address = $new_ip_address
hostname=$(host $new_ip_address | cut -d ' ' -f 5 | cut -d '.' -f 1)
echo $hostname > /etc/hostname
hostname $hostname
echo dhclient-exit-hooks.d/hostname: Dynamic Hostname = $hostname
So far there is nothing else to do for the node VM. Shut it down, clone it a few times (i.e. node-2, node-3) changing the MAC address. You should be able to start them without any problem and note that each node VM gets a unique network name and host name (e.g. node107, node 202 etc). On the matrix-manager VM you can also check all known nodes: cat /var/lib/misc/dnsmasq.leases
Milestone 1: a first test
Let’s see whether we can do this very basic thing: install a public Docker image in the manager’s registry and then have a node pull it from there. SSH to the manager, then:
docker pull hello-world && docker tag hello-world matrix-manager.matrix:5000/cloud/hello-world
docker push matrix-manager.matrix:5000/cloud/hello-world
Then ssh to a node, like node1.matrix and:
docker run matrix-manager.matrix:5000/cloud/hello-world
This should run a “hello-world” instance which you can verify by running:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8721f9846d03 matrix-manager.matrix:5000/hello-world "/hello" 9 seconds ago Exited (0) 8 seconds ago tender_hopper
Milestone 2: Pushing images to nodes with scripts
1. As a developer, I’d like to install web applications in the matrix.
2. As a tester, I’d like to be able to use web applications in the matrix.
2. packaging it as a Docker image
3. pushing it to our private registry
4. logging in to a node VM and running the application image
5. registering the application’s URL with varnish and routing HTTP traffic to the node VMs
6. all of this with fail over and load balancing
The first script, create-image, packages an application into a Docker image. The script would typically be executed on a developer’s workstation, requires a Docker installation on the workstation and will store the application image in the local registry.
The next script, install-image, is executed on the master VM and pulls the application image to our master registry.
The run-container script logs into a node VM via SSH, pulls an application image from the master VM registry and runs it as a container. Since we’re interested in web applications, the script will also bind HTTP to a local TCP port over which the application can be talked to.
Another interesting script is deploy-applications-plan which reads instructions from a file which describe which application images to install on which node VMs.
Last not least, update-proxy reads the same application deployment plan and creates a VCL file for Varnish which maps HTTP requests to containers running on specific node VMs.
So let’s get started! The action plan looks like this: deploy two Java web applications that output a simple “Hello world” to the cloud and access them via a web browser.
create-image simplewebapp1 test-image1
create-image simplewebapp2 test-image2
install-image simplewebapp1
install-image simplewebapp2




