Windows- und Linux-basierte Docker-Container auf Windows nutzen (Teil 2 von 2)

Seite 3: Container in Windows Server 2016 hosten

Inhaltsverzeichnis

Auf Windows Server 2016 bietet Microsoft neben den Hyper-V-Containern auch noch Windows Server Container, die kein Hyper-V benötigen. Sie sind weniger isoliert: Sie teilen sich den Windows-Betriebssystemkernel mit dem Host, und die Container-Prozesse sind daher auf dem Host sichtbar. Sie sind also etwas leichtgewichtiger, ermöglichen aber nicht, auf einem Nano Server ein Windows Server Core Image zu betreiben (siehe Tabelle 1). Für "Windows Server Container" müssen die Versionsnummern des Hosts und des Basisbetriebssystem-Images in den ersten drei Teilen (Major, Minor, Build) übereinstimmen.

Zwischen den Container-Arten unterscheidet man in den Start-Befehlen für einen Container mit den Angaben -isolation hyperv beziehungsweise -isolation Process (in PowerShell) sowie --isolation=hyperv beziehungsweise --isolation=process (bei docker.exe). Zu beachten ist, dass ohne diese Angabe der Standard auf einem Windows Server 2016 "Process" (also Windows Server Container) ist, während Windows 10 nur "Hyper-V" kennt und dies daher dort der Standard ist. Es kommt also beim Ausführen gleicher Befehle auf beiden Betriebssystemen zu einer Verhaltensänderung.

Betriebssystem des Docker-Hosts Mögliche Windows-Basisbetriebssystem-Images bei Einsatz von Windows-Server-Containern Mögliche Windows-Basisbetriebssystem-Images bei Einsatz von Hyper-V-Container
Windows Server 2016 mit Desktop Windows Server Core und Windows Nano Server Windows Server Core und Windows Nano Server
Windows Server 2016 Core Windows Server Core und Windows Nano Server Windows Server Core und Windows Nano Server
Nano Server nur Nano Server Windows Server Core und Windows Nano Server
Windows 10 Nicht verfĂĽgbar Windows Server Core und Windows Nano Server

Nicht alle Konstellationen von Container-Arten und Basisbetriebssystem-Image sindmöglich (Quelle:
Microsoft).

Das Aktivieren der Container-Features in Windows Server 2016 ist etwas einfacher als bei Windows 10. Beim Server basiert die Installation auf dem OneGet-Paketmanagement-Konzept, das das Unternehmen in PowerShell 5.0 eingefĂĽhrt und auch fĂĽr PowerShell 3.0 und 4.0 zurĂĽckportiert hat. OneGet ist dabei kein konkreter Paketmanager, sondern eine Art "Manager fĂĽr Paketmanager". Der konkrete Paketmanager ist durch einen OneGet-Provider implementiert.

Dazu muss der Nutzer eine PowerShell mit Administratorrechten starten. Als Erstes ist ein PowerShell-Modul aus der PowerShell Gallery zu installieren, das den Docker-Provider fĂĽr OneGet bereitstellt:

Install-Module -Name DockerMsftProvider -Force

Wenn eine Warnung erscheint, dass dafür der NuGet-Provider aktualisiert werden muss, ist das zu bestätigen. Das PowerShell-Modul für Docker installiert sich unter C:\Program Files\WindowsPowerShell\Modules und sollte beim Aufruf des Befehls Get-Module -listavailable zu sehen sein. Danach sind dann noch die eigentlichen Docker-Features mit den konkreten Werkzeugen über die OneGet-Provider zu installieren:

Install-Package -Name docker -ProviderName DockerMsftProvider -Force

Der Download erfolgt von https://dockermsft.blob.core.windows.net/dockercontainer und installiert die klassischen Docker-Werkzeuge. Die Paketinstallation aktiviert auch das optionale Windows-Server-Feature containers und richtet dockerd.exe als Windows-Systemdienst ein. Danach ist ein Neustart erforderlich. Um die PowerShell-Commandlets zu verwenden, muss man nun aber noch Schritt 3 aus dem Listing in Teil 1 des Artikels auf dem Windows Server ausfĂĽhren.

Die Unterstützung für den Betrieb von Linux-Containern auf Windows Server 2016 ist noch in der Entwicklung. Eine Vorabversion von "Docker für Windows" 17.05 (siehe Edge Channel) kann hier allerdings zur Überbrückung aushelfen. Hierzu ist dann Hyper-V als Virtualisierungsbasis für Moby-Linux nötig.

Images verbreiten kann man entweder in Form von .tar-Dateien oder ĂĽber eine Docker Container Registry. Zum Erstellen einer .tar-Datei verwendet man auf dem Host, wo sich das Image aktuell befindet, den Befehl

Save-ContainerImage -ID wwwings.web:latest -DestinationFilePath t:\image.tar

beziehungsweise

docker save wwwings.web:latest > w:\image.tar

Mit Load-ContainerImage lässt sich die Datei auf dem Zielhost einlesen:

Load-ContainerImage \\192.168.1.60\w$\image.tar  

beziehungsweise

docker load --input w:\image2.tar

Die dort enthaltenen Images stehen nun in der Liste der Images (Get-Containerimage) fĂĽr das Erstellen von Containern zur VerfĂĽgung.

Das beschriebene Verfahren hat aber den Nachteil, dass das .tar-Archiv sehr groß werden kann, weil hier nicht nur das angegebene Image, sondern alle benötigten Eltern-Images inklusive des kompletten Betriebssystembasis-Image verpackt werden. Wenn Eltern- und Basis-Images schon in einem Docker- Repository wie Docker Hub liegen, ist die Verbreitung über das Repository wesentlich platz- und netzwerkschonender.

Docker Hub bietet jedem Nutzer kostenfrei ein einziges privates und eine unbegrenzte Menge an öffentlichen Repositories. Für die Veröffentlichung in Docker Hub muss das Image ein Tag besitzen, das nach dem folgenden Muster Kontoname/RepositoryName:Version aufgebaut ist. Vor der Veröffentlichung muss man ihm also ein passendes Tag vergeben und auch "latest" definieren:

Tag-ContainerImage -ID wwwings.web:latest -Tag v1.0 -Repository ↵ 
itvisions/wwwings.web
Tag-ContainerImage -ID wwwings.web:latest -Tag latest -Repository ↵
itvisions/wwwings.web

beziehungsweise

docker tag wwwings.web:latest itvisions/wwwings.web:v1.0 
docker tag wwwings.web:latest itvisions/wwwings.web:latest

Danach besitzt das Image drei Tags: Das von Visual Studio erzeugte Standard-Tag (wwwings.web:latest) sowie die beiden neu vergebenen itvisions/wwwings.web:v1.0 und wwwings.web:latest.

Man sucht vergeblich einen Befehl wie "Remove-ImageTag", sondern muss dafür einen Löschbefehl für das Image (Remove-ContainerImage -ID wwwings.web:latest oder docker rmi wwwings.web:latest) absetzen. Diese Semantik ist sehr ungewöhnlich, denn der Befehl entfernt das Tag, wenn es mehrere Tags gibt. Es beseitigt aber das ganze Image, wenn es das letzte Tag für das Image war.

Wenn man ein Image mit mehreren Tags löschen will, kann man sich wieder das PowerShell-Pipelining zunutze machen. Get-ContainerImage liefert ein Objekt vom Typ Docker.DotNet.Models.ImagesListResponse mit der Eigenschaft RepoTags, die eine Liste von Zeichenketten enthält. Der folgende Befehl iteriert über diese Liste und gibt jedes Tag einzeln an Remove-ContainerImage weiter:

Get-ContainerImage wwwings.web:latest | Foreach-Object repotags | ↵ 
Remove-ContainerImage

Nach der erfolgreichen Tag-Vergabe erfolgt das Hochladen des Images in PowerShell via:

$DockerAuth = [Docker.DotNet.Models.AuthConfig]::new()
$DockerAuth.Username = 'ihrname'
$DockerAuth.Password = 'ihrkenntwort'
Push-ContainerImage -ID itvisions/wwwings.web:v1.0 -Authorization $DockerAuth

Beim Verwenden der klassischen Docker-Befehle verbindet man den lokalen Docker Host per docker login -u ihrname -p ihrkennwort mit Docker Hub. Danach fĂĽhrt Docker alle folgenden Befehle in diesem Benutzerkontext aus. Das Hochladen erledigt docker push itvisions/wwwings.web:v1.0.

Anschließend lässt sich das Image per Pull-ContainerImage itvisions/wwwings.web:v1.0 von allen Benutzern laden, die Zugang zum Repository haben.

Alternativ zu Docker Hub kann man auch die Azure Container Registry von Microsoft verwenden oder eine eigene Registry betreiben. Eine weitere Option ist das Hosten von Containern in der Cloud, zum Beispiel in Microsofts Azure Container Service (ACS).