Many of my recent projects have been single-server web applications using TurboGears or Flask that consume a few other services. While I was thinking about challenges like scaling, it occurred to me that I should take a look at OpenStack. I hope this will give me a better idea of how the cloud (which I take for granted) works.
You can read the history of OpenStack if you’re so inclined. Here is what matters: it is a set of cooperating services that can be used to build and scale applications. It is an open source counterpart to some of Amazon’s AWS offerings and it powers the cloud services offered by Rackspace, HP, Red Hat and others.
Getting started
To give OpenStack a test drive on my laptop, I’m using DevStack, a script which makes quick work of deploying a small instance of OpenStack. It starts with a clean deployment of Ubuntu 12.04 and the DevStack git repository:
git clone https://github.com/openstack-dev/devstack.git
At this point, you can add your chosen configuration values. (I did nothing on my first attempt.) Then, start the stack:
cd devstack; ./stack.sh
So, did it work? It seems the answer is yes. Here’s what I see now:
Horizon is now available at http://192.168.5.130/
Keystone is serving at http://192.168.5.130:5000/v2.0/
Examples on using novaclient command line is in exercise.sh
The default users are: admin and demo
The password: secrete
This is your host ip: 192.168.5.130
stack.sh completed in 1603 seconds.
And at http://192.168.5.130:
A quick check of the dashboard shows that I can launch new instances (which are guests running in qemu, hosted by my Ubuntu 12.04 host running in VMware Fusion running atop OS X–something tells me virtual doesn’t mean what it used to mean.) Sweet! It also shows me that Swift, the object storage service is not running. I’m playing around with OpenStack mostly because I want to learn more about the object storage service. (Yes, I could just use Amazon S3, but then I wouldn’t be writing this post.) It turns out that this is not as simple as you might think. (If you are not new to OpenStack, bear with me–I’ve been using it for a few hours now.)
The Swift Service
Swift is the name of the object storage service for OpenStack. It has an optional S3-compatible API and I think it will do what I want–give me an object store sandbox. After lots of searching and poking around, I came up with this configuration, put in local.conf before running stack.sh:
[[local|localrc]]
ADMIN_PASSWORD=secrete
DATABASE_PASSWORD=$ADMIN_PASSWORD
RABBIT_PASSWORD=$ADMIN_PASSWORD
SERVICE_PASSWORD=$ADMIN_PASSWORD
SERVICE_TOKEN=a682f596-76f3-11e3-b3b2-e716f9080d50
DEST=/opt/stack
LOGFILE=$DEST/logs/stack.sh.log
LOGDAYS=1
LOG_COLOR=False
SCREEN_LOGDIR=$DEST/logs/screen
RECLONE=yes
enable_service s-proxy s-object s-container s-account
SWIFT_HASH=66a3d6b56c1f479c8b4e70ab5c2000f5
SWIFT_REPLICAS=1
SWIFT_DATA_DIR=$DEST/data/swift
[[post-config|$NOVA_CONF]]
[DEFAULT]
API_RATE_LIMIT=False
I noticed that deploying DevStack with this configuration took much longer to run. This surprised me. The outcome was similar:
Horizon is now available at http://192.168.5.130/
Keystone is serving at http://192.168.5.130:5000/v2.0/
Examples on using novaclient command line is in exercise.sh
The default users are: admin and demo
The password: secrete
This is your host ip: 192.168.5.130
Great! The Swift tenant accounts are in place and I can see lots of Swift processes running:
$ ps -ef | grep swift | grep -v grep
troy 1299 54434 4 17:56 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-object-auditor /etc/swift/object-server/1.conf
troy 1352 54434 0 17:56 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-object-auditor /etc/swift/object-server/1.conf
troy 54429 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-container-updater /etc/swift/container-server/1.conf
troy 54430 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-account-auditor /etc/swift/account-server/1.conf
troy 54431 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-object-replicator /etc/swift/object-server/1.conf
troy 54433 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-container-replicator /etc/swift/container-server/1.conf
troy 54434 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-object-auditor /etc/swift/object-server/1.conf
troy 54435 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-container-auditor /etc/swift/container-server/1.conf
troy 54438 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-account-reaper /etc/swift/account-server/1.conf
troy 54439 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-container-sync /etc/swift/container-server/1.conf
troy 54440 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-account-replicator /etc/swift/account-server/1.conf
troy 54441 1 0 17:44 ? 00:00:00 /usr/bin/python /usr/local/bin/swift-object-updater /etc/swift/object-server/1.conf
troy 54604 54603 0 17:44 ? 00:00:00 python /opt/stack/swift/bin/swift-proxy-server /etc/swift/proxy-server.conf -v
troy 54676 54604 0 17:44 ? 00:00:00 python /opt/stack/swift/bin/swift-proxy-server /etc/swift/proxy-server.conf -v
troy 54684 54683 0 17:44 ? 00:00:00 python /opt/stack/swift/bin/swift-object-server /etc/swift/object-server/1.conf -v
troy 54979 54684 0 17:44 ? 00:00:00 python /opt/stack/swift/bin/swift-object-server /etc/swift/object-server/1.conf -v
troy 55138 55137 0 17:45 ? 00:00:00 python /opt/stack/swift/bin/swift-container-server /etc/swift/container-server/1.conf -v
troy 55210 55138 0 17:45 ? 00:00:00 python /opt/stack/swift/bin/swift-container-server /etc/swift/container-server/1.conf -v
troy 55217 55216 0 17:45 ? 00:00:00 python /opt/stack/swift/bin/swift-account-server /etc/swift/account-server/1.conf -v
troy 55293 55217 0 17:45 ? 00:00:00 python /opt/stack/swift/bin/swift-account-server /etc/swift/account-server/1.conf -v
I can even use it from the command line:
troy@ubuntu:~$ echo Hello foo > foo.txt
troy@ubuntu:~$ echo Hello bar > bar.txt
troy@ubuntu:~$ swift upload mycontainer foo.txt
foo.txt
troy@ubuntu:~$ swift upload mycontainer bar.txt
bar.txt
troy@ubuntu:~$ md5sum *.txt
f775802ffdb416d737993925223b040b bar.txt
a2a894025ee13943ee4887bebf6af3f1 foo.txt
troy@ubuntu:~$ swift list
mycontainer
troy@ubuntu:~$ swift list mycontainer
bar.txt
foo.txt
troy@ubuntu:~$ rm *.txt
troy@ubuntu:~$ swift download mycontainer
foo.txt [auth 0.184s, headers 0.212s, total 0.212s, 0.000 MB/s]
bar.txt [auth 0.197s, headers 0.220s, total 0.220s, 0.000 MB/s]
troy@ubuntu:~$ md5sum *.txt
f775802ffdb416d737993925223b040b bar.txt
a2a894025ee13943ee4887bebf6af3f1 foo.txt
I haven’t added the S3 compatability layer, but I have enough to help me move forward. If I’ve missed something or you know of a better way to deploy OpenStack for testing, let us know in the comments!
Caveat
Above, I pretended that reconfiguring OpenStack is a trivial thing. It might be, if you know what you’re doing. I tried a few different options to get DevStack to pick up my new configurations, but I found that nothing helped me get a configuration deployed cleanly like wiping the DevStack VM and starting again. Keep in mind that DevStack is a set of shell scripts. It’s not Puppet or Chef for clouds. It’s also aimed at developers who just want to get going as quickly as possible. And for that purpose, it’s probably good enough.