Eine Frage an die Systemadministranten: Wie lange dauert es, einen neuen Server aufzusetzen? So mit allem drum und dran? 5 Stunden? 5 Tage? Wie waere es mit 5 Minuten?!
Folgendes Rezept zeigt die vollstaendige Virtualisierung und Automatisierung einer Systemlandschaft am Beispiel eine Installation von Joomla. 5 Minuten nach Auftragseingang soll der komplette Server mit Webpraesenz am Netz sein.
Los gehts:
Zutaten:
Vorbereitungen:
Die (einmaligen) Vorbereitungen nehmen schon einen gewaltigen Zeiraum ein. Man muss sich immer wieder fragen: Welche Installationsschritte muessen gemacht werden, welche Handlangertaetigkeiten gehoeren automatisiert. Der Weg zur Standardisierung lohnt sich aber. Am Ende werden wir nicht nur eine virtuelle Linux-Server-Instanz installiert haben, sondern ein hochdynamisches System besitzen, welches muehelos erweitert und angepasst werden kann.
Installation XenServer: Die Software kommt auf bootfaehiger CD daher und moechte mindestens auf einer extra Festplattenpartition installiert werden. Bei der interaktiven Installation wird man nach IP-Adresse und festzulendes Admin-Passwort gefragt. Alles recht unspektakulaer. Wenn das XenCenter gestartet ist, bekommt man ein spartanisches Menue im DOS-Style zur Verfuegung gestellt. Man kann aber per HTTP und Browser auf die IP des XenServer zugreifen und von dort einen komfortablen Windows-Client herunterladen. Die Kommunikation mit dem XenServer erfolgt so ueber WEB und https-Verschluesselung
Konfiguration XenServer: Die Administration von Resourcen ist bei allen Virtualisierungsloesungen gleich (Vmware, Xen, AWS...):
Um unsere virtuelle Instanz "puppetmaster" installieren zu koennen, tauschen wir die XenServer-Install-CD gegen eine OpenSUSE-Install-DVD in unserem physikalischen CD-Laufwerk. Im XenServer definieren wir ausserdem 2 Netzwerke:
Unser "puppetmaster" bekommt auch 2 Netzwerk-Interface, 1 CPU, 6 GB Festplatte und ca. 512 MB RAM. Ueber den WIndows-Client laesst sich das recht komfortabel mit "New VM" zusammenklicken. Die Installation des Betriebssystems kann man im Consolen-Fenster der GUI durchfuehren. Am Schluss sollten wir einen Systemprompt und ssh-Zugriff auf den Rechner haben, um die restlichen Arbeiten ueber ein xterm oder putty durchfuehren zu koennen. WIr geben dem Rechner die IP-Adresse 192.168.0.10 fuer eth0 (Netzwerk 0) und 192.168.88.1 fuer eth1 (Install LAN). Defaultgateway soll 192.168.0.1 sein. Darueber gelangt der Rechner auch ins Internet.
Ueber das XenCenter sollte das CD-Laufwerk dem Host "puppetmaster" zugaenglich gemacht sein. Unter der Option "Storage" koennen wir dies kontrollieren (DVD Drive 0 on ...). Wenn dort die OpenSUSE-DVD drin liegt, koennen wir mit
mount /dev/dvd /mnt
auf "puppetmaster" die Installations-DVD mounten.Wir koennen auch das ISO-File downloaden und mit der loop-Option mounten:
mount -o loop
openSUSE-12.1-DVD-i586.iso /mnt/
Das Install-Medium machen wir durch unseren Webserver zugreifbar: /etc/apache2/conf.d/puppetmaster.conf
Alias /mnt/ "/mnt/"
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
chkconfig apache2 on && rcapache2 start
Jetzt sollten wir ueber http://puppetmaster/mnt auf das Installmedium zugreifen koennen.
Fuer die weiteren Virtual Machines erstellen wir uns am besten auf dem XenServer ein Template namens "autoyast". Diesem geben wir die Resource 1 CPU, 512 MB RAM, 6 GB Festplatte aber KEIN Netzwerk! Das konfigurieren wir spaeter dazu. Es sind mindestens 512 MB noetig fuer YAST, das ist sehr gefraessig. Wenn wir weniger RAM konfigurieren, bricht die Installation irgendwann mal mit "exit code 137" ab und nach langem Suchen auf tty3 finden wir Melduingen zu "out of memory". Das sollte man sich ersparen. Ausserdem stellen wir die Boot-Reihenfolge in unserem Template auf
Wir leben in der Annahme, dass auf der Festplatte kein boot-faehiges Betriebssystem installiert ist und dann immer von Netzwerk gebootet wird, um ein boot-faehiges Betriebssystem zu installieren. Anderenfalls muesste man mit Boot-Options im dhcpd arbeiten. Das geht zwar auch, ist aber nicht so toll. Wenn diese Massnahmen NICHT getroffen werden, kommt es zum Boot-Loop: Das System wird wieder und wieder neu installiert, weil es nicht mehr aus der Schleife rauskommt.
Installation DHCP:
zypper install dhcp-server
Konfiguration DHCP:
/etc/dhcpd.conf:
option domain-name-servers 192.168.88.1;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none; ddns-updates off;
log-facility local7;
subnet 192.168.88.0 netmask 255.255.255.0 {
range 192.168.88.100 192.168.88.200;
next-server 192.168.88.1;
allow booting;
allow bootp;
option routers 192.168.88.1; <br /> filename "pxelinux.0";
}
chkconfig dhcpd on && rcdhcpd start
Installation TFTP:
zypper install tftp
Konfiguration TFTP:
/etc/xinetd.d/tftp:
service tftp
{
socket_type = dgram
protocol = udp
wait = yes
flags = IPv6 IPv4
user = root
server = /usr/sbin/in.tftpd
server_args = -s /srv/tftp/pxelinux.cfg
disable = no
}
mkdir /srv/tftp/pxelinux.cfg && chkconfig xinetd on && rcxinetd start
Installation Booloader + AutoYast:
zypper install syslinux autoyast2 autoyast2-installation
cp /usr/share/syslinux/pxelinux.0 /srv/tftp/pxelinux.cfg/pxelinux.0
/srv/tftp/pxelinux.cfg/pxelinux.cfg/default
default linux
label linux
kernel linux
append initrd=initrd install=http://192.168.88.1/mnt/ autoyast=http://192.168.88.1/suse12.xml loghost=192.168.88.1
prompt 1
timeout 10
Die Konfiguration von Autoyast ist hier beschrieben. Es gibt auch viele nuetzliche Links und Beispiele. In einer Mailingliste findet man die meisten Antworten. Unser Autoyast-File heisst also suse12.xml und liegt auf dem Webserver des puppetserver. EIne Version befindet sich im Anhang des Postings. Was wird alles gemacht:
Eine POST-Scripte sind im xml enthalten, eines wird vom Webserver gezogen. myPostScript.sh haengt ebenfalls am Posting dran. Wir installieren die zwei rpm-Pakete fuer puppet von unserem puppet-server, da sie aus unerfindlichen Gruenden nicht auf dem normalen Repository zu finden sind. Mit
/usr/bin/puppet agent --test
klopfen wir am puppetmaster an. Der Default-Hostname in der Grundinstallation heisst "puppet". Wenn wir diesen im DNS auf unseren puppetmaster zeigen lassen, wird automatisch die richtige Verbindung hergestellt. Zum erfolgreichen Verbindungsaufbau muessen allerdings SSL-Zertifikate ausgetauscht und signiert werden. Mit unserem --test-Aufruf haben wir schon mal einen Zertifikatrequest an den puppetmaster geschickt. Dieser muss den anfragenden Host nun signieren. An dieser Stelle waere also wieder Handarbeit notwendig. Abhilfe schafft ein cron-Eintrag auf dem puppetmaster:
*/5 * * * * /usr/bin/puppet cert sign --all
Nicht sehr schick. Hier fehlt noch ein Shell/Perl-Script, was das Vorhandensein von neuen Zertifikat-Requests prueft und nur dann eine SIgnierung durchfuehrt.
puppet fragt zyklisch beim puppetmaster an, ob es etwas zu tun gibt. Wenn das Zertfikat signiert ist, hat die Verbindung Erfolg und unser Client holt seine Aufgaben ab. Aber welche?
puppet bekommen wir entweder als rpm wie in unserem autoyast-Script, oder als Source von http://puppetlabs.com/ . Es gibt immer eine kommerzielle und eine Freeware-Version. In der kommerziellen ist mehr Support und ein Dashboard dabei. Auf unserem puppetmaster-Server brauchen wir einen puppetmasterd-Prozess. Entsprechende Start-Scripts finden wir im Source-Paket. Zur Installation brauchen wir ruby. Die eigentliche Konfiguration finden sich in /etc/puppet - wie auf allen puppet-Clients auch. DIe Zertifikate liegen in einem anderen Verzeichnis. Wenn irgendwann mal was schiefgegangen ist und die Zertifizierung nicht klappen will, kann man den ganzen Kram auch loeschen:
find /var/lib/puppet -type f -print0 |xargs -0r rm
Danach ist eine neue Ausstellung von Zertifikaten und dessen Signierung notwendig - wenn sich z.B. der Hostname geaendert hat und die Konfig im puppet eh nicht mehr passt.
Die weitere Konfiguration unterteilt sich in modules und maniefests.
module sind zum Beispiel "apache" und desen Konfiguration liegt in einem eigenen Unterverzeichnis. Dort gibt es ein weiteres Unterverzeichnis "files". Das sind Dateien, die wir von puppet verwalten wollen. Da ist zum Beispiel
Im Unterverzeichnis "manifests" gibt es eine init.pp:
class apache2 {
Package { ensure => "installed" }
$enhancers = [ "apache2", "apache2-mod_php5", "apache2-mod_perl" ]
package { $enhancers: }
# package { apache2: ensure => latest}
# package { apache2-mod_php5: ensure => latest }
file { "/etc/apache2/vhosts.d/vhost.conf":
notify => Service["apache2"], # this sets up the relationship
ensure => "present",
source => [
"puppet:///modules/apache2/vhost.conf"
],
}
file { "/etc/sysconfig/apache2":
notify => Service["apache2"], # this sets up the relationship
ensure => "present",
source => [
"puppet:///modules/apache2/apache2"
],
}
# create a directory
file { "/srv/www/hallo.welt.eumel.local/":
ensure => "directory",
}
file { "/srv/www/hallo.welt.eumel.local/index.html":
ensure => "present",
source => [
"puppet:///modules/apache2/hallowelt.cnt"
],
}
# define the service to restart
service { "apache2":
ensure => "running",
enable => "true",
require => Package["apache2"],
}
}
Die Syntax ist eigentlich recht selbsterklaerend:
Damit passiert jetzt folgendes:
Es passiert nicht weniger. Aber auch nicht mehr. Wenn anderen Konfigurationsdateien geaendert werden, obliegt das nicht in der Hoheit von puppet sie zurueckzuaendern - wenn sie nicht im maniefest irgendwo hinterlegt sind.
So kann man dann mit einzelnen Diensten beispielsweise /etc/passwd oder sudo-Eintraegen fortfahren. Alle Konfigurationsparameter sind auf http://www.puppetcookbook.com beschrieben.
Noch ein letzter Tip fuer die Installation. WIr machen unserem Vhost den Garaus:
dd if=/dev/zero of=/dev/sda1 bs=512 count=1
Das sind bis jetzt aber nur die Arbeiten im Hintergrund. Fuer unsere Kunden muss man noch ein passables Frontend zur Verfuegung stellen. Eine gute Veranlagung fuer die Verbindung der einzelnen Komponenten ist Cobbler. Hier ist eine Anleitung fuer OpenSuSE. Cobbler ist in erster Linie ein Frontend fuer Fedora, was aber auch mit anderen Betriebssystemen kompatibel ist. Leider erfuellt es nicht ganz die Beduerfnisse des Szenarios, was wir uns oben schon aufgebaut haben. SO fehlt zum Beispiel die Anbindung an unser XenCenter. Klar kann man das auch irgendwie in Cobbler implementieren, aber mit CodeIgniter habe ich selbst ein Frontend fuer unseren puppetmaster geschrieben. Es arbeitet zustandlos, speichert also keine Passwoerter oder Daten und kann die API des XEN-Centers bedienen. Eine Vorab-Version befindet sich im Anhang.
Damit waere das Rezept fuer unsere 5-Minuten-Terrine abgeschlossen. Aaaaber, leider kommt noch ein Aber zum Schluss ;)
Leider haben wir unterwegs unsere neue Maschine verloren. Der Server wuerde vom Netz booten, bekommt eine zufaellige IP-Adresse, fuer den fehlen die Rezepte im puppet, der Endanwender kriegt niemals mit, ob die neue Maschine verfuegbar ist, wie sie heisst und wie er sich einloggen kann.
Also, ToDo's:
Fazit: Ein bischen was gibt es noch zu tun. Den Beweis der erfolgreichen Installation bleibe ich diesmal noch schuldig B)