Archive
Jenkins, Stackato, Cloud-Init and Eucalyptus == Potent Combination for an On-Premise Continuous Integration Environment
The Ingredients
Jenkins
An extendable open source continuous integration server.
Stackato
The Enterprise Private PaaS that makes it easy to deploy, manage, and monitor applications on any cloud.
Cloud-init
The Ubuntu package that handles early initialization of a cloud instance. It is installed in the Ubuntu Cloud Images and also in the official Ubuntu images available on EC2.
Eucalyptus
Allows you to build production-ready, AWS-compatible private and hybrid clouds by leveraging your existing virtualized infrastructure to create on-demand cloud resource pools.
What happens when you combine all three of these tools? A potent combination for continuous integration on a easy-to-configure PaaS and an on-premise, AWS-compatible IaaS. With this combination, developers can take advantage of easy configuration that Stackato brings to the table, running on top of Eucalyptus – bringing an AWS-like cloud environment into your datacenter.
This blog entry will discuss the steps that I took to get Jenkins installed on a Stackato instance store-backed instance running on Eucalyptus. But before I get started, I would like to thank the folks from ActiveState for all their guidance. Their support staff is really top notch, and very helpful. Check them out in #stackato on freenode.net. They can also be checked out on Twitter at @ActiveState. Now on to the dirty work…..
The Recipe for Success
The Stackato Microcloud Image and Cloud-Init
To begin, the following is needed:
- A running Eucalyptus cloud
- User credentials and proper Eucalyptus IAM policies to allow uploading of images and launching instances. (If there is more information needed here, please check out the Managing Access section in Eucalyptus 3.2 Administrator’s Guide.)
- the Stackato Mircocloud VM for KVM
- A Linux desktop with euca2ools installed.
After downloading the Stackato VM for KVM and unzipping the file, we will need to pull out the root file system, the kernel and ramdisk. These will be uploaded, bundled and registered as the EMI, EKI, and ERI. To extract the root filesystem, do the following:
- Use parted to locate the root filesystem as follows:
# parted stackato-img-kvm-v2.6.6.img GNU Parted 2.1 Using /root/images/Stackato-VM/stackato-img-kvm-v2.6.6.img Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) U Unit? [compact]? b (parted) p Model: (file) Disk /root/images/Stackato-VM/stackato-img-kvm-v2.6.6.img: 10737418240B Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 1 1048576B 200278015B 199229440B primary ext3 boot 3 200278016B 1237319679B 1037041664B primary linux-swap(v1) 2 1237319680B 10736369663B 9499049984B primary ext4 (parted) quit
- In this example, the root filesystem is partition 2. The value for “Start” and “Size” will need to be used. Next, run dd to extract the root filesystem:
dd if=stackato-img-kvm-v2.6.6.img of=stackato-rootfs.img bs=1 skip=1237319680 count=9499049984
- Once it has completed, mount stackato-rootfs.img to the loopback device:
mount -o loop stackato-rootfs.img /mnt/
- Copy out initrd.img-3.2.0-27-virtual and vmlinuz-3.2.0-27-virtual from /mnt/boot.
- In /mnt/etc/fstab, replace the UUID entry with LABEL. The LABEL will look simliar to the following:
LABEL=cloudimg-rootfs / ext4 defaults 1 1
- Chroot to /mnt – there may be a need to do a mount -o bind for sys, dev, and proc.
- Run “dpkg-reconfigure cloud-init”, and make sure that the EC2 Data Source is selected.
- Unmount stackato-rootfs.img (if sys, dev, and proc were mounted, unmount them before unmounting stackato-rootfs.img). After it has been unmounted, run tune2fs to change the label of the image:
tune2fs -L cloudimg-rootfs stackato-rootfs.img
After following these steps, the following should be available:
- initrd.img-3.2.0-27-virtual – to be bundled, uploaded and registered as the ERI
- vmlinuz-3.2.0-27-virtual – to be bundled, uploaded and registered as the EKI
- stackato-rootfs.img – to be bundled, uploaded and registered as the EMI
Go through the steps of bundling, uploading and registering the ERI, EKI, and EMI. For additional information, please refer to the Add an Image section of the Eucalyptus 3.2 User Guide.
Launching the Stackato Image
Now its time to launch the Stackato image on Eucalyptus. Since cloud-init has the enabled EC2 data source now, when the image is launched, the instance will grab ssh keys, and mount the ephemeral storage. Also, additional configuration can be passed using the user-data file option. More information regarding this can be found on Stackato’s documentation in reference to using cloud-init. Key thing to remember here is that the minimum RAM requirement for the Stackato image is 2 gigs. Make sure the VM type used for launching the Stackato image has at least 2 gigs of RAM or more. In this example, the image ID is emi-DAB23A8A. The ramdisk and kernel are registered as eri-9B453C09 and eki-ADF640B0. The VM type c1.xlarge is used, which has 4 CPU, 4096 MB of RAM, and 50 Gigs of disk space.
euca-run-instances -k admin emi-DAB23A8A -t c1.xlarge --kernel eki-ADF640B0 --ramdisk eri-9B453C09
Use euca-describe-instances to check to see when the instance reaches a running state:
euca-describe-instances i-100444EF RESERVATION r-CC69438B 345590850920 default INSTANCE i-100444EF emi-DAB23A8A euca-192-168-55-104.wu-tang.euca-hasp.eucalyptus-systems.com euca-10-106-101-17.wu-tang.internal running admin 0 c1.xlarge 2013-02-23T00:34:07.436Z enter-the-wu eki-ADF640B0 eri-9B453C09 monitoring-disabled 192.168.55.104 10.106.101.17 instance-store
The key thing for running a Stackato instance is setting up the correct DNS entries. For more information regarding setting up DNS with regards to a Stackato instance, please read the Detail Configuration section on DNS in the Stackato online documentation. For this example, instead of using an external DNS service using a tool like nsupdate, to configure the A record and CNAME records, we will use xip.io. xip.io is a magic domain name that provides wildcard DNS for any IP address. Next, its time to configure the Stackato instance.
Configuration of the Stackato Instance
To configure the Stackato instance, do the following:
- SSH into the instance.
ssh -i creds/admin.priv stackato@euca-192-168-55-104.wu-tang.euca-hasp.eucalyptus-systems.com
- Make note of the ip address associated with eth0 and the netmask using ifconfig. Also note the gateway IP by using the route command.
- Run “kato op static_ip” to configure the static IP address for eth0. Make sure and add 127.0.0.1 as the first entry as part of the nameservers, and add “containers.” as the first entry under the search domains.
- Run “kato rename public DNS name “, where public DNS name includes the public IP of the instance, using xip.io (e.g. 192.168.55.104.xip.io)
- Run “kato disable mdns”, then run “sudo reboot” to reboot the instance.
- Once the instance has come back up, ssh into the instance, and run the following command ”kato setup core api.public DNS name” where public DNS name is the same value used for the “kato rename” step (e.g. 192.168.55.104.xip.io).
- Next, edit /etc/resolv.conf and make sure that the value for the search option is “containers.”, and the first entry for the nameservers is 127.0.0.1.
- Finally, run “kato enable –all-but mdns”
Thats it! Now go to the public DNS name that was used in your favorite browser. For this example, 192.168.55.104.xip.io was used. The following landing page should look similar to what you see here in the Stackato documentation regarding accessing the instance through the management console.
Setting Up Jenkins
After setting up the admin account, navigate to the “App Store” on the lefthand menu. Once selected, navigate to find the Jenkins application:
After selecting to install Jenkins, select “Yes” to install. After the installation takes place, select “Applications” in the left hand menu. From there, select the Jenkins application, and select “Start” (its the green arrow to the right of the application window). Once it has started, you will see the following:
Now Jenkins is ready to be used.
If anyone wants to test this out on Eucalyptus but doesn’t have access to their own Eucalyptus cloud, fear not, the Eucalyptus Community Cloud has the Stackato image available. After applying to get access to the Community Cloud, follow the steps above. The image for Stackato is as follows:
IMAGE emi-859B3D5C stackato_v2.6.6/stackato-cloudinit.manifest.xml 150820662310 available public x86_64 machine eki-6FBE3D2D eri-67463B77 instance-store
And as always, this image and steps can be used on AWS EC2 as well.
Let me know if there are any questions. Feedback is always welcome. Enjoy!
Another Great Example of AWS Fidelity – Neo4j, Cloud-Init and Eucalyptus
I recently ran across a blog entry entitled Neo4j 1.9.M01 – Self-managed HA. I found the concept of graph databases storing data really interesting and reached out to the guys at Neo4j to get some insight on how to deploy their HA solution on Eucalyptus. Amongst the resources that they provided, they shared this little gem – how to deploy Neo4j on EC2. In order to run first, you need to know how to walk – so before going down the path of standing up HA Neo4j, I decided to be influenced by the DIY on EC2 article provided by Neo4j and deploy Neo4j on Eucalyptus - with a little help from Cloud-Init. The follow-up blog will show how to use the same setup, and deploy an HA Neo4j environment.
The Setup
Eucalyptus
The Eucalyptus cloud I used is configured using Eucalyptus High-Availability. Its running on CentOS 6.3, running KVM. Its also running in Managed networking mode, so that we can take advantage of network isolation of the VMs, and the use of security groups - interacting very much in the same way as its done in the security groups provided in AWS EC2.
Ubuntu Cloud Image – 12.04 LTS Precise Pangolin
The image that we will use is the Ubuntu 12.04 LTS Cloud image. The reasons for using this image is as follows:
- Ubuntu cloud images come pre-packaged with cloud-init, which helps with bootstrapping the instance.
- I wanted to have the solution work on AWS EC2 and Eucalyptus; since Ubuntu cloud images work on both, its a great choice.
Registering the Ubuntu Cloud Image with Eucalyptus
In order for us to get started, we need to get the Ubuntu Cloud image into Eucalyptus so that we can use it for our instance. To upload, bundle and register the Ubuntu Cloud image, ramdisk and kernel, do the following:
- Download current version of Ubuntu Precise Server AMD64 from the Ubuntu Cloud Image – Precise page, then unpack (ungzip, unarchive) the tar-gzipped file.
$ tar -zxvf precise-server-cloudimg-amd64.tar.gz x precise-server-cloudimg-amd64.img x precise-server-cloudimg-amd64-vmlinuz-virtual x precise-server-cloudimg-amd64-loader x precise-server-cloudimg-amd64-floppy x README.files
- Make sure to download and source your Eucalyptus credentials.
- We need to bundle, upload, and register precise-server-cloudimg-amd64-loader (ERI), precise-server-cloudimg-amd64-vmlinuz-virtual (EKI), and precise-server-cloudimg-amd64.img (EMI). For more information regarding this, please refer to the “Image Overview” section of the Eucalyptus 3.1 User Guide.
$ euca-bundle-image -i precise-server-cloudimg-amd64-loader --ramdisk true $ euca-upload-bundle -b latest-ubuntu-precise -m /tmp/precise-server-cloudimg-amd64-loader.manifest.xml $ euca-register -a x86_64 latest-ubuntu-precise/precise-server-cloudimg-amd64-loader.manifest.xml $ euca-bundle-image -i precise-server-cloudimg-amd64-vmlinuz-virtual --kernel true $ euca-upload-bundle -b latest-ubuntu-precise -m /tmp/precise-server-cloudimg-amd64-vmlinuz-virtual.manifest.xml $ euca-register -a x86_64 latest-ubuntu-precise/precise-server-cloudimg-amd64-vmlinuz-virtual.manifest.xml $ euca-bundle-image -i precise-server-cloudimg-amd64.img $ euca-upload-bundle -b latest-ubuntu-precise -m /tmp/precise-server-cloudimg-amd64.img.manifest.xml $ euca-register -a x86_64 latest-ubuntu-precise/precise-server-cloudimg-amd64.img.manifest.xml
After bundling, uploading and registering the ramdisk, kernel and image, the latest-ubuntu-precise bucket in Walrus should have the following images:
$ euca-describe-images | grep latest-ubuntu-precise IMAGE eki-0F3937E9 latest-ubuntu-precise/precise-server-cloudimg-amd64-vmlinuz-virtual.manifest.xml 345590850920 available public x86_64 kernel instance-store IMAGE emi-C1613E67 latest-ubuntu-precise/precise-server-cloudimg-amd64.img.manifest.xml 345590850920 available public x86_64 machine instance-store IMAGE eri-0BE53BFD latest-ubuntu-precise/precise-server-cloudimg-amd64-loader.manifest.xml 345590850920 available public x86_64 ramdisk instance-store
Cloud-init Config File
Now that we have the image ready to go, we need to create a cloud-init config file to pass in using the –user-data-file option that is part of euca-run-instances. For more examples of different cloud-init files, please refer to the cloud-init-dev/cloud-init repository on bazaar.launchpad.net. Below is the cloud-init.config file I created for bootstrapping the instance with an install of Neo4j, using ephemeral disk for the application storage, and installing some other packages (i.e. latest euca2ools, mlocate, less, etc.). The script can be also accessed from github as well – under the eucalptus/recipes repo.
#cloud-config
apt_update: true
apt_upgrade: true
disable_root: true
package_reboot_if_required: true
packages:
- less
- bind9utils
- dnsutils
- mlocate
cloud_config_modules:
- ssh
- [ apt-update-upgrade, always ]
- updates-check
- runcmd
runcmd:
- [ sh, -xc, "if [ -b /dev/sda2 ]; then tune2fs -L ephemeral0 /dev/sda2;elif [ -b /dev/vda2 ]; then tune2fs -L ephemeral0 /dev/vda2;elif [ -b /dev/xvda2 ]; then tune2fs -L ephemeral0 /dev/xvda2;fi" ]
- [ sh, -xc, "mkdir -p /var/lib/neo4j" ]
- [ sh, -xc, "mount LABEL=ephemeral0 /var/lib/neo4j" ]
- [ sh, -xc, "if [ -z `ls /var/lib/neo4j/*` ]; then sed --in-place '$ iMETA_HOSTNAME=`curl -s http://169.254.169.254/latest/meta-data/local-hostname`\\nMETA_IP=`curl -s http://169.254.169.254/latest/meta-data/local-ipv4`\\necho ${META_IP} ${META_HOSTNAME} >> /etc/hosts; hostname ${META_HOSTNAME}; sysctl -w kernel.hostname=${META_HOSTNAME}\\nif [ -d /var/lib/neo4j/ ]; then mount LABEL=ephemeral0 /var/lib/neo4j; service neo4j-service restart; fi' /etc/rc.local; fi" ]
- [ sh, -xc, "META_HOSTNAME=`curl -s http://169.254.169.254/latest/meta-data/local-hostname`; META_IP=`curl -s http://169.254.169.254/latest/meta-data/local-ipv4`; echo ${META_IP} ${META_HOSTNAME} >> /etc/hosts" ]
- [ sh, -xc, "META_HOSTNAME=`curl -s http://169.254.169.254/latest/meta-data/local-hostname`; hostname ${META_HOSTNAME}; sysctl -w kernel.hostname=${META_HOSTNAME}" ]
- [ sh, -xc, "wget -O c1240596-eucalyptus-release-key.pub http://www.eucalyptus.com/sites/all/files/c1240596-eucalyptus-release-key.pub" ]
- [ apt-key, add, c1240596-eucalyptus-release-key.pub ]
- [ sh, -xc, "echo 'deb http://downloads.eucalyptus.com/software/euca2ools/2.1/ubuntu precise main' > /etc/apt/sources.list.d/euca2ools.list" ]
- [ sh, -xc, "echo 'deb http://debian.neo4j.org/repo stable/' > /etc/apt/sources.list.d/neo4j.list" ]
- [ apt-get, update ]
- [ apt-get, install, -y, --force-yes, euca2ools ]
- [ apt-get, install, -y, --force-yes, neo4j ]
- [ sh, -xc, "sed --in-place 's/#org.neo4j.server.webserver.address=0.0.0.0/org.neo4j.server.webserver.address=0.0.0.0/' /etc/neo4j/neo4j-server.properties" ]
- [ sh, -xc, "service neo4j-service restart" ]
- [ sh, -xc, "export LANGUAGE=en_US.UTF-8" ]
- [ sh, -xc, "export LANG=en_US.UTF-8" ]
- [ sh, -xc, "export LC_ALL=en_US.UTF-8" ]
- [ locale-gen, en_US.UTF-8 ]
- [ dpkg-reconfigure, locales ]
- [ updatedb ]
mounts:
- [ ephemeral0, /var/lib/neo4j, auto, "defaults,noexec" ]
Now, we are ready to launch the instance.
Putting It All Together
Before launching the instance, we need to set up our keypair and security group that we will use with the instance.
- To create a keypair, run euca-create-keypair. *NOTE* Make sure you change the permissions of the keypair to 0600 after its been created.
euca-create-keypair neo4j-user > neo4j-user.priv; chmod 0600 neo4j-user.priv
- Next, we need to create a security group for our instance. To create a security group, use euca-create-group. To open any ports you need for the application, use euca-authorize. The ports we will open up for the Neo4j application are SSH (22), ICMP, HTTP( 7474), and HTTPS (7473).
- Create security group:
# euca-create-group neo4j-test -d "Security for Neo4j Instances"
- Authorize SSH:
# euca-authorize -P tcp -p 22 -s 0.0.0.0/0 neo4j-test
- Authorize HTTP:
# euca-authorize -P tcp -p 7474 -s 0.0.0.0/0 neo4j-test
- Authorize HTTPS:
# euca-authorize -P tcp -p 7473 -s 0.0.0.0/0 neo4j-test
- Authorize ICMP:
# euca-authorize -P icmp -t -1:-1 -s 0.0.0.0/0 neo4j-test
- Create security group:
- Finally, we use euca-run-instances to launch the Ubuntu Precise image, and use cloud-init to install Neo4j:
# euca-run-instances -k neo4j-user --user-data-file cloud-init-neo4j.config emi-C1613E67 --kernel eki-0F3937E9 --ramdisk eri-0BE53BFD --group neo4j-test
To check the status of the instance, use euca-describe-instances.
# euca-describe-instances i-A9EF448C RESERVATION r-ED8E4699 345590850920 neo4j-test INSTANCE i-A9EF448C emi-C1613E67 euca-192-168-55-104.wu-tang.euca-hasp.eucalyptus-systems.com euca-10-106-69-154.wu-tang.internal running admin 0 m1.small 2012-12-04T03:13:13.869Z enter-the-wu eki-0F3937E9 eri-0BE53BFD monitoring-disable euca-192-168-55-104.wu-tang.euca-hasp.eucalyptus-systems.com euca-10-106-69-154.wu-tang.internal instance-store
Because I added in the cloud-init config file to do an “apt-get upgrade”, it takes about 5 to 7 minutes until the instance is fully configured and Neo4j is running. Once you have it running, go to https://<ip-address of instance>:7473. It will direct you to the web administration page for monitoring and management of the Neo4j instance. In this example, the URL will be https://euca-192-168-55-104.wu-tang.euca-hasp.eucalyptus-systems.com:7473
Thats it! The cool thing about this too, is that you can find an Ubuntu Precise AMI on AWS EC2, use the same cloud-init script, use euca2ools, and follow these instructions to get the same deployment on AWS EC2.
As mentioned before, the follow-up blog will be how to deploy the HA solution of Neo4j on Eucalyptus. Enjoy!
Eucalyptus Recipes Project
Reblogged from Technological Musings:
Automation and configuration management is a big part of any successful cloud deployment. Whether on AWS, Eucalyptus or another cloud provider, having services that can be easily spun up and down with a consistent configuration is a must at cloud scale. The recipes project is looking to assist new cloud users with a first step.
The recipes project is attempting to be as vendor agnostic as possible by using both…
Moving the Cloud Forward
It is sort of becoming a tradition for each member of the Fedora Board to declare a personal goal of some sort and then lead by doing. So now that I am the newest Board member, some people are curious about my plans.
In 2010 I helped get Fedora's Cloud SIG off the ground. At that point in time our main goal was to get a modern version of Fedora running inside Amazon's popular cloud, EC2.








