Cloud Management – Teil 1: blkdeviotune/migrate-setmaxdowntime

This entry is part 1 of 2 in the series Cloud Management

Viele von euch haben bestimmt schon einmal von OpenNebula oder OpenStack gehört, beiden Plattformen verwenden standardmäßig libvirtd als Hypervisor, da jedoch die darunter liegende Hardware mit unter stark beansprucht werden wird, vor allem im Cloud Bereich, wo mehrerer KVM Instanzen auf einem Virt Host um CPU/Speicher/IO Resourcen konkurrieren, ist es gelegentlich notwendig die einen oder andere Instanz zu bändigen bzw. in die Schranken zu weisen.

Unsere Cloud läuft derzeit noch mit OpenNebula, wir selbst sind sehr zufrieden mit dem Stack, da sich dieser leicht Verwalten lässt und sich auch gut mit unserem Ceph als Backend verträgt, natürlich verwenden wir in unserem Cloud Stack noch andere Tools, diese sind aber nicht Gegenstand dieses Artikels, mehr dazu in späteren Teilen der Serie.

Libvirtd kann mit CLI Tools wie virsh gesteuert werden, auch besteht die Möglichkeit libvirtd über die entsprechende libvirt C API oder durch seine ScriptLanguage Bindings für ruby/python/perl/javascript/etc… anzusprechen bzw. anzusteuern zu können.

So beispielsweise unterstützt man OpenNebula wenn die Migration einer KVM Instanz von Virt Host A zu Virt Host B aufgrund von Last auf der Instanz selbst partout nicht klappen will…

root@virt1: ~ $ virsh migrate-setmaxdowntime --downtime 1800 one-8366
error: Requested operation is not valid: domain is not being migrated (dieser Fehler kommt nur wenn sich die Instanz nich im Status Migrate befindet, ist hier also nur exemplarisch mit abgebildet)

…oder wenn die Instanz AMOK läuft und somit andere Instanzen zu stark beeinträchtigt…

root@virt1: ~ $ virsh blkdeviotune one-8366 vda --live
total_bytes_sec: 62914560
read_bytes_sec : 0
write_bytes_sec: 0
total_iops_sec : 400
read_iops_sec  : 0
write_iops_sec : 0

…dann limitieren wir diese einfach ein bisschen…

root@virt1: ~ $ virsh blkdeviotune one-8366 vda --live 62914560 0 0 200 0 0

…und vergewissern uns nochmal ob unsere neuen IOPs Limits übernommen wurden…

root@virt1: ~ $ virsh blkdeviotune one-8366 vda --live
total_bytes_sec: 62914560
read_bytes_sec : 0
write_bytes_sec: 0
total_iops_sec : 200
read_iops_sec  : 0
write_iops_sec : 0

…ich denke, damit sollte klar sein worauf wir hier abzielen möchten.

In folgenden Teilen dieser Serie werden wir euch noch mehr Tips & Tricks mit auf den Weg geben, die helfen sollen eure Cloud zu bändigen bzw. aufkommende Probleme anzugehen, also bleibt gespannt. 😉

Enrico Labedzki

Autor: Enrico Labedzki

Enrico ist beruflich ganz schön rumgekommen – IT hat ihn aber immer beschäftigt. Nach einem Ausflug in die Selbstständigkeit im Bereich Webentwicklung und Network Solutions, wurde es dann Zeit Nägel mit Köpfen zu machen und endlich den Weg als Softwareentwickler und Systemintegrator einzuschlagen. In seiner Freizeit widmet sich der passionierte Bastler der Elektrotechnik und Animatronik. Bei Netways bereichert er mit seinem vielseitigen Know-How das Managed Service-Team.

Getting started Opennebula API

In wenigen Tagen starten die OpenNebula Techdays welche von Netways gesponsort werden. Da auf diesen einige interessante Dinge gezeigt werden gibt es hier jetzt eine kleine Einführung in die API.

Wenn man die API von OpenNebula benutzen möchte, gibt es zwei Möglichkeiten. Einmal “RPC XML” und zweitens mit einem Ruby Binding. In meinem Beispiel werde ich mich auf das Ruby Binding beziehen.

Um mit der API rumspielen zu können benötigen wir erstmal eine passende OpenNebula Umgebung. Hierfür können wir uns ganz einfach eine vorinstallierte VM als VirtualBox image herunterladen.

Um nun auch auf die API zugreifen zu können, muss man noch eine Portweiterleitung für den Port “26330” einrichten (Port 9869 ist optional, sollte man auch auf das Web-interface zugreifen wollen). Die Weiterleitung kann unter Setting > Network > Advanced > Port Forwarding eingerichtet werden.

Jetzt kann man anfangen sich gegen die API zu connecten. Als erstes fügt man die benötigten Ruby Gems hinzu. Dies wird mit

require 'opennebula'
include OpenNebula

gemacht.

Danach erstellt man Variablen für die login credentials und den Endpoint. Ich benutze dafür die default Username und Passwort Kombination.

CREDENTIALS = "oneadmin:opennebula"
ENDPOINT    = "http://<DeineVBoxIP>:26330/RPC2"

 

Nachdem dies erledigt ist, kann man eine Verbindung zur API festlegen. Hierfür legt man wieder eine Variable fest. (Bitte beachtet, das die credentials und endpoint variablen genauso heißen, wie oben festgelegt!)

client = Client.new(CREDENTIALS, ENDPOINT)

 

Als nächstes initialisiert man den Virtual Maschine Pool. Dafür wird die Variable vm_pool angelegt.

vm_pool = VirtualMaschinePool.new(client, -1)

 

Um mögliche Fehler abzufangen kann man eine kurze Fehlerabfrage einrichten. Diese gibt uns, im Falle eines Fehlers, gleich den richtigen Fehler Code zurück.

rc = vm_pool.info
if OpenNebula.is_error?(rc)
     puts rc.message
     exit -1
end

 

Damit jetzt jede Virtuelle Maschine gestoppt wird, richtet man eine kleine Schleife ein die uns pro VM, die sich im vm_pool befindet, eine Funktion ausführt.

vm_pool.each do |vm|
     rc = vm.shutdown
end

 

Mit der oben eingerichteten Fehlerabfrage kann man sich hier auch gleich noch den aktuellen Status bzw eine Success oder Fehlermeldung ausgeben lassen. Dafür fügt man ein paar Zeilen zu seiner Schleife hinzu.

vm_pool.each do |vm|
     rc = vm.shutdown
     if OpenNebula.is_error?(rc)
          puts "Virtual Machine #{vm.id}: #{rc.message}"
     else
          puts "Virtual Machine #{vm.id}: Shutting down"
     end
end

 

Das ganze noch mit einem sauberen

exit 0

abschließen und das erste Script ist fertig!

 

Um das Endprodukt testen zu können, muss man noch eine VM in OpenNebula erstellen. Hierfür kann man ein schon vorgefertigte Template nutzen.

OpenNebula API

Dieses einfach instantiieren und warten bis die VM hochgefahren ist. (Meist ca 10 Sekunden).

Wenn man jetzt das Ruby Script ausführt sollten man folgende Ausgabe erhalten:

Virtual Machine 1: Shutting down

 

Wie man an diesem Beispiel sehen kann, ist es sehr einfach eigene Scripte für Opennebula zu schreiben. Noch mehr spannende Dinge gibt es auf den diesjährigen TechDays!

Kay Probst

Autor: Kay Probst

Nachdem ihm sein Praktikum bei uns gefallen hat, kam Kay im September 2015 zu NETWAYS, um seine Ausbildung zum Fachinformatiker für Systemintegration zu beginnen. Er kann es schon jetzt kaum abwarten, bald an eigenen Projekten arbeiten zu dürfen. Auch privat beschäftigt er sich mit dem Computer und versetzt sich bei diversen Computerspielen gerne in andere Charaktere hinein.

Drei Wege um virtuelle Maschinen zu migrieren

OpenNebulaConf Grafiken 09Neue Storage-Lösungen sprießen wie Tulpen im Frühling aus dem Boden. Jede einzelne ist flexibler, schlanker und hochverfügbarer.
Da kommt meine Cloud ins Spiel, die eigentlich gut läuft aber so ein schnelleres Storage ist eine willkommene Abwechslung.

So ein neues Storage ist schnell aufgesetzt, was uns dann aber vor eine neue Aufgabe stellt,
denn unsere VMs laufen… nur nicht auf unserem hippen Storage.

Nun gibt es diverse Methoden um eine virtuelle Maschine in ein neues Image bzw. neues Storage zu transferieren.

Da haben wir zum einen die altbewährte Methode, mit dem Urgestein aller blockorientierten Kopiervorgänge dd.
Dazu muss die virtuelle Maschine komplett ausgeschaltet sein. Da sich der Zustand der VMs nicht mehr ändert, kann man beruhigt die VM kopieren.

dd if=/path/to/input/file of=/path/to/output/file bs=4096

Zum anderen die Methode ein qcow2 Image in ein Blockdevice zu schreiben.
In Worten gesagt: das Image wird mit “qemu-img convert” in Raw umgewandelt und danach mit dd auf das neue Blockdevice kopiert. (Auch hier sollte die VM nicht mehr laufen!)

qemu-img convert -p -f qcow2 -O raw /path/to/input/file /path/to/outputfile.raw && dd if=/path/to/outputfile.raw of=/path/of/device bs=4M

Da die beiden genannten Arten eine lange Downtime benötigen, sind sie nur für VMs geeignet die nicht zeitkritisch sind.

Ein UNIX System kann mit guten Kenntnissen, mit relativ kurzer Ausfallszeit migriert werden. Ein hilfreiches Werkzeug dabei ist Rsync.

Leider kann ich hierzu kein fixes Beispiel vorzeigen, da die einzelnen Schritte von System zu System unterschiedlich ausfallen.

Die essentiellen Schritte sind:

1. Neues Device in der VM mounten und das gewünschte Filesystem erstellen.
2. Systemverzeichnisse auf dem neuen Device erstellen.
3. Das komplette System mit Rsync auf das neue Device kopieren. Hier muss man natürlich etwas aufpassen und Verzeichnisse wie /proc oder ggf. /mnt exkludieren. Auch auf bind Mounts sollte man achten, damit man Daten nicht ausversehen doppelt kopiert.
4. Die grub.cfg natürlich im neuen /boot Pfad aktualisieren. (grub-install und update-grub sind hierfür hilfreich)
5. Das “alte Device” als read-only einbinden und die neue fstab anpassen.
6. Und last but not least, einen weiteren Rsync in dem die restlichen Files auf das neue Image übertragen werden. (auch hier bitte das Exkludieren von wichtigen Pfaden nicht vergessen. z.B.: /etc/fstab oder auch /boot !!)

Der Vorteil hierbei ist: die Downtime erstreckt sich dabei nur über den zweiten Rsync, bei dem die Festplatte im “read-only” Modus ist.

Habt Ihr weitere coole Möglichkeiten einen VM zu migrieren?
Dann dürft ihr euch in den Kommentaren dazu äußern.

Oder seid Ihr interessiert an dem Thema Cloud und alles was damit zu tun hat? Dann besucht uns einfach auf der OpenNebula Conf 2014

Thilo Wening

Autor: Thilo Wening

Thilo hat bei NETWAYS mit der Ausbildung zum Fachinformatiker, Schwerpunkt Systemadministration begonnen und unterstützt nun nach erfolgreich bestandener Prüfung tatkräftig die Kollegen im Consulting. In seiner Freizeit ist er athletisch in der Senkrechten unterwegs und stählt seine Muskeln beim Bouldern. Als richtiger Profi macht er das natürlich am liebsten in der Natur und geht nur noch in Ausnahmefällen in die Kletterhalle.

Virtualisierung stoppen!

Trotz der provokativem Überschrift werde ich einer der letzten sein, der dafür plädiert weniger zu virtualisieren – ganz im Gegenteil. In Zeiten von IaaS, PaaS, SaaS geht eigentlich nichts ohne Virtualsierung. Ob Vollvirtualsierung, Paravirtualisierung oder Container-based-Virtualisierung die Möglichkeiten sind nahezu grenzenlos, die aufsetzenden Frameworks unzählig.

In produktiven Umgebungen mit hoher und unterschiedlichster Workload und viel gemeinsam genutzten Infrastrukturkomponenten bzw. Ressourcen ist es deshalb umso wichtiger einzelne virtuelle Maschinen oder Container zu “stoppen” besser gesagt zu drosseln. Natürlich kann man mit mehr Hardware aufkeimende Engpässe entsprechend ausdehnen. Oft sind aber kleine und ungewollte Verhalten der Auslöser für querschießende Prozesse, die parallel ausgeführte Maschinen beeinflussen und somit die Qualität des generellen Services beeinflussen.

Drosseln kann man u.a. CPU Zeit, Memory, IO auf Blockdevices, IO auf NICs. Wie immer gibt es mehrere Möglichkeiten entsprechende Limits zu setzen. Pauschal lässt sich mit cgroups über die Virtualsierungstechnologien hinweg gut und effizient drosseln. Für KVM bzw. Qemu sind die eingebauten Features die effizientesten. Beim aktiven Drosseln muss der CPU des Hosts entsprechend arbeiten und ist laut IBM hier einen Tick effizienter bei Qemu-capped im Vergleich zu cgroup-capped.

KVM Prozesse können mit libvirt auch zur Laufzeit gedrosselt werden. Die Bandbreite der ersten Festplatte einer KVM-VM würde man mit Hilfe von virsh wie folgt auf 10MB/s und 50iops drosseln:

virsh blkdeviotune $virshid $name --live $total_bytes_sec $total_iops_sec
virsh blkdeviotune 123 vda --live 10240000 50

Das Cloud-Computing Framework OpenNebula wird in seiner nächsten Version ebenfalls Funktionen zur Drosselung bereitstellen.

Wem das alles zu umständlich ist, nutzt einfach das folgende funktionierende aber nicht ganz ernstgemeinte Command:
while true; do kill -STOP $ID; sleep 1; kill -CONT $ID; done

Sebastian Saemann

Autor: Sebastian Saemann

Sepp kam von einem großen deutschen Hostingprovider zu NETWAYS, weil ihm dort zu langweilig war. Bei uns kann er sich nun besser verwirklichen, denn er leitet zusammen mit Martin das Managed Services Team. Wenn er nicht gerade Server in MCollective einbindet, versucht er mit seinem Motorrad einen neuen Geschwindigkeitsrekord aufzustellen.

Docker

Die Devops-Tool-Chain hat seit einiger Zeit ein sehr interessantes neues Tool mit dem Namen “Docker”. Docker erfährt einen regelrechten Hype um sich, wobei die Meinungen um das Tool durchaus gemischt sind. Einen Blick ist es auf jeden Fall Wert. Aber was ist Docker eigentlich?

Docker ist ein Open-Source-Framework, das leichtgewichtige, portable, LXC-Container bereitstellt und steuert, die praktisch überall laufen können. Eine Anwendung kann also problemlos auf einem Laptop des Entwicklers, oder in großen Produktionsumgebungen auf Bare-Metal oder in der Cloud laufen. Das mit dem überall beschränkt sich dann aber doch auf einen Linux-Kernel mit LXC, aber das wiederum kann praktisch überall laufen. Die Use-Cases sind die Automatisierung von Deployments, das Bereitstellen von PaaS/SaaS Services, automatisierte Continuous-Integration-Tests und die Skalierung von Anwendungen. Spätestens jetzt ruft der erste “Bingo” beim Buzzword-Bingo.

In anderen Worten ist Docker ein Tool, vergleichbar mit Vagrant, mit dem sich Anwendungen einfach über Umgebungen hinweg portieren lassen.

docker run ubuntu /bin/echo hello world

Tatsächlich ist das aufgezeigte Beispiel vielleicht etwas ernüchternd: es gibt bei Erfolg lediglich “hello world” auf einer neuen Zeile zurück. Tatsächlich passiert aber viel mehr. Das Image ‘ubuntu’ wird heruntergeladen – wenn es nicht bereits lokal vorhanden ist – und in einem LXC-Container gestartet. In diesem wiederum wird /bin/echo ausgeführt und anschließend beendet sich der Container wieder.

Ein Container wird immer aus einem Image erzeugt und läuft so lange die Anwendung läuft – wird diese beendet, beendet sich auch der Container. Images sind über Repositories, bei Bedarf auch eigenen Repositories, verfügbar. Ähnlich wie mit Git lassen sich diese Images steuern. docker commit, docker pull, docker push erstellen neue Images und laden diese hoch bzw. runter.

docker run -i -t ubuntu /bin/bash
docker commit $ID my_fancy_app
docker run -p 80:3000 my_fancy_app rails server

In dem Beispiel wird ein LXC-Container mit Ubuntu gestartet mit einer interaktiven Shell. In der Sitzung installiert man seine Anwendung. Eleganter ist ein Dockerfile, dass das automatisch vornimmt. In dem Beispiel wird eine Ruby-on-Rails-Anwendung installiert und mit dem commit Befehl anschließend ein neues Image erzeugt. Nebenbei bemerkt: docker diff zeigt den Unterschied zum initialen Container. Abschließend wird das neue Image in einem neuem Container mit einer Portweiterleitung von 80 auf 3000 und der Anwendung (Webrick) gestartet. Die Anwendung ist dann unter der $IP:80 auf dem System, dass den Container hosted, verfügbar. Die Anwendung bzw. der Container kann jetzt beliebig oft sekundenschnell gestartet werden, solange der Netzwerkport natürlich nicht doppelt belegt wird. Der Container ist jetzt in der Lage auf jedem System gestartet zu werden, dabei ist es egal ob es eine Amazon AWS VM, KVM/XEN VM, Bare-Metal oder Virtualbox(Vagrant) ist.

Seine Container kann man auch mit Puppet steuern, verteilen und starten.

docker::run { 'my_app':
image => 'my_fancy_app',
command => 'rails start',
ports => ['80', '443'],
}

Zusammenfassend ist Docker ein geniales Framework für einige bestimmte Anwendungsfälle. Ich bin begeistert.

Mehr Information findet man auf docker.io

Sebastian Saemann

Autor: Sebastian Saemann

Sepp kam von einem großen deutschen Hostingprovider zu NETWAYS, weil ihm dort zu langweilig war. Bei uns kann er sich nun besser verwirklichen, denn er leitet zusammen mit Martin das Managed Services Team. Wenn er nicht gerade Server in MCollective einbindet, versucht er mit seinem Motorrad einen neuen Geschwindigkeitsrekord aufzustellen.

Rückblick auf ein Jahr mit der Cloud

Rückblick auf ein Jahr mit der Cloud

Laut den Mayas geht 2012, also schon in ein paar Tagen, die Welt unter! Bevor es zu spät ist möchte ich deshalb noch die Gelegenheit nutzen über das vergangene Jahr, insbesondere über die Erfahrungen mit OpenNebula als private Cloud, zu berichten.

Zum Jahresbeginn starteten wir mit dem Ziel eine private Cloud für uns und unsere Kunden in unserem Rechenzentrum betreiben zu können. Am Ende der Evaluierungsphase stellte sich OpenNebula für uns als die richtige Lösung dar und bis jetzt haben wir die Entscheidung noch nicht bereut. OpenNebula ist ein starkes Open-Source Projekt, dass sich besonders durch seine stetige und rasante Weiterentwicklung auszeichnet. Mittlerweile ist das Projekt auch regelmäßiger Gast auf unseren Konferenzen und OpenNebula wurde mit in unser Schulungsportfolio aufgenommen. Die gute Partnerschaft zwischen uns und OpenNebula hält für das kommende Jahr voraussichtlich noch einige Überraschungen parat. Selbstverständlich erfährt man auf unserem Blog als Erster davon – solange die Gerüchteküche nicht schneller ist.

Unsere private Cloud ging mit der Version 3.2 in den Produktivbetrieb. Das Setup ist so ausgelegt, dass jeder Host sowohl ein Wirt-System als auch das OpenNebula-Frontend als Rolle übernehmen kann. Die Logik übernimmt hierfür Pacemaker auf Basis von Corosync. Das zentrale Storage war zu Beginn ein iSCSI-Export mit OCFS2, das in der Betaphase auch jeden Failover-Fall mitgemacht hat, sobald es allerdings produktiv war, kam es zu nicht deterministischen Problemen, weshalb wir in einer nächtlichen Wartung das OCFS2 durch NFS ersetzt haben.

Ein weiteres Problem trat auf als der Dienst libvirtd, mit dem OpenNebula die VMs auf den Hosts überwacht und bei Bedarf auf einem anderen Node neustartet, seinen Dienst auf einem Host mit Segfault quittiert hat. Daraufhin hat OpenNebula die vermeintlich als down deklarierten VMs doppelt auf den anderen Hosts gestartet. Aufgrund dessen haben wir uns einen Ressource Agent zur Überwachung von libvirtd geschrieben und diesen mit in die Kontrolle von Pacemaker übergeben. Würde das Problem wieder auftreten würde Pacemaker den entsprechenden Host mit allen VMs und Diensten mit Hilfe von STONITH hart neustarten (Strom aus).

Auf die Resource Agents ist leider auch nicht immer Verlass. Nach einem System Update wurde der RA, der sich um das STONITH kümmert, vom Paketbetreuer mit einem Syntaxfehler im Bash-Skript ausgerollt, was natürlich erst auffiel, als ein Host gefenced werden sollte.

Zu guter Letzt gab es natürlich immer noch das berühmte Layer 8 Problem. Auf Details verzichte an dieser Stelle aber lieber 🙂

Zusammenfassend kann man also sagen, OpenNebula hat sich verhalten wie es soll und es hat eher die Infrastruktur drum herum bzw. die Software Probleme gemacht. Nach der Fehlerbeseitung der Kinderkrankheiten läuft unsere private Cloud nun performant und sehr zuverlässig. Auch das Update auf 3.4, mit dem die multiplen Datastores eingezogen sind, und später auf 3.6 waren ohne größeren Komplikationen möglich.

Mittlerweile hat sich die Anzahl unserer Wirt-System verdoppelt und auch die Anzahl an produktiven VMs nimmt stetig zu. Die Erweiterung der Cloud um weitere Host-Systeme ist dank Puppet und den hierfür geschriebenen Puppetmodulen einfach und schnell möglich. Hosts von VMs via Livemigration zu befreien, um Wartung am Host-System vornehmen zu können (Livemigration), Ressourcen-Allozierung (CPU,Memory,Quotas) und die sekundengenau Berechnung der benötigten Ressourcen für das Accounting sind nur einige herausstechende Funktionen, die uns die Arbeit erleichtern und neue Möglichkeiten zur Administration bereitstellen.

Unser Auszubildender Marcus hat uns für seine Abschlussprüfung eine kleine Cloud als Staging-Umgebung und Spielwiese zur Verfügung gestellt, so dass wir zukünftig Updates und Features vorher ausgiebig testen können. Mit Ozones ist dann auch die zentrale Steuerung mehrerer Clouds möglich.

Zukünftig stehen natürlich weitere Updates aus, sowie die Möglichkeit unseren Kunden Zugriff zu gewähren und hoffentlich auch der stetige Ausbau der Cloud-Infrastruktur durch Neukunden und Wachstum unserer bestehenden. Die Aussichten sehen jedenfalls gut aus.

Insgesamt und trotz der anfänglichen Schwierigkeiten ist das Projekt “private Cloud” ein voller Erfolg und OpenNebula hat sich für uns als eine sehr gute Wahl entpuppt.

Sebastian Saemann

Autor: Sebastian Saemann

Sepp kam von einem großen deutschen Hostingprovider zu NETWAYS, weil ihm dort zu langweilig war. Bei uns kann er sich nun besser verwirklichen, denn er leitet zusammen mit Martin das Managed Services Team. Wenn er nicht gerade Server in MCollective einbindet, versucht er mit seinem Motorrad einen neuen Geschwindigkeitsrekord aufzustellen.