VM Anlegen

vSphere – API

Bezugnehmend zu einem älteren Artikel hier auf dem Blog, wo ich bereits auf die allgemeine Intergration der vSphere SOAP API  eingegangen bin, handelt der heutige Artikel über das Anlegen von neuen virtuellen Maschinen auf einem ausgewählten Datastore. Für das Anlegen einer VM wird wie im vorherigen Beitrag auf das Community-SDK vmwarephp eingegangen, welches sich aus verschiedenen Quellen wie z.B. Github beziehen lässt.

Definition der Komponenten

Eine einzelne VM zu erstellen ist keine simple Aufgabe, wenn die vSphere-Dokumentation keine genauen Informationen dazu gibt, welche Übergabeparameter mit welchen Attributen befüllt sein müssen. Oftmals stößt man dahingehend eher auf der Suche nach exakt der Möglichkeit VMs zu erstellen auf das klonen von VMs. Genaue Informationen zum Erstellen der VMs ohne ein vordefiniertes Template oder eine bereits existente VM gibt es nicht. Dahingehend habe ich mir die Mühe genommen, dessen Arbeitablauf für eine Integration durch PHP zu verfolgen und zu implementieren.

In erster Linie besteht eine VM aus mehreren Teilkomponenten die voneinander abhängig sind. Ein Name und jeweilige Spezifikationen rund um Arbeitsspeicher und CPU sind nicht ausreichend. Dahingehend werden mehrere Komponenten benötigt um eine VM erstellen zu können.

Bestandteile einer VM

Eine VM besteht aus einigen Grundlegenden Objekten innerhalb von vSphere. Dahingehend nenne ich hier die Pflichtfelder um eine VM anlegen zu können. Nun woraus besteht nun eigentlich eine VM in vSphere, welche Klassen benötigen ich dafür?  Diese Frage lässt sich relativ simpel beantworten:

  1. Eine VM besteht immer aus einer Config Klasse die von der Methode „CreateVM_Task“ erwartet wird. Diese Konfiguration spezifiert die Eigenschaften der jeweiligen VM.
  2. Die Konfiguration der VM besteht aus den Hardware- wie auch Softwareinformationen, sprich sie gibt an wieviel Arbeitsspeicher, Festplattenspeicher und CPU-Cores eine VM nutzen darf. Ebenso wird darin spezifiert welches Betriebssystem eingesetzt werden soll.
  3. Die eigentliche Konfiguration (VirtualMachineConfigSpec) wiederum besteht aus weiteren Objekten die von einander abhängig sind:
    1. VirtualMachineFileInfo
    2. VirtualDeviceConfigSpec
    3. VirtualDevice
    4. VirtualDiskFlatVer2BackingInfo
  4. Einige der in Punkt 3 angegebenen Klassen sind abhängig von entsprechenden „Foldern“ und „Datastores“.

 

 VM erstellen mittels PHP

Um nun nachdem einige Kerninformationen genannt sind, werde ich hier anhand eines Beispiels die Implementation einer VM Erstellung aufzeigen. Bevor allerdings eine VM tatsächlich erstellt werden kann, muss eine Konfiguration für diese erstellt werden.

Jede VM hat mindestens eine Virtualdisk, welche im Rahmen der VM die Harddisk darstellt. Jedes der virtuellen Disks ordnet sich in die Gruppe VirtualDevice ein. Ein VirtualDevice kann eine Harddisk sein oder als anderes Beispiel ein CD-Laufwerk o.ä. Diese Spezifikation treffen Sie innerhalb des Parts „VirtualDevice“. Eine VirtualDisk stellt ein Kernelement der virtuellen Maschine dar.  Dahingehend müssen Sie erst einmal den Typen eines virtuellen Devices spezifieren. Dazu haben Sie folgende Möglichkeiten die vSphere Ihnen bietet:

 

Typ-Definition

Ich möchte in meinem Beispiel nun eine Harddisk anlegen für eine virtuelle Maschine die ich im nachhinein erstellen werde, dahingehend wähle ich die Klasse „VirtualDiskFlatVer2BackingInfo“. Diese Klasse erwartet zwei Parameter die ich setzen muss, damit im Nachgang, sobald die VM erstellt wird kein Fehler auftritt. Diese beiden Parameter sind:

 

Diskmode gibt wie das neue Laufwerk einzubinden ist. Filename dagegen gibt an auf welchem Datastore sich die jeweilige virtuelle Harddisk befinden soll. Dahingehend müssen Sie ermitteln welche Datastores  Sie zur Verfügung haben:

 

$oVhost = new \Vmwarephp\Vhost(
            "<ip-addresse:port>",
            "<username>",
            "<password>"
);
$aDatastores = $oVhost->findAllManagedObjects("Datastore", array());

In der Variable „aDatastores“ finden Sie nun ein Array von Datastore Objekten, die Sie durchiterieren können. An den realen Namen wie er auch im vSphere angezeigt wird kommen Sie über das Attribut „name“ ran. Der FileName muss innerhalb von eckigen Klammern definiert werden, um das Datastore zu spezifieren.

$name = $aDatastores[0]->name;

Anschließend erstellen Sie das Objekt.

$oBackingInfo = new VirtualDiskFlatVer2BackingInfo();
$oBackingInfo->diskMode = "persistent";
$oBackingInfo->fileName = "[".(string)$oDatastores[4]->name."]";

VirtualDevice spezifieren

Im Nachgang, nachdem Sie festgelegt haben, welche Art von VirtualDevice Sie anlegen möchten, müssen Sie das entsprechende VirtualDevice formen. Dieses VirtualDevice benötigt, aufgrund des Typs „Harddisk“ bzw.  VirtualDiskFlatVer2BackingInfo eine Größe, welche definiert wie groß dieses Laufwerk sein muss, wie aber auch die eigentliche BackingInformation und eine UnitNumber sowie einen Key:

 

 

 

$oVirtualDevice = new VirtualDevice();

$oVirtualDevice->backing = $oBackingInfo;
$oVirtualDevice->unitNumber = 0;
$oVirtualDevice->capacityInKB = 10485760; // 10 GB
$oVirtualDevice->key = 0;

In diesem Fall wird die Harddisk auf eine Größe von 10 GB begrenzt.

Als nächstes muss VmWare / vSphere mitgeteilt werden, wie es das neue VirtualDevice behandeln soll. Dies passiert über die Klasse „VirtualDeviceConfigSpec“.

$oVirtualDeviceConfigSpec = new VirtualDeviceConfigSpec();
$oVirtualDeviceConfigSpec->operation = "add";
$oVirtualDeviceConfigSpec->device = $oVirtualDevice;

Anhand dieses Objekts spezifiziere ich, dass das neue VirtualDevice hinzugefügt werden soll, zu den bisherigen (im Falle einer Erstellung der VM die erste und neue).

 

Definition des Filesystems

Nun wo im Grunde genommen spezifiziert ist, wie die neue Harddisk auszusehen hat, und es als VirtualDevice in einem einzelnen Objekt zusammen gefasst ist, muss dem vSphere bekannt gemacht werden wie der VM-Pfad auf dem lokalen Datastore aussieht. Dies passiert über ein neues Objekt der Klasse VirtualMachineFileInfo.

 

$oVirtualMachineFileInfo = new VirtualMachineFileInfo();
$name = (string)$oDatastores[0]->name;
$oVirtualMachineFileInfo->vmPathName = "[".$name."]";

Wichtiger Hinweis: an dieser Stelle, vmPathName erwartet die vmx Datei. Diese muss auf dem gleichen Datastore wie die eigentliche VM liegen. Auch an dieser Stelle wird das Datastore spezifiert um VmWare / vSphere die Wahl des Dateinamens zu überlassen.

 

Erzeugen der Basis-Konfiguration

Als fast letzter Schritt muss ein Config-Objekt von der Klasse „VirtualMachineConfigSpec“ erzeugt werden. Dieses Objekt wird von der Methode „CreateVM_Task“ erwartet. Bei welcher folgende Attribute Pflichtfelder sind:

 

 

$oConfigSpec = new VirtualMachineConfigSpec();
$oConfigSpec->files = $oVirtualMachineFileInfo;
$oConfigSpec->name = "testvm3";
$oConfigSpec->memoryMB = 512;
$oConfigSpec->memoryHotAddEnabled = true;
$oConfigSpec->numCPUs = 1;
$oConfigSpec->deviceChange = array($oVirtualDeviceConfigSpec);
$oConfigSpec->cpuHotAddEnabled = true;
$oConfigSpec->guestId = "otherLinuxGuest";

In diesem Beispiel setze ich den Namen auf testvm3″ den verfügbaren Arbeitsspeicher auf 1GB, die Anzahl von CPUs auf 1 sowie die jeweiligen virtuellen Devices. Weiterer Aspekt ist das Attribut „memoryHotAddEnabled“ sowie „cpuHotAddEnabled“, welches spezifiziert, dass während des Betriebs der VM dynamisch Arbeitsspeicher und einzelne CPUs hinzugefügt werden können.

Abschließend als letzter Punkt, definiere ich die guestId welches das verwendete Betriebssystem angibt. Ohne dieses Attribut, wird diese VM nicht gestartet werden können. Eine Liste der verfügbaren GuestIds findet sich hier für die Version 5.5.

 

VM Erstellen

Bevor nun endlich eine VM erstellt werden kann, muss als letzter Schritt der Folder in dem die VM hinterlegt wird definiert werden, sowie aber auch und ein RessourcePool. Dazu lassen sich alle Folder sowie Ressourcepools wie folgt abholen:

 

 

//Folders
$aFolders = $oVhost->findAllManagedObjects("Folder", array());

//Ressourcepool
$aRessourcepool = $oVhost->findAllManagedObjects("ResourcePool", array());

Beide Variablen sind Arrays, einerseits des Typs „Folder“ und andererseits des Typs „RessourcePool„.

 

Anschließend mit z.B. dem ersten Element im Array „aFolders“ und dem ersten Pool in „aRessourcepool“ lässt sich die eben spezifierte VM anlegen:

 

$oTask  = $aFolders[0]->CreateVM_Task(array(
    "config" => $oConfigSpec,
    "pool" => $aRessourcepool[0]->reference,
));

Im Anschluss liefert das vSphere ein Objekt der Klasse „Task“ zurück.