Wie kann ich Docker im Cluster lauffähig machen?

146695
Goto Top
Hallo,
ich versuche gerade Docker auf einem Cluster (dabianbasiert) ans Laufen zu bringen.
(Damit meine ich nicht Swarm oder Kubernetes, sondern ein richtiges Cluster.)

Geplant ist die Konstriktion so:
Der Main-Node startet Docker. Die Für den Betrieb nötigen Dateien
(Images, Container, Volumes) liegen auf einer Festplatte, die als NAS den anderen
Nodes zugänglich ist. Auf jedem Node werden dann die Ordner und Dateien dahin
gemountet wo sie "hingehören".
Der Scheduler verteilt dann die anstehende Arbeit an die einzelnen Nodes, die
wiederum alle auf die gleichen Ordner und Dateien (auf dem NAS) zugreifen.
Ziel dieses Aufbaus ist es, dass ein Prozess vom Scheduler auf
einen anderen Node ausgelagert werden kann ohne dass er selber einen Unterschied
spürt / Dateien nicht mehr findet o.ä.

Scheinbar muss ich dafür auf dem NAS allerdings mehr lagern als "nur" /var/lib/docker
was sonst überall angegeben wurde. Weiß jemand welche Orte und Dateien ich alle
auf dem NAS speichern und auf jedem Node neu mounten muss damit Docker nicht "merkt"
auf welchem Node es läuft?

Warum ich weder Swarm noch Kubernetes nutzen möchte (falls die Frage jetzt aufkommt)
ist schlicht, weil diese beiden Lösungen die Kontainer Fest auf die Nodes verteilen.
Der Rechenaufwand pro Container wird bei mir allerdings stark schwanken, sodass
ich nicht genau festlegen kann welcher Node welche und wie viele Container bekommt.

Danke schon mal im Voraus face-smile

Content-Key: 623886

Url: https://administrator.de/contentid/623886

Ausgedruckt am: 10.08.2022 um 17:08 Uhr

Mitglied: Sheogorath
Sheogorath 19.11.2020 um 18:17:40 Uhr
Goto Top
Moin,

also Grundlegend würde ich sagen: gar nicht. Docker ist nicht dafür ausgelegt, dass die Dateien über mehrere Maschinen hinweg geteilt werden. Im Gegenteil, Docker verlangt exklusiven Zugriff auf /var/lib/docker. Wenn du also irgendwie mehr als einen Spielplatz laufen lassen möchtest, dann wurde ich dringend davon abraten. Stattdessen bietet es sich an bind-mounts für Volumens zu nutzen und die von dir erwähnten Lösungen für clustering in Betracht zu ziehen. Es gibt da noch ein paar weitere, aber keine davon wird dich komplett /var/lib/docker über ein Netzlaufwerk an mehrere Maschinen teilen lassen.

Das klingt erstmal nicht hilfreich, ist ja deine Frage eigentlich, wie man das trotzdem geht, aber lass mich kurz ein paar Gründe aufzählen warum das so eine schlechte Idee ist und dann wie du zumindest theoretisch näher dran kommst.

Zunächst mal speichert Docker allerhand Statusinformationen in /var/lib/docker. Also zum Beispiel welche container existieren, welchen zustand diese haben und ob diese z.B. neugestartet werden sollen, wenn dockerd startet. Heißt, wenn /var/lib/docker in mehreren Hosts gemountet ist und diese dockerd starten, wird jeder versuchen die container mit restart status zu starten. Dann schreiben mehrere Prozesse auf den gleichen Container filesystemen herum, was riesiges durcheinander gibt.

Dann kommen wir mal zum Containerfilesystem. Standardmäßig nutzt docker für das overlayfs ein loop device, sprich eine Datei in /var/lib/docker. Diese wird je nach bedarf vergrößert und entsprechend mit container-Filesystem-Inhalt befüllt, auch hierfür muss diese Datei explizit durch dockerd verwaltet werden.

Und nicht zuletzt: die network interface DB, welche alle datne rundnum docker networks speichert. Auch diese braucht exklusiven Zugriff durch Dockerd und ist nicht für paralleles bearbeiten ausgelegt.

Neben all den Dingen oben, die für Data curruption sorgen werden, sollte man auch erwähnen, dass die performance mit einem remote /var/lib/docker doch recht bescheiden sein kann. Aber da kann man ja Hardware gegenwerfen, solange es kein Latenzproblem ist. Bei letzterem hilft dann nur caching. Aber warte, caching war doch doof für Konsistenz, oder? face-wink


So genug mit dem, was nicht geht. Was kann man denn machen? Zunächst mal, kannst du versuchen Volumens auszulagern, diese scheinen ja dein Hauptproblem zu sein. Damit hast du dann schon mal das los. Zusätzlich, wenn du Angst vor fehlenden Images hast, kannst du entweder einen der modernen P2P pull-through proxies aufsetzen oder aber lokal ein registry anlegen, welches sich vom Netzwerk share bedient. Hier kann es sein, dass du wieder auf Konsistenz achten musst. Oder aber einfach einen registry host hast.

Wenn es dir aber unendlich wichtig ist, wirklich /var/lib/docker auf dein network storage zu verfrachsten, dann solltest du darüber nachdenken ein /var/lib/docker pro "cluster node" zu haben und diese nicht zu teilen.

Dein storage kann dann vielleicht selbst deduplizierung hintenrum machen.

Dann musst du aber immer doch deine Scheduler auf die dockerds loslassen und die Volumens mounten. Wenn du das selbst schrieben willst, erfindest du den core von Kubernetes neu, denn genau das ist das, was K8s auch macht. Aber das kann man natürlich halten wie man will.

So oder so, mit dockerd allein wirst du ein Konstrukt wie du es dir gerade auszumalen scheinst nicht realisieren können, denn genau dafür gibt es die Orchestrierungslösungen wie Swarm und K8s.

In diesem Sinne

Gruß
Chris
Mitglied: Justlerninghere
Justlerninghere 19.11.2020 um 21:54:35 Uhr
Goto Top
Sowas wäre im restart auf nen temporär ausgelagtem volume auch nicht machbar? Vorausgesetzt ich stelle sicher dass ich nach der Nutzung auf ursprünglichen Zustand mit Ausnahme von meinem lib zu Ende der Nutzung was ich als temporäre cfw interpretiert hätte
Zitat von @Sheogorath:

Moin,

also Grundlegend würde ich sagen: gar nicht. Docker ist nicht dafür ausgelegt, dass die Dateien über mehrere Maschinen hinweg geteilt werden. Im Gegenteil, Docker verlangt exklusiven Zugriff auf /var/lib/docker. Wenn du also irgendwie mehr als einen Spielplatz laufen lassen möchtest, dann wurde ich dringend davon abraten. Stattdessen bietet es sich an bind-mounts für Volumens zu nutzen und die von dir erwähnten Lösungen für clustering in Betracht zu ziehen. Es gibt da noch ein paar weitere, aber keine davon wird dich komplett /var/lib/docker über ein Netzlaufwerk an mehrere Maschinen teilen lassen.

Das klingt erstmal nicht hilfreich, ist ja deine Frage eigentlich, wie man das trotzdem geht, aber lass mich kurz ein paar Gründe aufzählen warum das so eine schlechte Idee ist und dann wie du zumindest theoretisch näher dran kommst.

Zunächst mal speichert Docker allerhand Statusinformationen in /var/lib/docker. Also zum Beispiel welche container existieren, welchen zustand diese haben und ob diese z.B. neugestartet werden sollen, wenn dockerd startet. Heißt, wenn /var/lib/docker in mehreren Hosts gemountet ist und diese dockerd starten, wird jeder versuchen die container mit restart status zu starten. Dann schreiben mehrere Prozesse auf den gleichen Container filesystemen herum, was riesiges durcheinander gibt.

Dann kommen wir mal zum Containerfilesystem. Standardmäßig nutzt docker für das overlayfs ein loop device, sprich eine Datei in /var/lib/docker. Diese wird je nach bedarf vergrößert und entsprechend mit container-Filesystem-Inhalt befüllt, auch hierfür muss diese Datei explizit durch dockerd verwaltet werden.

Und nicht zuletzt: die network interface DB, welche alle datne rundnum docker networks speichert. Auch diese braucht exklusiven Zugriff durch Dockerd und ist nicht für paralleles bearbeiten ausgelegt.

Neben all den Dingen oben, die für Data curruption sorgen werden, sollte man auch erwähnen, dass die performance mit einem remote /var/lib/docker doch recht bescheiden sein kann. Aber da kann man ja Hardware gegenwerfen, solange es kein Latenzproblem ist. Bei letzterem hilft dann nur caching. Aber warte, caching war doch doof für Konsistenz, oder? face-wink


So genug mit dem, was nicht geht. Was kann man denn machen? Zunächst mal, kannst du versuchen Volumens auszulagern, diese scheinen ja dein Hauptproblem zu sein. Damit hast du dann schon mal das los. Zusätzlich, wenn du Angst vor fehlenden Images hast, kannst du entweder einen der modernen P2P pull-through proxies aufsetzen oder aber lokal ein registry anlegen, welches sich vom Netzwerk share bedient. Hier kann es sein, dass du wieder auf Konsistenz achten musst. Oder aber einfach einen registry host hast.

Wenn es dir aber unendlich wichtig ist, wirklich /var/lib/docker auf dein network storage zu verfrachsten, dann solltest du darüber nachdenken ein /var/lib/docker pro "cluster node" zu haben und diese nicht zu teilen.

Dein storage kann dann vielleicht selbst deduplizierung hintenrum machen.

Dann musst du aber immer doch deine Scheduler auf die dockerds loslassen und die Volumens mounten. Wenn du das selbst schrieben willst, erfindest du den core von Kubernetes neu, denn genau das ist das, was K8s auch macht. Aber das kann man natürlich halten wie man will.

So oder so, mit dockerd allein wirst du ein Konstrukt wie du es dir gerade auszumalen scheinst nicht realisieren können, denn genau dafür gibt es die Orchestrierungslösungen wie Swarm und K8s.

In diesem Sinne

Gruß
Chris