NOTE: This document is a companion to the slides on building virtual cloud environments in the desktop. I intend to speak about this at the PHP cloud event as part of my talk. I am making it available here, so that I can attract comments from anyone willing to try it before the event. These are just additional notes that you may be interested in.
Introduction
Virtualization during development?
- How often has it happened to you that some code ran fine in your development box, but when you deployed it, it didn’t work because you had a load balancer logic which caused your app to break and you didn’t have a similar setup in your development environment?
- How often has it happened to you that you got something to work, but it took you a while to replicate the same thing on a production server because you don’t remember the exact steps?
- How often have you screwed up your laptop because you tried to install something?
- How nice would it be if I could have a virtual environment to test the app – an environment that does not have ‘my’ identity? An identity, that mimics the production setup?
- How nice would it be if new employees can get started with development without requiring to spend a lot of time setting up a dev environment?
- Examples of situations where a multi-machine deployment is different from a single machine deployment:
- my.cnf requires change to the bind-address to allow remote hosts to connect
- We need to GRANT PRIVILEGES to the remote host and user
Let us look at a sample usecase – where I have a codeserver, a webserver and a db server on 3 different boxes and I run a deployment end to end. We will create a setup that mimics a production environment.
After creating the base VM image
- Login to the Base VM.
- Verify that the network is configured fine.
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub ubuntu@base.
ssh -t ubuntu@base. sudo apt-get update && sudo apt-get upgrade -y
ssh -t ubuntu@base. sudo apt-get install openssh-server -y
ssh ubuntu@base. ping -c 3 192.168.100.1
ssh ubuntu@base. "cat /etc/network/interfaces.old | sed 's/eth0/eth1/g' > /tmp/interfaces"
ssh -t ubuntu@base. sudo mv /etc/network/interfaces /etc/network/interfaces.old
ssh -t ubuntu@base. sudo mv /tmp/interfaces /etc/network/interfaces
Cloning the base VM
- We now clone this base image to multiple machines
$ #Add the DNS server to the resolv.conf
$ cat /etc/resolv.conf
nameserver 192.168.100.1
nameserver 192.168.1.1
$ cat create-new-domain.sh
domain_name=$1
sudo virt-clone -o basevm -n $domain_name -f /var/lib/libvirt/images/$domain_name.img
virsh start $domain_name
echo "Sleeping 10 seconds for the OS to boot"
sleep 10
ssh -t ubuntu@base. "echo $domain_name | sudo tee /etc/hostname"
ssh -t ubuntu@base. "sudo init 6"
echo "Sleeping 10 seconds for the OS to reboot"
sleep 10
$ ./create-new-domain.sh <server-name>
$
Try logging in from host to guest and guest to host. Both should work.
Code server creation
Setup the GIT server over SSH
$ ./create-new-domain.sh codeserver
$ ssh -t ubuntu@codeserver. sudo apt-get install git-core -y
$ ssh -t ubuntu@codeserver. git config --global user.name "Gautham Pai"
$ ssh -t ubuntu@codeserver. git config --global user.email "<your-email-here>"
$ ssh -t ubuntu@codeserver. mkdir git-data
$ ssh -t ubuntu@codeserver. "cd git-data;git init;git config --bool core.bare true"
Initializing the base repository
$ git clone ubuntu@codeserver.:~/git-data
$ cd git-data/
$ echo “Test” > test-file
$ git add test-file
$ git commit -m "Test file" -a
$ git push origin master
Web server creation
Setting up Apache
$ ./create-new-domain.sh webserver
$ ssh -t ubuntu@webserver. sudo apt-get install apache2 php5-mysql libapache2-mod-php5 git-core -y
$ ssh -t ubuntu@webserver. sudo /etc/init.d/apache2 restart
DB server creation
Setting up MySQL
$ ./create-new-domain.sh dbserver
$ ssh -t ubuntu@dbserver. sudo apt-get install mysql-server -y
$ #Allowing external connections
$ ssh -t ubuntu@dbserver. "cat /etc/mysql/my.cnf | sed 's/^bind-address.*/bind-address\t\t= 0.0.0.0/g' > /tmp/my.cnf"
$ ssh -t ubuntu@dbserver. "sudo mv /etc/mysql/my.cnf /etc/mysql/my.cnf.bk"
$ ssh -t ubuntu@dbserver. "sudo mv /tmp/my.cnf /etc/mysql/my.cnf"
$ ssh -t ubuntu@dbserver. "sudo service mysql restart"
Connecting various servers
Connecting web server with db server
$ #Allowing web server to connect to MySQL
$ webserver_ip=`host webserver | grep "has address" | awk '{print $NF}'`
$ ssh -t ubuntu@dbserver. mysql -uroot -e "\"GRANT ALL PRIVILEGES ON *.* TO 'ubuntu'@$webserver_ip IDENTIFIED BY 'ubuntu'\""
Checking out and deploying code
$ ssh -t ubuntu@webserver. git-data/deploy/deploy.sh
Bringing up the system for testing
$ #Start the domains
$ virsh start webserver && virsh start dbserver && virsh start codeserver
$ #Destroy the domains
$ virsh destroy webserver && virsh destroy dbserver && virsh destroy codeserver
Key locations
- /etc/libvirt/qemu/ - This is where the configuration of each of the Vms is stored.
- /var/lib/libvirt/images - This is where the actual machines reside.