Open phish108 opened 3 years ago
Mit uvtool
bzw. uvt-kvm
ist diese Konfiguration etwas einfacher.
Dazu muss uvtool
und uvtool-libvirt
im system installiert sein.
https://ubuntu.com/server/docs/virtualization-uvt
http://manpages.ubuntu.com/manpages/trusty/man1/uvt-kvm.1.html
Folgende Schritte:
uvt-simplestreams-libvirt sync arch=amd64 release=groovy
(den release filter kann man auch weglassen, dann werden alle aktiven releases geladen). uvt-kvm create --cpu 2 \
--memory 2048 \
--user-data cloud_init.cfg \
$HOSTNAME \
release=groovy
Mit uvt-kvm ip $HOSTNAME
kann die IP der VM abgefragt werden.
Mit uvt-kvm ssh --insecure $HOSTNAME
kann man sich auf den Host verbinden.
Dieser Ansatz verbindet die Vorteile von VMs mit denen von Docker Containern. Im Gegensatz zu sog. Anwendungscontainern (Docker), sind LXC/LXD Container sog. System Container. D.h. man isoliert das Betriebssystem oberhalb des LINUX-Kernels. Dadurch spart man die Ressourcen, die ein virtualisierter Kernel benötigt. Ausserdem ist diese Technik speichersparender, weil nur ein Kernel für alle Systeme auf dem Host läuft.
Der Vorteil von lxc
/ lxd
ist, dass diese Tools auf Ubuntu Server vorinstalliert sind. Ähnlich wie die VM Cloud Images, kann LXD die verwendeten Container Images im Hintergrund aktualisieren, so dass das Starten eines Systemcontainers umso schneller geht.
Um diese Art der Virtualisierung zu nutzen, muss lxd
mit lxd init
initialisiert werden. lxd init
stellt anschliessend ein paar Fragen über die Grundeinstellungen des Systems. Wichtig ist hierbei, dass bei den Fragen zum Netzwerk, der Typ mit bridged
und das Netzwerkdevice analog zu #5 (z.B. ovs0
) angegeben wird.
Wir können das default Profil von LXD mit lxc profile show default
anzeigen lassen. Das Profil können wir später mit lxc profile edit default
auch anpassen. In LXD ist das Profil die Basiseinstellung für die Systemcontainer. Hier legen wir i.d.R. die Hardware-Bedingungen fest.
Anschliessend können virtuelle Hosts als LXC Container mit den folgenden Schritten gestartet werden.
1. > UBUNTUVERSION="20.10"
2. > HOSTNAME=$(petname)
3. > lxc init ubuntu:$UBUNTUVERSION $HOSTNAME
4. > cat cloud_init.cfg | sed s/HOSTNAME/$HOSTNAME/ | lxc config set $HOSTNAME user.user-data -
5. > lxc start $HOSTNAME
In Schritt 1 und 2 parametrisieren wir das System.
In Schritt 3 wird der Systemcontainer mit dem entsprechenden Image initialisiert aber nicht gestartet. Dieser Schritt dauert ein paar Augenblicke, wenn das LXC Image noch nicht auf dem System vorhanden ist. In diesem Fall wird der Download-Fortschritt angezeigt.
In Schritt 4 übergeben wir dem Container die cloud-init
Konfiguration, die wir für die KVM
Lösung erstellt haben. Wir müssen lediglich den Wert HOSTNAME
gegen den Namen der VM mit sed
austauschen. Das Ergebnis speichern wir dann im Container.
In Schritt 5 starten wir den Container. Jetzt wird unsere cloud-init Konfiguration ausgeführt und das virtuelle System eingerichtet.
Mit dem Befehl lxc list
erhalten wir eine Übersicht über alle laufenden Container auf dem jeweiligen Host bzw. im Cluster. Dieser befehlt liefert uns auch die IP4 und IP6-Adressen des Containers.
Anschliessend können wir uns mit ssh
auf das jeweilige System verbinden.
Alternativ können wir uns mit lxc exec $HOSTNAME /bin/bash
als Superuser (root
) in einem LXC Container anmelden. Das funktioniert auch dann, wenn das System ohne Netzwerk installiert ist oder der cloud-init
Prozess fehlgeschlagen hat.
Wir stoppen einen Container mit lxc stop $HOSTNAME
.
Wir löschen einen gestoppten Container mit lxc delete $HOSTNAME
Damit auf einer VM die richtige Software installiert ist, können wir mit der packages
-Liste in unserem Cloud-Init user-data
zusätzliche Pakete installieren. Dabei müssen wir aber darauf achten, das wir die Quellen updaten. Das erreichen wir mit package_update: true
.
Die Basis für die Installation der virtuellen Systeme findet sich in der Datei tools/install-vm.sh
.
Damit die Hosts aus dem Internet konsistent erreichbar sind, ist es notwendig, dass sie einheitliche IP Adressen erhalten.
Das kann zum einen über die Host ID erfolgen oder über die MAC Adresse des Rechners. Weil die System Container keine echte MAC Adresse haben muss diese für jeden von aussen erreichbaren Container hartkodiert werden.
Für LXC Container werden MAC Adressen im Range 00:16:3e:XX:XX:XX
verwendet. Wir müssen 12 Adressen in diesem Range für unsere externen Verbindungen fixieren, damit diese im System festgehalten werden können. Das Problem ist, dass diese MAX Adressen zwar feste erhalten, aber andere Hosts können diese Adressen zufällig treffen. Dagegen können wir uns leider nicht absichern. :/KI
Dieser Beitrag beschreibt zwei Vorgehensweisen, um über die Shell zufällige MAC-Adressen zu generieren.
https://superuser.com/questions/218340/how-to-generate-a-valid-random-mac-address-with-bash-shell
Für die Generierung der 12 Adressen habe ich basierend auf den Vorschlägen im von phish108 erwähnten Beitrag das folgende kleine Shellscript geschrieben und ausgeführt.
#!/bin/bash
LC_CTYPE=C
MAC=00-16-3e
for i in {1..12}
do
echo $MAC$(hexdump -n3 -e '/1 "-%02X"' /dev/random)
done
-n3 definiert die Anzahl. zu lesender Bytes: Hier sind es 3 '/1' heisst, die Formatierung soll für jedes gelesene Byte gelten. "-%02X" ist eine printf Spezifikation. Sie legt für unser Beispiel eine führende Null, gefolgt von 2 grossgeschriebenen Hex-Ziffern fest. /dev/random ist das erzeugte Zufallsbyte.
Mit dem Linux Kommando chmod u+x 'Pfad/Dateiname'
wird das Shellscript ausführbar gemacht und mit ```bash 'Pfad/Dateiname' ausgeführt.
Dies sind 12 mit dem Script generierte MAC Adressen
00-16-3e-A2-2F-46
00-16-3e-69-62-E8
00-16-3e-4B-54-16
00-16-3e-C9-CD-F2
00-16-3e-62-12-2E
00-16-3e-6E-B4-EB
00-16-3e-B7-DF-35
00-16-3e-A7-2C-71
00-16-3e-6A-1C-1A
00-16-3e-61-3C-06
00-16-3e-7D-A7-92
00-16-3e-83-65-56
Die Mac-Adressen hier sind natürlich Fake. Der korrekte Generator findet sich im Tools-Verzeichnis
Damit alles funktioniert müssen die folgenden Packete auf einer fristen Ubuntu Installation vorhanden sein.
Um einen Virtual host mit qemu/libvirt aufzusetzen verwenden wir nicht die normale ISO live CD. Stattdessen müssen wir ein "cloud-image" verwenden.
Die offiziellen Ubuntu Cloud Images gibt es direkt bei Ubuntu Cloud Images. Auf dieser Seite werden die aktuell unterstützten Ubuntu Versionen als vorinstallierte Festplattenabbilder, als sog. Images, angeboten. Von diesen Images können wir unsere virtuellen Maschinen direkt booten. Wichtig ist dass nicht das KVM Disk Image verwendet wird, sondern immer die Datei
<VERSIONSNAME>-server-clouding-amd64.img
geladen wird. Das KVM Disk Image funktioniert die Hälfte der Zeit nicht richtig.Dazu verwendet man am besten
curl -O IMAGE-URL
wie im folgenden Beispiel:Diese Instanzen können wir mit Cloud-Init konfigurieren, so dass wir sehr schnell vorkonfigurierte Instanzen erstellen können.
Ich habe die folgenden Anleitungen verwendet, bis ich eine virtuelle Maschine erfolgreich gebootet habe.
Für eine erfolgreiche Konfiguration müssen die folgenden Punkte berücksichtigt werden:
password
mit der Nutzereinrichtung vermischt werden.Die folgenden Schritte sind für die Installation notwendig:
Die
CloudInit
-Konfiguration erstellen und in die folgende Datei schreibencloud_init.cfg
. Diese Datei kann beliebige Konfigurationen haben aber minimal ungefähr so aussehen.Das Coole ist hier, dass wir mit den auf Github hinterlegten SSH Schlüsseln auf die neue Maschine zugreifen können. Diese Konfiguration übernimmt automatisch alle SSH Schlüssel. Mit Ansible sollten wir zusätzlich sicherstellen, dass die Schlüssel regelmässig mit
ssh-import-id
aktualisiert werden.Wir sollten immer einen separaten Ansible User anlegen, so dass wir im nächsten Schritt die Installation vervollständigen können. Nach der Installation kann dann direkt die eigentliche Systemkonfiguration mit Ansible vorgenommen werden.
Mit der Cloud-Init Datei konfigurieren wir die VM beim ersten booten.
Das Passwort sollte nicht mit einem dynamisch erzeugten Seed gehasht werden. Damit entfällt der Schritt das Seed zu berechnen.
Die harte Tour
Auf die harte Tour müssen wir jetzt noch das seed Image erstellen. Ich empfehle die im Kommentar beschriebene Technik mit uvt-kvm.
Anschliessend kann die VM mit dem folgenden Befehl gestartet werden:
Die installation sollte nach ein paar Sekunden abgeschlossen sein.
Mit
virsh domifaddr $HOSTNAME
erhalten wir die IP-Adresse der Maschine. Damit können wir uns mit SSH auf die VM verbinden.Andere wichtige
virsh
-Befehle:virsh shutdown $HOSTNAME
kann die VM beendet werden.virsh destroy $HOSTNAME
erzwingt das Beenden der VM.virsh undefine $HOSTNAME
entfernt die VM aus dem System (sobald diese nicht mehr läuft).