modified: 2010-11-30-the-barrymores-stole-my-heart-then-crushed-it.rst modified: 2010-12-31-four2go-a-new-spin-on-an-old-classic.rst modified: 2011-01-02-a-homegrown-python-bread-crumb-module.rst modified: 2011-01-05-how-did-stack-overflow-get-initial-traction.rst modified: 2011-01-09-graphic-design-powerhouse-wacom-bamboo-ubuntu-and-mypaint.rst modified: 2011-01-10-i-just-used-google-to-purchase-chinese-food-takeout-for-two.rst modified: 2011-01-11-response-to-l-theanine-a-4000-year-old-mind-hack.rst modified: 2011-03-26-porting-the-chaostheory-wordpress-theme-to-pylowiki.rst modified: 2011-04-03-voice-over-ip-with-teamspeak.rst modified: 2011-04-16-dropbox-encryption-with-truecrypt.rst modified: 2011-06-25-google-bot-attempts-to-crawl-shortest-urls-first.rst modified: 2011-07-02-add-a-breadcrumb-subscriber-to-a-pyramid-project-using-4-simple-steps.rst modified: 2011-07-11-a-hack-to-gain-80-percent-efficiency-when-creating-github-projects.rst modified: 2011-08-08-programming-is-like-alchemy.rst modified: 2011-08-18-security-professionals-yes-we-appear-vulnerable-but-that-attack-vector-will-never-happen.rst modified: 2011-08-22-python-image-grabber-pig-py.rst modified: 2011-09-06-deliberating-the-viewers-vs-doers-concept.rst modified: 2011-09-08-a-system-administrators-guide-to-installing-and-maintaining-multiple-python-environments.rst modified: 2011-09-09-hacker-olive-oil-lamp-crafted-from-home-materials.rst modified: 2011-10-01-how-do-i-calculate-the-m-in-my-mvp.rst modified: 2011-10-05-linkpeek-com-web-address-thumbnail-api-alpha-release.rst modified: 2011-10-12-a-better-way-to-show-website-backlinks.rst modified: 2011-10-15-i-cancelled-my-xbox-live-automatic-renewal.rst modified: 2011-10-15-r8168-driver-issues-after-ubuntu-11-10-upgrade-kernel-linux-3-0.rst modified: 2011-11-30-how-to-incorporate-custom-configuration-in-a-pyramid-application.rst modified: 2011-12-19-linkpeek-com-webpage-to-image-was-a-by-product.rst modified: 2012-01-18-today-i-lost-a-customer.rst modified: 2012-02-16-my-4-month-olds-15-minutes-of-fame.rst modified: 2012-03-03-how-to-save-hundreds-of-dollars-on-groceries-without-clipping-coupons.rst modified: 2012-03-26-nosslsearch-cname-is-a-bad-idea-and-solution.rst modified: 2012-05-19-high-load-on-web-server-after-updating-from-ubuntu-10-04-to-ubuntu-12-04-lts.rst modified: 2012-06-10-always-attempt-to-scale-vertically-first.rst modified: 2012-06-29-miniuri-parser-and-ago-human-timedelta.rst modified: 2013-01-09-ago-py-human-readable-timedelta0-0-4-release.rst modified: 2013-03-02-virt-backs-domfetcher-class-returns-doms-from-libvirt-api.rst modified: 2013-03-22-guido-name-dropped-tornado-python-tulip-and-pep-3156.rst modified: 2013-05-26-honey-i-just-deleted-linkpeek-com.rst modified: 2013-06-20-high-load-and-cpu-usage-craftbukkit-compared-to-vanilla-minecraft.rst modified: 2013-10-19-simplify-deployments-with-upstart-and-uwsgi.rst modified: 2013-10-27-backup-all-virtual-machines-on-a-smartos-hypervisor-with-smart-back-sh.rst modified: 2013-12-13-hackathon-2013-virtualization.rst modified: 2013-12-17-sensu-salt.rst modified: 2014-01-02-test-game-engine-with-python-and-sfml.rst modified: 2014-01-25-how-to-reset-hp-ilo-lights-out-user-and-password-settings-with-ipmitools.rst modified: 2014-02-21-configuration-management-and-the-golden-image.rst modified: 2014-03-08-replace-the-nagios-scheduler-and-nrpe-with-salt-stack.rst modified: 2014-04-08-how-to-patch-heartbleed-openssl-defect-libssl-on-ubuntu.rst modified: 2014-08-23-heka-world2.rst modified: 2014-12-03-custom-rundeck-hipchat-notification-templates.rst modified: 2015-02-22-securely-publish-jenkins-build-artifacts-on-salt-master.rst modified: 2015-05-08-a-python-script-which-searches-for-available-interpreters.rst modified: 2015-11-15-migrating-from-wordpress-to-pelican.rst modified: 2016-06-21-output-all-instance-identifiers-of-an-aws-vpc-to-json.rst modified: 2016-11-21-sharing-a-pyramid-cookie-with-flask-or-tornado.rst
490 lines
13 KiB
ReStructuredText
490 lines
13 KiB
ReStructuredText
Hackathon 2013 Virtualization
|
|
#############################
|
|
:date: 2013-12-13 20:56
|
|
:author: Russell Ballestrini
|
|
:tags: Project
|
|
:slug: hackathon-2013-virtualization
|
|
:status: published
|
|
|
|
As a warning before we dive into things, this post is less of a formal
|
|
publication and more of a stream of conscience.
|
|
|
|
My employer `newcars.com <https://newcars.com/jobs/>`__ has allowed the
|
|
technical staff to host hackathon! Over the past couple weeks I have had
|
|
quite a few ideas tumbling around in my head:
|
|
|
|
- Standup a central logging server
|
|
- Standup Sensu for monitoring
|
|
- Bake-off and document some KVM virtualization hypervisors (Ubuntu or
|
|
SmartOS)
|
|
- Test Docker and document findings
|
|
|
|
Ultimately I have chosen to dedicate my time to testing out
|
|
virtualization on the new Cisco UCS Blade servers. I plan to test Ubuntu
|
|
KVM first.
|
|
|
|
**KVM (Ubuntu 12.04)**
|
|
|
|
I decided to use a Salt-stack configuration management formulas to
|
|
document how I transformed ``kvmtest02`` (a regular Ubuntu 12.04 server)
|
|
into a KVM hypervisor. I use ``kvmtest0a`` and ``kvmtest02b`` when
|
|
refering to the virtual machines living on the hypervisor. Here is the
|
|
formula:
|
|
|
|
**kvm/init.sls:**
|
|
|
|
::
|
|
|
|
# https://help.ubuntu.com/community/KVM
|
|
# Ubuntu server a KVM - Kernel Virtual Machine hypervisor
|
|
|
|
# the official ubuntu document suggests we install the following
|
|
kvm-hypervisor:
|
|
pkg.installed:
|
|
- names:
|
|
- qemu-kvm
|
|
- libvirt-bin
|
|
- ubuntu-vm-builder
|
|
- bridge-utils
|
|
|
|
# we need to make all of our ops people part of the libvirtd group
|
|
# so that they may create and manipulate guests. we skip this for now
|
|
# and assume all virtual machines will be owned by root.
|
|
|
|
# these are optional packages which gives us a GUI for the hypervisor
|
|
virt-manager-and-viewer:
|
|
pkg.installed:
|
|
- names:
|
|
- virt-manager
|
|
- virt-viewer
|
|
- require:
|
|
- pkg: kvm-hypervisor
|
|
|
|
# create a directory to hold virtual machine image files
|
|
kvm-image-dir:
|
|
file.directory:
|
|
- name: /cars/vms
|
|
- user: root
|
|
- group: root
|
|
- mode: 775
|
|
|
|
.. raw:: html
|
|
|
|
</p>
|
|
|
|
I used the following to install the formula to the test hypervisor:
|
|
|
|
::
|
|
|
|
salt 'kvmtest02.example.com' state.highstate
|
|
|
|
.. raw:: html
|
|
|
|
</p>
|
|
|
|
The salt highstate reported everything was good (green), so I moved on
|
|
to setting up the bridge networking interface. At this point I don't
|
|
want to figure out the logistics setting up the network bridge in
|
|
configuration management, so I simply manually edited
|
|
``/etc/network/interfaces`` to look like this (substitute your own
|
|
network values):
|
|
|
|
::
|
|
|
|
|
|
# The loopback network interface
|
|
auto lo
|
|
iface lo inet loopback
|
|
|
|
# The primary network interface
|
|
#auto eth0
|
|
#iface eth0 inet manual
|
|
|
|
# https://help.ubuntu.com/community/KVM/Networking
|
|
# create a bridge so guest VMs may have their own identities
|
|
auto br0
|
|
iface br0 inet static
|
|
address XXX.XX.89.42
|
|
netmask 255.255.255.0
|
|
network XXX.XX.89.0
|
|
broadcast XXX.XX.89.255
|
|
gateway XXX.XX.89.1
|
|
|
|
# dns-* options are implemented by the resolvconf package
|
|
dns-nameservers XXX.XX.254.225 XXX.XX.254.225
|
|
dns-search example.com
|
|
|
|
# bridge_* options are implemented by bridge-utils package
|
|
bridge_ports eth0
|
|
bridge_stp off
|
|
bridge_fd 0
|
|
bridge_maxwait 0
|
|
|
|
Then, I crossed my fingers and reloaded the network stack using this
|
|
command:
|
|
|
|
::
|
|
|
|
/etc/init.d/networking restart
|
|
|
|
I also used this to "bounce" the bridge network interface:
|
|
|
|
::
|
|
|
|
ifdown br0 && ifup br0
|
|
|
|
I verified with ``ifconfig``.
|
|
|
|
I'm ready to create my first VM. There are many different ways to boot
|
|
the VM and install the operating system. KVM is fully virtualized so
|
|
nearly any operating system may be install on the VM.
|
|
|
|
If you have not already, please get familiarized with the following two
|
|
commands:
|
|
|
|
#. virsh
|
|
#. virt-install
|
|
|
|
The ``virsh`` command is an unified tool / API for working with
|
|
hypervisors that support the libvirt library. Currently ``virsh``
|
|
supports Xen, QEmu, KVM, LXC, OpenVZ, VirtualBox and VMware ESX. For
|
|
more information run ``virsh help``.
|
|
|
|
The ``virt-install`` command line tool is used to create new KVM, Xen,
|
|
or Linux container guests using the "libvirt" hypervisor management
|
|
library. For more information run ``man virt-install``.
|
|
|
|
Woah, virsh and virt-install both support LXC?
|
|
|
|
We have decided to only support Ubuntu 12.04 at this time, so obviously
|
|
we will choose that for our guest's OS. Now we need to decide on an
|
|
installation strategy. We may use the following techniques to perform an
|
|
install:
|
|
|
|
- boot from local CD-rom
|
|
- boot from local ISO
|
|
- boot from PXE server on our local vLAN
|
|
- boot from netboot image from anywhere in the world
|
|
|
|
We will choose the PXE boot strategy because our vLAN environment
|
|
already uses that for physical hosts.
|
|
|
|
We will use the ``virt-install`` helper tool to create the virtual
|
|
machine's "hardware" with various flags. Lets document the creation of
|
|
this guest in a simple bash script so we may reference it again in the
|
|
future.
|
|
|
|
/tmp/create-kvmtest02-a.sh:
|
|
|
|
::
|
|
|
|
HOSTNAME=kvmtest02-a
|
|
DOMAIN=example.com
|
|
|
|
sudo virt-install \
|
|
--connect qemu:///system \
|
|
--virt-type kvm \
|
|
--name $HOSTNAME \
|
|
--vcpu 2 \
|
|
--ram 4096 \
|
|
--disk /cars/vms/$HOSTNAME.qcow2,size=20 \
|
|
--os-type linux \
|
|
--graphics vnc \
|
|
--network bridge=br0,mac=RANDOM \
|
|
--autostart \
|
|
--pxe
|
|
|
|
.. raw:: html
|
|
|
|
</p>
|
|
|
|
This was not used, but shows the flags to perform a netboot from
|
|
Internet:
|
|
|
|
::
|
|
|
|
--location=https://archive.ubuntu.com/ubuntu/dists/raring/main/installer-amd64/ \
|
|
--extra-args="auto=true priority=critical keymap=us locale=en_US hostname=$HOSTNAME domain=$DOMAIN url=http://192.168.1.22/my-debconf-preseed.txt"
|
|
|
|
.. raw:: html
|
|
|
|
</p>
|
|
|
|
I created the vm:
|
|
|
|
::
|
|
|
|
bash /tmp/create-kvmtest02-a.sh
|
|
|
|
.. raw:: html
|
|
|
|
</p>
|
|
|
|
``virt-install`` drops you into the "console" of the VM, but this will
|
|
not work yet, so we use ctrl+] to break out and get back to our
|
|
hypervisor. Use ``virsh list`` to list all the currently running VMs.
|
|
|
|
Lets use ``virt-viewer`` to view the VMs display. For this we need to
|
|
SSH to the hypervisor and forward our display to our workstation, we do
|
|
this with the ``-X`` flag. For example:
|
|
|
|
::
|
|
|
|
|
|
ssh -X kvmtest02
|
|
|
|
Now we can launch ``virt-viewer`` on the remote hypervisor, and the GUI
|
|
will be drawn on our local X display!
|
|
|
|
::
|
|
|
|
|
|
virt-viewer kvmtest02-a
|
|
|
|
Once I got that to work, I also tested ``virt-manager`` which gives a
|
|
GUI to control all guests on the remote hypervisor.
|
|
|
|
::
|
|
|
|
|
|
virt-manager
|
|
|
|
.. raw:: html
|
|
|
|
</p>
|
|
|
|
Now we need to determine the auto-generated MAC Address of the new
|
|
virtual machine.
|
|
|
|
::
|
|
|
|
virsh dumpxml kvmtest02-a | grep -i "mac "
|
|
mac address='52:54:00:47:86:8e'
|
|
|
|
We need to add this MAC address to our PXE server's DHCP configuration
|
|
to allocate the IP and tell it where to PXE-boot from.
|
|
|
|
During a real deployment we would get an IP address allocated and an A
|
|
record and PTR setup for new servers. This is a test and I will be
|
|
destroying all traces of this virtual machine after presenting during
|
|
the hackathon, so for now I'm going to skip the DNS entries and "steal"
|
|
an IP address. I must be VERY careful not to use an IP address already
|
|
in production. First use dig to find an IP without a record, then
|
|
attempt to ping and use NMAP on the IP.
|
|
|
|
::
|
|
|
|
dig -x XXX.XX.89.240 +short
|
|
ping XXX.XX.89.240
|
|
nmap XXX.XX.89.240 -PN
|
|
|
|
The IP address checked out, it didn't have a PTR, it didn't respond to
|
|
pings, and using nmap proved there were no open ports. I'm very
|
|
confident this IP address is not in use.
|
|
|
|
I added a record to our DHCP / PXE server for this Virtual Machine. I
|
|
attempted multiple times to pxe boot the VM, but the network stack was
|
|
never automatically configured... The DHCP server was discovering the
|
|
new VMs MAC and offering the proper IP address, as noted by these log
|
|
lines:
|
|
|
|
::
|
|
|
|
Dec 13 07:57:43 pxeserver60 dhcpd: DHCPDISCOVER from 52:54:00:47:86:8e via eth0
|
|
Dec 13 07:57:43 pxeserver60 dhcpd: DHCPOFFER on xxx.xx.89.240 to 52:54:00:47:86:8e via eth0
|
|
Dec 13 07:57:44 pxeserver60 dhcpd: DHCPDISCOVER from 52:54:00:47:86:8e via eth0
|
|
Dec 13 07:57:44 pxeserver60 dhcpd: DHCPOFFER on xxx.xx.89.240 to 52:54:00:47:86:8e via eth0
|
|
Dec 13 07:57:48 pxeserver60 dhcpd: DHCPDISCOVER from 52:54:00:47:86:8e via eth0
|
|
Dec 13 07:57:48 pxeserver60 dhcpd: DHCPOFFER on xxx.xx.89.240 to 52:54:00:47:86:8e via eth0
|
|
|
|
I wasted about 4 hours attempting to troubleshoot and diagnose why the
|
|
VM wouldn't work with DHCP. I ended the night without any guests
|
|
online...
|
|
|
|
**The Next DAY!**
|
|
|
|
So today I decided to stop trying to get DHCP and PXE working. I
|
|
downloaded an Ubuntu server ISO to the hypervisor, and used
|
|
``virt-manager`` to mount the ISO on the guest and booted for a manual
|
|
operating system install.
|
|
|
|
This did two things, it proved that the hypervisor's network bridge
|
|
``br0`` worked for static network assigned settings and that something
|
|
between the DHCP server and the hypervisor was preventing the
|
|
``DHCPOFFER`` answer from getting back to the VM. I looked into iptables
|
|
firewall, removed apparmor, removed SELINUX and reviewed countless logs
|
|
looking for hints... then moved on...
|
|
|
|
I was able to get salt-minion installed on the vm using our
|
|
post-install-salt-minion.sh script, which I manually downloaded from the
|
|
salt master. But to keep this test self contained, I pointed the VM's
|
|
salt-minion to ``kvmtest02`` which we already had setup as a test
|
|
salt-master.
|
|
|
|
The salt-master saw the salt-minion's key right away, so I decided to
|
|
target an install. This what I applied to the VM:
|
|
|
|
salt/top.sls:
|
|
|
|
::
|
|
|
|
'kvmtest02.example.com':
|
|
- kvm
|
|
|
|
'kvmtest02b.example.com':
|
|
- virtualenv
|
|
- python-ldap
|
|
- nginx
|
|
- the-gateway
|
|
|
|
salt-pillar/top.sls
|
|
|
|
::
|
|
|
|
# kvmtest02b gateway in a VM experiment
|
|
'kvmtest02b.example.com':
|
|
- nginx
|
|
- the-gateway.alpha
|
|
- deployment-keys.the-gateway-alpha
|
|
|
|
.. raw:: html
|
|
|
|
</p>
|
|
|
|
The stack was successfully deployed to the VM and proved that virtual
|
|
machines are a viable solution for stage or production. It also gave me
|
|
the change to test out this particular deployment again and found a few
|
|
gotchas we need to create maintenance tickets for.
|
|
|
|
Without configuration management, it would have taken weeks to deploy
|
|
this custom application stack. The install with configuration management
|
|
took less then 10 minutes!
|
|
|
|
One of the KVM related snags I ran into was that Nginx does some fun
|
|
calculations with cpu cache to determine hash table sizes. As a
|
|
temporary work around, until I can devote more research time, I raised
|
|
up the following three hash table directives in the http section of
|
|
nginx.conf:
|
|
|
|
::
|
|
|
|
server_names_hash_bucket_size 512;
|
|
types_hash_bucket_size 512;
|
|
types_hash_max_size 4096;
|
|
|
|
.. raw:: html
|
|
|
|
</p>
|
|
|
|
**SmartOS**
|
|
|
|
**snippet from /etc/dhcp/dhcpd.conf**
|
|
|
|
::
|
|
|
|
# SmartOS hypervisor group to boot image
|
|
group "smartos-hypervisors" {
|
|
next-server xxx.xx.89.71;
|
|
|
|
host smrtest01-eth0 {
|
|
hardware ethernet 00:25:B5:02:07:DF;
|
|
option host-name "ncstest01";
|
|
fixed-address smrtest01.example.com;
|
|
|
|
if exists user-class and option user-class = "iPXE" {
|
|
filename = "smartos/menu.ipxe";
|
|
} else {
|
|
filename = "smartos/undionly.kpxe";
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
::
|
|
|
|
mkdir /cars/tftp/smartos
|
|
cd /cars/tftp/smartos
|
|
wget http://boot.ipxe.org/undionly.kpxe
|
|
wget https://download.joyent.com/pub/iso/platform-latest.tgz
|
|
tar -xzvf platform-latest.tgz
|
|
mv platform-20130629T040542Z 20130629T040542Z
|
|
mkdir platform
|
|
mv i86pc/ platform/
|
|
|
|
create boot menu that we referenced,
|
|
``vim /cars/tftp/smartos/menu.ipxe``
|
|
|
|
::
|
|
|
|
#!ipxe
|
|
|
|
kernel /smartos/20130629T040542Z/platform/i86pc/kernel/amd64/unix
|
|
initrd /smartos/20130629T040542Z/platform/i86pc/amd64/boot_archive
|
|
boot
|
|
|
|
Make sure to replace platform version with current.
|
|
|
|
I was able to get the blade server to PXE boot the image, but it seems
|
|
SmartOS doesn't really support the SANs. SmartOS really expects to see
|
|
local disks, and to build a ZFS pool on top of that. Basically SmartOS
|
|
could be used to build a SAN, so they didn't put much effort in
|
|
supporting SANs. After I figured this out I abandoned this test. We
|
|
could revist this again, using one of the Dell servers, or use it to
|
|
stand up a really powerful Alpha server environment.
|
|
|
|
**LXC**
|
|
|
|
Run /usr/bin/httpd in a linux container guest (LXC). Resource usage is
|
|
capped at 512 MB of ram and 2 host cpus:
|
|
|
|
::
|
|
|
|
virt-install \
|
|
--connect lxc:/// \
|
|
--name lxctest02-a \
|
|
--ram 512 \
|
|
--vcpus 2 \
|
|
--init /usr/bin/httpd
|
|
|
|
.. raw:: html
|
|
|
|
</p>
|
|
|
|
**Discussion points**
|
|
|
|
- Why doesn't DHCP work on bridge?
|
|
- If we use virtualization, we need to come up with a plan for IP
|
|
addresses, like possibly allocate ~5 IP addresses to a hypervisor
|
|
host
|
|
- We need to come up with a naming convention for guests, in testing I
|
|
appended a letter to the hypervisor name ``kvmtest02`` so the guests
|
|
names were ``kvmtest02a`` and ``kvmtest02b``, is this plausible going
|
|
forward?
|
|
|
|
**If I had more time ...**
|
|
|
|
.. raw:: html
|
|
|
|
<ul>
|
|
<li>
|
|
|
|
I would have liked to test out LXC
|
|
|
|
.. raw:: html
|
|
|
|
</li>
|
|
<li>
|
|
|
|
I would have liked to test out Docker
|
|
|
|
.. raw:: html
|
|
|
|
</li>
|
|
<li>
|
|
|
|
I would have liked to test out physical to virtual migrations
|
|
|
|
.. raw:: html
|
|
|
|
</li>
|
|
</p>
|