[Support]  [Forum]  [Newsletter]       [Suche]  [Kontakt]  [Impressum]  [Datenschutz]

Stor IT Back - Ihr Speicherspezialist

  [Angebote]   [Produkte]   [Schulungen]   [Firmenprofil]   [Partner]   [Kunden]   [Information]   [Download]   [News]

LOGO Stor IT Back

"Container Virtualisierung" V1.1 (c) Stor IT Back 2018


Container Virtualisierung - Einführung

Ein wichtiger Vertreter der Container Virtualisierung ist Docker. Aber was sind Container eigentlich? Fangen wir mit der klassischen Virtualisierung an, es wird ein komplettes Betriebssystem auf einem anderen Betriebssystem gestartet. Das Betriebssystem auf dem physikalischen Host ist der Hypervisor und das andere darauf laufende Betriebssystem ist die virtuelle Maschine (VM). Das verbraucht sehr viele Ressourcen, da ja ein zweites komplettes Betriebssystem mit allen Prozessen laufen muss. Weiterhin braucht eine VM deutlich mehr Speicherplatz, neben RAM und CPU.
Das macht der Container jetzt anders, er nutzt einfach das schon laufende Betriebssystem mit. Der Container läuft als einzelne Prozesse auf dem Host. Sie können es sich als eine Applikation vorstellen, die aber gegenüber dem Betriebssystem abgeschottet ist. In einem Container muss also immer eine Applikation laufen, wird die Applikation beendet, dann beendet sich auch der Container.

Eine bildliche Darstellung von Server Virtualisierung (wie zum Beispiel VMware ESXi oder Microsoft Hyper-V) und Container (Docker oder Linux Container) verdeutlicht die Unterschiede:

Server Virtualisierung
Klassische Server-Virtualisierung wie ESXi oder Hyper-V
Container Virtualisierung
Container Virtualisierung mit Docker

Bei der Server Virtualisierung wird immer ein Betriebssystem mit virtueller Hardware benötigt und zwar für jede virtuelle Maschine ein eigenes. Allerdings sind hier auch die virtuellen Maschinen komplett voneinander getrennt, sie können komplett unterschiedliche Betriebssysteme nutzen. Eine Migration von einem physikalischen Betriebssystem auf eine virtuelle Maschine ist einfach möglich. Wie man aber auch sieht, ist der Overhead bei der Server Virtualisierung deutlich größer.
Kommen wir zu den Containern: Hier läuft auf einem Betriebssystem die Docker Engine (Beispiel bei der Docker Software) und darauf die Container. Der Container hat keine virtuelle Hardware und auch kein eigenes Betriebssystem. Er nutz Hardware und Betriebssystem vom Host OS mit. Aber was bedeutet dies für die Kompatibilität? Der große Vorteil von Containern soll ja die flexible Nutzung auf unterschiedlichen Systemen sein, ohne groß etwas anpassen zu müssen. Nehmen wir einmal an, wir hätten einen Container auf einem Linux-System entwickelt, eine Webapplikation auf einem Debian System. Nun möchten wir diesen Container auf einem Windows System, ebenfalls unter Docker starten. Dafür wird auf Windows Hyper-V benötigt, also die Server Virtualisierung von Microsoft. Dort wird ein Linux gestartet, ab da wird alles ganz einfach ... Aber ich kann ja auch einen Windows Container (ein Container, der Windows als Basis hat) erstellen. Die läuft dann in Microsoft Windows Container, die Linux Container in Docker for Windows.


Container - Begriffe Docker

Docker basiert auf verschiedenen Linux-Technologien wie zum Beispiel Cgroups und Namespaces. Mit einer Programmierschnittstelle libcontainer, LXC (Linux Containers) zur Prozess-Isolation und dem Overlay-Dateisystem AuFS (oder auch btrfs) stellt Docker die Container zur Verfügung. Weitere Begriffe:
Image
Das Image ist das Speicherabbild eines Containers. Es besteht aus mehreren Layern, die schreibgeschützt sind. Das Image muss nicht installiert werden, ein einfaches Kopieren reicht für die Installation aus. Das Image kann auch in Repositories gespeichert und von dort verteilt werden.
Container
Von einem Container spricht man, wenn ein Image aktiv ausgeführt wird. Ist quasi mit einer laufenden virtuellen Maschine vergleichbar. Der Container kann gestoppt werden bzw. wird nach Ablauf des Programmes automatisch gestoppt.
libcontainer
Dies ist die Schnittstelle zu allen Grundfunktionen eines Docker Containers
libswarm
Dies ist die Schnitstelle zur Steuerung von Docker Containern
libchan
Ermöglicht eine einfache Kommunikation zwischen Prozessen und Prozessteilen von Docker
LXC
LXC ist die Basis für Container, es stellt eine Programmbibliothek, APIs, Containervorlagen und Werkzeuge zur Kontrolle der Container. Weiterhin ermöglicht LXC die Container unter anderen Usern als root zu starten. Eine wichtige Sicherheitsfunktion. Container können damit nicht mehr so einfach auf das Hostsystem zugreifen.
Cgroups
Die cgroups sind für die Ressourcenverwaltung der Container zuständig. Sie begrenzen den Speicher, den Durchsatz im Netzwerk und auf die Festplatten.
Layer
Ein Layer ist ein Teil eines Images, der Befehle oder Dateien enthält, die einem Image hinzugefügt wurden. Damit lassen sich verschiedene Container aus einem einzelnen Image erstellen.
Dockerfile
Das Dockerfile ist eine Textdatei, die Befehle enthält, die bei der Ausführung des Containers abgearbeitet werden. Für jeden Befehl in dem Dockerfile wird ein Layer angelegt.
Repository
Ein Repository enthält verschiedene Images, die zum Beispiel unterschiedliche Versionen oder Entwicklungsschritte sein können


Installation und Einführung - Docker auf Linux

Das folgende Beispiel basiert auf einem Debian Stretch System, Docker wird dort über die Paketverwaltung installiert.

Wichtiger Hinweis:
Dies soll keine vollständige Anleitung für die Installation und den Betrieb von Docker sein, sondern nur einen Eindruck über die Funktion vermitteln.

Installation zusätzlich benötigte Software:
sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common

Einzufügen der Installationsquellen für die Paketverwaltung:
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"

Installation von Docker:
sudo apt-get update
sudo apt-get install docker-ce

Damit ist die Docker-Software auf dem Debian System installiert und der Daemon gestartet. Für eine einfachere Verwaltung der Images und Container kann ein normaler User der Gruppe docker hinzugefügt werden, damit wird sudo beim Aufruf der Docker-Kommandos nicht mehr benötigt.

Die Überprüfung der Installation ist sehr einfach, es wird ein Container gestartet.

docker run hello-world

admin@debian:~$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

Aber woher kommt jetzt dieser Container? Docker versucht als erstes das Image auf der lokalen Platte zu finden, da wir Docker aber gerade erst installiert haben, haben wir noch keine Images. Also sucht Docker als nächstes im Docker Repository und lädt das Image dann auf die lokale Platte herunter und startet den Container. Im Docker Repository sind sehr viele Images vorhanden, einige zum Testen, aber viele auch mit kompletten Anwendungen und Applikationen. Diese Images können direkt genutzt werden, aber auch den eigenen Anforderungen angepasst werden. Es ist sogar möglich, das eigene Image, zum Beispiel mit einer eigenen Anwendung, auf das Docker Repository hochzuladen. Andere können dann dieses Image selbst nutzen.

Nehmen wir ein anderes Beispiel:

docker run -it ubuntu bash

admin@debian:~$ docker run -it ubuntu bash
root@f6255860bef0:/# id
uid=0(root) gid=0(root) groups=0(root)
root@f6255860bef0:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@f6255860bef0:/# ps -efa
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 10:52 pts/0 00:00:00 bash
root 12 1 0 10:53 pts/0 00:00:00 ps -efa
root@f6255860bef0:/# exit
exit

Jetzt wird wieder ein Image heruntergeladen und ein Container mit Ubuntu gestartet mit der Anwendung bash. Durch die Parameter -it befinden wir uns dann direkt im Container auf der bash Shell. Dort können wir jetzt zum Beispiel den Ubuntu Container durch weitere Software erweitern.

Ergebnis:
Auf einem installierten Linux System kann innerhalb von weniger als 5 Minuten der erste Container gestartet werden.


Conatiner mit Docker - Installation auf Debian

Conatiner mit Docker - Installation auf Debian



Befehle - Docker auf Linux

Einen wichtigen Befehl von Docker haben wir ja schon kennengelernt, es ist run, er startet einen Container (und lädt das Image, wenn es nicht schon vorhanden ist, auch gleich runter). Dem run Befehl können auch weitere Parameter mitgegeben werden. Auch da haben wir schon -it gesehen. Dies ruft den Container interaktiv auf und nutzt eine virtuelle TTY Schnittstelle. Damit wird man direkt auf dem Container angemeldet.

Sie können aber auch ein Image einfach nur herunterladen, das geht mit docker pull nginx. Dieser Befehl lädt das Image nginx (ein einfacher Webserver) herunter. Damit ist das Image auf der lokalen Festplatte, wird aber nicht gestartet. Durch docker run -d --name test-nginx -p 80:80 nginx wird das Image als Container mit dem Namen test-nginx gestartet. Der Parameter -p gibt den Port auf dem Host-Betriebssystem bzw. dem Container an. Der Webserver wird also auf dem Port 80 des Hosts hören. Ein Browser auf die IP des Hosts zeigt dann die Test-Seite von nginx an. Der Parameter -d startet den Container im Hintergrund und zeigt die ID an. Die ID wird später für das Beenden des Containers benötigt.

admin@debian:~$ docker run -d --name test-nginx -p 80:80 nginx
432689b0af02f0cada32d76c185423f97422c6652c1e6b6dade86caacf232c18
docker: Error response from daemon: driver failed programming external connectivity on endpoint test-nginx (203ecee9df85dfae49658453037c8bb6e789e2c30306c7236d1e2d1f825feae5): Error starting userland proxy: listen tcp 0.0.0.0:80: listen: address already in use.
admin@debian:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Also das war jetzt nicht erfolgreich. Was ist passiert? Ganz einfach, der Port 80 wird schon auf dem Host genutzt, dort läuft ein Apache Webserver. Also wurde der Container nicht gestartet. Mit dem Kommando docker ps können wir uns die laufenden Container anzeigen lassen. Es läuft kein Container also war der Start nicht erfolgreich. Korrigieren wir unsere Fehler und nutzen den Port 8080:

admin@debian:~$ docker run -d --name test-nginx -p 8080:80 nginx
docker: Error response from daemon: Conflict. The container name "/test-nginx" is already in use by container "432689b0af02f0cada32d76c185423f97422c6652c1e6b6dade86caacf232c18". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
admin@debian:~$ docker rm test-nginx
test-nginx
admin@debian:~$ docker run -d --name test-nginx -p 8080:80 nginx
5d75bc4aaa730689ad9854b1be57bf4b16c9466a244b2006639b01234de69268
admin@debian:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d75bc4aaa73 nginx "nginx -g 'daemon of" 18 seconds ago Up 16 seconds 0.0.0.0:8080->80/tcp test-nginx

Schon wieder ein Fehler beim Aufruf des run Kommandos. Wenn der Container mit unserem Namen schon existiert (auch wenn er nicht läuft), dann müsste er entweder einen anderen Namen bekommen oder wir löschen den ersten Versuch. Und genau das haben wir mit dem Kommando docker rm gemacht. Danach konnte der Container gestartet werden. Mit dem Kommando docker ps kann man sich die laufenden Container anschauen. Jetzt klappt natürlich auch der Browser-Aufruf und es wird die "Welcome" Seite angezeigt.

Jetzt kommt der große Vorteil der Container: Wenn ich den Webserver jetzt auch noch auf Port 8081 und 8082 benötige, dann starte ich den Container mit neuem Namen und dem entsprechenden Port einfach noch zwei Mal.
Werden die Container nicht mehr benötigt, so lassen sie sich einfach stoppen und bei Bedarf wieder starten.

admin@debian:~$ docker run -d --name test-nginx1 -p 8081:80 nginx
606b541324e53b5ff8f4909c5bd4b7e86c7e46f81b9f40930991116fd232d55f
admin@debian:~$ docker run -d --name test-nginx2 -p 8082:80 nginx
7793025d7cd86b190ea94c8490d9416901ac8abe4cef4b4c51299696ed86637c
admin@debian:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7793025d7cd8 nginx "nginx -g 'daemon of" 6 seconds ago Up 4 seconds 0.0.0.0:8082->80/tcp test-nginx2
606b541324e5 nginx "nginx -g 'daemon of" 14 seconds ago Up 12 seconds 0.0.0.0:8081->80/tcp test-nginx1
5d75bc4aaa73 nginx "nginx -g 'daemon of" 8 minutes ago Up 8 minutes 0.0.0.0:8080->80/tcp test-nginx
admin@debian:~$ docker stop test-nginx test-nginx1 test-nginx2
test-nginx
test-nginx1
test-nginx2
admin@debian:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Die Container können natürlich auch verändert und die Veränderungen dann wieder in neue Images geschrieben werden. Bei docker ist die Hilfefunktion gleich mit eingebaut. Ein docker --help zeigt alle Kommandos an und ein docker Kommando --help zeigt dann alle Parameter zu dem Kommando an.


Interner Aufbau der Container / Image

Wichtig ist die Unterscheidung zwischen Image und Container in Docker. Das Image enthält alle Programme, Libraries, Tools, Config-Dateien für den zu startenden Container. Neben dem Image, welches im Normalfalle aus verschiedenen Layern besteht, wird auch noch eine Beschreibungsdatei, das sogenannte Dockerfile benötigt. In diesem Dockerfile stehen Informationen zu dem Aufbau der Layer der Images und auch Anweisung zum Beispiel für die Netzwerkkonfiguration.
Schauen wir uns erst mal das Images an: Wie würde man einen Container bauen, der die Applikation apache (also den Webserver) nutzt? Nehmen wir einmal an, ein fertiges Image auf dem Docker Hub würde es nicht geben. Dann starten wir mit einem Basis-Image zum Beispiel einer CentOS Basisinstallation. Auf diesem Image sind grundlegende Programme und Libraries enthalten und die bash als Shell. Dieses Image könnte man dann als Container starten und meldet sich mit dem -it Paramter auf der bash an. Jetzt kann man wie üblich den apache Webserver installieren, also so, als wäre man auf einem richtigen Server. Läuft der Container jetzt wie gewünscht, dann sind die Änderungen nur im Container, nicht aber im Basis-Image.

Image und Container Aufbau
Beispiel Aufbau Container durch Images

Danach kann aus diesem Container ein neues Image gebaut werden. Es wird dann zum Basis-Image ein neuer Layer für den Apache. Aus diesem neuen Image (Basis Image und Apache Image) können Sie jetzt wieder einen neuer Container startet. Möchten Sie jetzt eine Webseite oder Anwendung hinzufügen (Container starten und Webseite hinein kopieren), so können Sie auch dann wieder ein neues Image (Basis Image und Apache Image und Webseite Image) daraus erstellen. Möchten Sie eine andere Webseite in einem Container erstellen, so starten Sie einfach das Basis und Apache Image neu und fügen die neue Webseite hinzu. Sie können also Images und Container immer wieder verwenden.
Damit sind die Images immer Read Only, bis auf den obersten Layer, der ist immer Read Write. Dieser oberste Layer (oberstes Image) gehört zur Laufzeit des Containers nicht zum eigentlichen Image, sondern zum laufenden Container. Wenn Sie also den Container stoppen und dann löschen, so sind alle Änderungen am Image verschwunden. Sie waren im obersten Image Read Write enthalten. Damit können Container immer wieder frische aus einem Image gestartet werden. Ein Container besteht aus als dem Image und dem beschreibbaren obersten Layer.

Eine Besonderheit bei Docker ist, dass ein Volume in mehrere Container hinein gemountet werden kann. Bei den Images ist es quasi immer so, wenn ein Layer schon im Cache ist, also in einem Container läuft, dann wird es bei einem anderen Container mit dem gleichen Layer einfach wiederverwendet. Ein Ansatz um Speicherplatz im RAM und Filesystem zu sparen.


Wer nutzt Container und warum?

Die größte Akzeptanz finden Container bei Software-Entwicklern, die verschiedene Versionen ihrer Software auf unterschiedlichen Systemen entwickeln und testen müssen. Was sind dort die konkreten Vorteile der Container? Die Entwickler können auf einem Basis-System (dem Docker-Host) verschiedene Versionen von Betriebssystemen mit verschiedenen Versionen ihrer Software kombinieren und dann testen. Da die Container aus einzelnen Layern aufgebaut sind, lassen sie sich einfach und schnell kombinieren und starten.

Aber nicht nur bei der Software-Entwicklung spielen Container eine immer größere Rolle, auch bei Administratoren in Unternehmen. In Containern können einfach und schnell Anwendungen den Nutzern zur Verfügung gestellt werden, für die eigentlich keine Betriebssysteme vorhanden sind oder Voraussetzungen nicht erfüllt sind. Aber auch ein Update der Anwendung wird deutlich einfacher. Der Container wird ja aus einem Image gestartet und das kann für verschiedene Nutzer immer das gleiche sein (siehe das Beispiel mit dem Webserver oben). Das Update muss also nur auf dem einen "golden" Image durchgeführt werden und nach einem Neustart der Container haben alle Anwender die neue Version. Sie stellen einen Fehler in der neuen Applikation fest, aber haben es schon an alle Nutzer verteilt? Kein Problem, das alte Image wieder herstellen und alle Container neu starten. Mit einer klassischen Softwareverteilung ist das nicht möglich, bzw. mit deutlich mehr Aufwand.

Eine Anwendung wäre zum Beispiel der Webbrowser im Container für privates Surfen im Büro. Sie möchten Ihren Mitarbeitern das private Surfen erlauben, aber nicht direkt auf dem Firmenrechner? Auch das könnte im Container laufen. Was sind Probleme beim privaten Surfen in der Firma? Eine Forderung, gerade von der Geschäftsführung, ist häufig die zeitliche Begrenzung der Nutzung, also nur in den Pausen und nach der Arbeit. Aber auch ein Security Problem taucht auf, die Verbindungen sind ja alle verschlüsselt, also kann der Firmenproxy den Datenverkehr nicht kontrollieren, er findet keine Viren und sonstige Bedrohungen. Wenn der Mitarbeiter zum privaten Surfen aber einen Container nutzt, dann laufen evtl. Programme (und auch die Viren) in dem Container. Wenn der Download von Dateien aus dem Container nicht möglich ist und der Container regelmäßig neu gestartet wird ist dies eine recht sichere Möglichkeit.


Conatiner mit Docker - Sicherer Browser im Container

Conatiner mit Docker - Sicherer Browser im Container



Backup und Recovery von Docker Containern

Wie können Container einfach und schnell gesichert werden? Die Basis dafür haben Sie schon kennengelernt. Wenn ein Container läuft, dann kann er mit dem Befehl docker commit im aktuellen Zustand auf ein neues Image kopiert werden. Damit haben wir eine schnelle und einfache Sicherung von laufenden Containern. Eines ist dabei aber zu beachten: Die Daten in dem Container müssen konsistent sein. Was bedeutet dies? Wenn zum Beispiel eine Datenbank in dem Container läuft und die Sicherung wird bei laufender Datenbank über Transaktionen hinweg durchgeführt, so lässt sich entweder die Datenbank aus der Sicherung nicht starten oder die Daten sind nicht konsistent. In beiden Fällen ist das Backup nicht brauchbar. Dafür gibt es aber eine einfache Lösung: docker commit -p pausiert den Container für den Commit Befehl, also für unsere Datenbank.
Damit ist eine einfache Datensicherung möglich, aber wie läuft die Recovery? Eigentlich noch einfacher. Wichtig ist natürlich vorher die Sicherung auf einen anderen Server und andere Plattensysteme zu verschieben. Das kann ganz Docker-Konform mit einem privaten Docker Repository erledigt werden. Mit dem Befehlt docker push kann das Image der Datensicherung verschoben werden. Aber kommen wir zur Recovery, das Image liegt auf einem Repository und von dort kann der Container mit docker load auf den gleichen oder einen anderen Docker Host geladen und mit docker run gleich gestartet werden. Viel einfacher geht es nicht und Sie benötigen nicht einmal eine Backup-Software.

Kann der Ablauf noch verbessert werden oder wo liegen die Nachteile? Nehmen wir einmal an, wir starten viele Container aus dem gleichen Image. Somit ist der Unterschied zwischen den Containern nur der obere Read Write Layer. Die restlichen Layer sind ja immer gleich. Also warum nicht nur den oberen Layer sichern? Dies spart Plattenplatz in der Sicherung und Zeit beim Backup und auch beim Restore.

Was natürlich auch immer geht, aber nicht die eleganteste Lösung ist: Einfach eine Sicherung innerhalb des Containers erstellen und per NFS, SMB oder Backup-Client außerhalb des Containers sichern. Also so, als wäre man auf einer physikalischen Maschine.


Angebote der Stor IT Back zum Thema Container

Angebot Dell EMC ME4 Serie / ME4012 ME4024 ME4084
Dell EMC ME4 Serie iSCSI, FC SAS-RAID
Single/Dual Controller, Block Storage

10 Gbit/s iSCSI, 16 Gbit/s FC, 12 Gbit/s SAS Host
SSD, SAS, NL-SAS Platten / Replikation / Tiering
ab 8.706,00 Euro
zzgl. MwSt.

Angebot Lenovo Thinsystem DS2200
Lenovo ThinkSystem DS2200 SAN Storage
FC / iSCSI / SAS Host, NL-SAS / SAS / SSD Festplatten

bis zu 96 Festplatten, Dual Controller
Real Time Tiering, Storage Pools, Thin Provisioning
Preis
auf Anfrage
Schulungen für Storage und Backup
Schulungen und Workshops
Storage (SAN, NAS, iSCSI)
Backup (LANfree, SnapShot)
Storage- und Servervirtualisierung
Praxis-Schulungen
individuell / auch Inhouse
 
 
Zurück zur Übersicht
Container Virtualisierung
Übersicht der Angebote
Kontakt zur Stor IT Back
Suche auf der Webseite