четверг, 20 июня 2013 г.

Виртуалки из шаблонов и DDNS

Практически в любой полноценной системе виртуализации есть весьма удобная фича - шаблоны, которые позволяют развертывать большое количество виртуалок с минимальными телодвижениями. Но, как правило, после запуска подобных "клонированных"  виртуалок требуется их донастройка - имя хоста, пароли, настройки сети и т.п. (механизм sysprep для винды и /.unconfigured для rhel/centos/fedora и подобные).
А как развернуть 100500 linux-based виртуалок, которые различаются только именем хоста и сетевыми настройками, быстро да без пользовательского участия? Решение для oVirt под катом.

Общая идея - создать виртуалку-эталон с нужным софтом и настройками, сделать из нее шаблон, из шаблона наплодить 100500 нужных виртуалок, которым раздавать сетевые настройки через dhcp, а hostname брать из имени виртуалки и регистрировать его в dynDNS.
Есть только одна неувязка - "имя виртуалки" по-дефолту ниге внутри гостевой системы не фигурирует. Но эту проблему можно решить, поможет нам в этом VDSM-Hooks в oVirt-е.
Я написал хук, который заполняет поле 'SKU Number' в system information разделе биоса гостевой системы (т.к. он по-дефолту не используется) именем виртуальной машины:

#!/usr/bin/python

import os
import sys
import hooking
import traceback

'''
vmname inject vdsm hook
====================
hook is getting VM name and writes it into bios 'SKU Number' field.
'''

if True:
    try:
        domxml = hooking.read_domxml()
        names = domxml.getElementsByTagName('name')[0]
        vmname = names.childNodes[0].nodeValue
        system = domxml.getElementsByTagName('system')[0]
        entry = domxml.createElement('entry')
        entry.setAttribute('name','sku')
        text = domxml.createTextNode(vmname)
        entry.appendChild(text)
        system.appendChild(entry)
        hooking.write_domxml(domxml)

    except:
        sys.stderr.write('name-inject: [unexpected error]: %s\n' %
                         traceback.format_exc())
        sys.exit(2)


Его необходимо выложить в /usr/libexec/vdsm/hooks/before_vm_start/ на всех нодах кластера, выполнятся он будет каждый раз перед запуском любой виртуалки.
Теперь внутри гостевой системы можно получить имя виртуальной машины, прочитав информацию о биосе командой dmidecode.
Дальше - дело техники. Имя виртуалки есть - его можно использовать при старте в качестве hostname и отдать dhcp-клиенту, чтобы с ним он зарегистрировался в DNS.
Я использую для этого такой скрипт:

#!/bin/bash
# Start the sysprep from template
#
# chkconfig: 2345 9 20
# description: Sets hostname and network configuration from 'SKU Number' bios field

case "$1" in
start)
        if [ -f /.template ];
        then
                vmname=`dmidecode | grep 'SKU' | awk '{print $3}'`
                echo "send fqdn.fqdn $vmname" >> /etc/dhcp/dhclient-eth0.conf
                rm -f /.template
        fi
        chkconfig sysprep off
        RETVAL=0
        ;;
stop|status|reload|force-reload)
        RETVAL=0
        ;;
*)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|force-reload}"
        RETVAL=2
esac

exit $RETVAL


При подготовке виртуалки-шаблона необходимо сделать следующие действия:
  • Установить необходимый софт и произвести нужные настройки (кроме сети)
  • Удалить /etc/udev/rules.d/*-persistent-*.rules , /etc/ssh/ssh_host*
  • В /etc/sysconfig/network выставить hostname=localhost.localdomain (чтобы dhclient мог изменить его на значение, полученное от dhcp-сервера)
  • В /etc/sysconfig/network-scripts/ifcfg-eth* удалить все уникальные идентификаторы - MAC, UUID и т.п., BOOTPROTO="dhcp"
  • Добавить в /etc/init.d/ вышепреведенный скрипт, включить его в автозапуск (chkconfig <scriptname> on)
  • Создать файлик /.templatе
  • Выключить виртуалку
После создания виртуалки из такого шаблона, при первом запуске произойдет следующее:
  • vdsm-hook добавит в биос имя виртуалки
  • перед запуском сети запустится скрипт, который прочитает из биоса имя виртуалки и запишет его в конфиг dhclient-а
  • при инициализации сети dhcp-клиент передаст fqdn=<имя виртуалки> dhcp-серверу, тот зарегистрирует его в DNS (если, конечно это разрешено) и передаст сетевые настройки (в т.ч. тот же hostname) клиенту
  • dhcp-клиент применит полученные настройки - hostname, ip/mask/gate и т.п. 
  • ...
  • PROFIT!

Комментариев нет:

Отправить комментарий