Eigene VM Images erzeugen

(english version see here)

Azure bietet eine Vielzahl an Images für neue VMs (aktuell mehr als 800). Aber manchmal möchte man dann vielleicht doch ein eigenes Image für neue VMs verwenden. Ganz aktuell könnte es zum Beispiel sein, dass ein Wunsch-Image noch nicht in der Microsoft Cloud Deutschland zur Verfügung steht, und man echt nicht mehr warten möchte und unbedingt schon mal anfangen will und nach einem Weg sucht… Nun, ein Wort der Warnung ist hier angebracht: Klar kann man das machen, aber für einen produktiven Einsatz bitte unbedingt auf einem freigegebenen Image in der Microsoft Cloud Deutschland aufsetzen. Das hier ist nur zum warm werden…

Wir nehmen als Beispiel ein Ubuntu-Image, und da wir kein eigenes haben, nehmen wir das in der Public Azure Cloud bereitgestellte und tun so, als ob wir das angepasst haben und in der Microsoft Cloud Deutschland verwenden möchten…

Wie gehen wir vor? Die grobe Abfolge ist:

  1. Neue Ubuntu-VM in der Public Azure Cloud erzeugen
  2. für das Image vorbereiten
  3. VHD kopieren in die Microsoft Cloud Deutschland
  4. neue Ubuntu-VM in Microsoft Cloud Deutschland erzeugen

Dann mal los:

Neue Ubuntu-VM in der Public Cloud erzeugen

Wir erzeugen uns eine klassische VM mit einem Service, der folgende Einzeiler sollte klar sein, oder? Das verwendete Image kann ja variieren, ich hab mal 12.4.5 genommen:

$image="b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-12_04_5_LTS-amd64-server-20150413-en-us-30GB"
New-AzureQuickVM -Linux -Name "ubuntu-image" -Servicename "ubuntu-service"
-Imagename $image –Linuxuser "superman" -Password "P@ssw0rd!"
-Location "West Europe" -Instancesize Small

Image vorbereiten

Wir loggen uns einmal per SSH ein, die Adresse finden wir über die folgenden Zeilen:

$vm=Get-AzureVM -Name "ubuntu-image" -Servicename "ubuntu-service"
$vm | Get-AzureEndpoint

…und nutzen hierbei die Angaben bei Vip und Port. Sinn macht’s natürlich auch, zu warten, bis die VM fertig gestartet ist. Kaum sind wir angemeldet, bereiten wir die VM auf ihr Image-Dasein vor:

sudo waagent –deprovision
sudo init 0

und schon ist unsere Verbindung wieder weg. Jetzt die folgenden Kommandos, um die VM wieder zu entfernen und den Blob freizubekommen. Azure betrachtet das VHD-Blob als OS-Disk, und um diese AzureDisk zu entfernen, brauchen wir den Namen. Den bekommen wir einfacher, solange die VM noch existiert, wir haben ja weiter oben zum Glück die VM im $vm-Objekt gespeichert.

$diskname = $vm.VM.OSVirtualHardDisk.DiskName
$vm | Stop-AzureVM
$vm | Remove-AzureVM
Remove-AzureDisk –DiskName $diskname

Bitte dran denken, die VM zu entfernen, aber nicht das VHD-Blob, also auf keinen Fall –DeleteVHD anhängen, das wäre jetzt blöd.

VHD kopieren

Wir haben jetzt also noch ein Blob übrig mit der VHD, und das kopieren wir rüber in unsere neue Umgebung. Wie das geht, kann man entweder in meinem entsprechenden Blogartikel nachlesen, oder man verwendet ein Tool wie den CloudBerry Storage Explorer, der auch direkt zwischen Clouds kopieren kann. Ich überspringe das jetzt mal der Einfachheit halber und beschränke mich auf Stichpunkte:

  • StorageKey des alten und des neuen StorageAccounts ermitteln
  • StorageContext für die alte und für die neue Umgebung erzeugen
  • Container und Name der alten Umgebung ermitteln
  • Container der neuen Umgebung anlegen
  • Name für das neue Blob ausdenken
  • Start-CopyAzureStorageBlob verwenden

Noch ein kleiner Hinweis: Blobs können eigentlich nicht umbenannt werden, sondern das ist ein Kopieren und Löschen. Man spart sich also Arbeit, wenn man gleich auf den neuen Namen kopiert, wenn man eh schon am Kopieren ist…

Image erzeugen

Jetzt kommen wir zum eigentlichen Punkt, nämlich das kopierte VHD-Blob als Image anzulegen, um es für neue VMs verwenden zu können. Die Vorarbeit haben wir ja schon gemacht, nämlich das Deprovisioning. Das komplizierte ist jetzt nur noch, alle erforderlichen Angaben zusammen zu bekommen.

Für unser Beispiel hier nehmen wir mal an, das neue StorageAccount heißt “germany1”, der Container heißt “images”, und das Blob heißt “ubuntu-2016-v1.vhd”. Das wird natürlich was anderes sein, aber diese Angaben sind alle beim Kopieren der VM angefallen und sollten also bekannt sein. Wir erzeugen uns einen Context (sofern der nicht vom Kopieren noch vorhanden ist) und ermitteln alle restlichen Informationen:

$storage="germany1"
$container="images"
$vhd="ubuntu-2016-v1.vhd"

$context=New-AzureStorageContext -StorageAccountName $storage
-StorageAccountKey (Get-AzureStorageKey -StorageAccountName $storage).Primary

$blob=Get-AzureStorageBlob -Context $context -Container $container -Blob $vhd
$uri = ($blob.ICloudBlob).Uri.AbsoluteUri

 

Dann kommt die eigentliche Magie:

Add-AzureVMImage -Imagename $blob.Name -RecommendedVMSize Small -OS Linux -MediaLocation $uri

und schon sehen wir unser neues Image in der Liste der verfügbaren Images:

Get-AzureVMImage | select Label,ImageName

Image verwenden

Das können wir jetzt wie eine von Azure bereitgestellte Imagedatei verwenden, also eigentlich wie zu Beginn dieses Artikels, nur die erste Zeile hat jetzt unseren neuen Imagenamen (und die Location ist angepasst):

$image="ubuntu-2016-v1"
New-AzureQuickVM -Linux -Name "ubuntu-image" -Servicename "ubuntu-service"
-Imagename $image –Linuxuser "superman" -Password "P@ssw0rd!"
-Location "Germany Central" -Instancesize Small

Herzlichen Glückwunsch! Wir haben gerade eine VM erzeugt, die auf einem selbstgemachten Image basiert. War doch gar nicht so schwer, oder?