Ratlos schrieb:
> Nein, und es ist wahrlich eine ernstgemeintes Anliegen von mir.
Gut... okay, dann wollen wir mal. Also, Du verstehst das schon ganz
richtig, Docker ist so etwas Ähnliches wie Virtualisierung. Aber dann...
siehst Du es auch wieder falsch, fürchte ich.
Docker emuliert keinen eigenen Computer wie eine virtuelle Maschine,
sondern isoliert die Prozesse auf der Betriebssystemebene. Insofern ist
ein Docker-Image etwas völlig anderes als ein VM-Image: während das
VM-Image ein komplettes Betriebssystem mit Kernel und allem 'drum und
'dran beinhaltet, ist ein Docker-Image im Endeffekt nur ein lauffähiges
Abbild eines Prozesses, ähnlich wie Deine Executables in, sagen wir,
/usr/bin/ oder eine .exe-Datei unter Windows. Im Unterschied zu diesen
Executables beinhaltet ein Docker-Image jedoch außerdem alle
Abhängigkeiten, die das Programm im Image zur Laufzeit benötigt, also
Shared Objects / Dynamic Link Libraries (*.so / *.dll).
Um ein Docker-Image, mithin: einen solchen Prozeß zu starten, braucht
man also nur das Image sowie eine Konfiguration. Diese Konfiguration
wird Container genannt und beinhaltet einen Verweis auf das betreffende
Image, sowie obendrein noch weitere Informationen, etwa zur Anbindung
von Speicher und / oder Netzwerk. Ein Container wird nämlich komplett
vom Betriebssystem isoliert betrieben und läuft in seinem eigenen
Netzwerk, seinem eigenen Prozeß-ID-Namensraum, und so weiter. Sofern
keine weiteren Maßnahmen ergriffen werden, können Prozesse des Hosts
nicht auf die im Container zugreifen und umgekehrt können Prozesse im
Container nicht auf solche des Hosts zugreifen.
Kommen wir zu Deinem LAMP-Beispiel. Das würde man üblicherweise mit je
einem Container für Apache und einem für das SQL-RDBMs machen, als
Faustregel gilt: nur ein Programm je Container. Man kann das zwar anders
machen, zum Beispiel mit einem supervisord, aber es gilt als schlechter
Stil und gibt einige der Vorteile von Docker, insbesondere im
Zusammenhang mit Kubernetes, auf. Damit nun Dein Apache (beziehungsweise
das PHP darin) auf Deine Datenbank zugreifen kann, müssen sie über die
Container-Konfiguration vernetzt werden; meistens wird man dazu ein
eigenes softwaredefiniertes Netzwerk erstellen und beide Container damit
verbinden. Zudem ist es vermutlich sinnvoll, wenn irgendetwas auf die
Webseiten zugreifen kann, die Dein Apache ausliefern soll, also muß
wiederum per Konfiguration angegeben werden, daß die Ports 80 (http) und
/ oder 443 (https) per DNAT auf den Apachen in Deinem Container gemappt
werden.
Es ist zwar möglich und wird zum Beispiel im Golang-Umfeld gerne
gemacht, einfach nur ein statisch gelinktes Programm ins Image zu
installieren. Aber in der Regel werden Docker-Images von einem bereits
bestehenden Image mit einem vollständigen Betriebssystem (außer dem
Kernel, dessen Funktionen stellt ja der Host bereit) erstellt, so daß
ein (weitgehend) vollständiges System im Image installiert ist.
Was den Storage angeht, so gibt es da verschiedene Varianten. Die
einfachste ist, Deine htdocs und / oder die Datenverzeichnisse Deines
RDBMS einfach mit in das Image zu packen, aber das funktioniert nur dann
gut, wenn sie unveränderlich sind -- aber dann braucht ja es in der
Regel keine dynamische Seite mit RDBMS... ;-) Also gibt es dazu bessere
Möglichkeiten, nämlich sogenannte "Mounts" -- die im Prinzip entweder
ein Verzeichnis des Hosts, oder ein Docker-Volume in den Container
mounten. Dadurch können die Daten dynamisch verändert werden und bleiben
auch dann erhalten, wenn der Container weggeworfen und neu erzeugt wird.
Das ganze Docker-Universum wäre nur halb so sinnvoll, wenn es nicht noch
einen weiteren Teil dabei gäbe, nämlich die Registry, über die Du Deine
Images verteilen kannst. Anders gesagt: Du erstellst Dein Image, testest
es, indem Du einen oder mehrere Container daraus erstellst und sie
testest, und wenn alles wie gewünscht funktioniert, dann lädst Du Dein
Image in die Registry. Dann kann jeder, der an Deine Registry kommt und
das Image herunterladen darf, es einfach herunterladen, seinen eigenen
Container daraus machen und ihn starten. Und wenn Du eine neuere Version
Deines Image bereitstellst, kann er seine Version des Image ganz einfach
aktualisieren und einen neuen Container daraus erzeugen...
Kubernetes ist eine konsequent weitergedachte Implementierung dieses
Konzepts, um Docker-Container auf einem Cluster zu betreiben. Dabei
kümmert sich Kubernetes um die Verteilung der Last auf die Nodes, um die
Bereitstellung von Storage, um die (Hoch)Verfügbarkeit der Prozesse auch
dann, wenn ein Node ausfällt, und natürlich darum, die internen und
externen Netzwerkverbindungen weiterzuleiten. Aber bevor Du Dich mit
Kubernetes beschäftigst, lern' lieber erstmal Docker. ;-)