2014-02-24 6 views
19

Ich habe bisher große Erfolge mit Mesos, Marathon und Docker erzielt, um eine Flotte von Servern und die Container, die ich auf sie platziere, zu verwalten. Nun möchte ich jedoch etwas weiter gehen und Dinge wie die automatische Verknüpfung eines Haproxy-Containers mit jedem Haupt-Docker-Dienst, der gestartet wird, oder andere dämon- und containerisierte Dienste bereitstellen, die verknüpft sind und nur für den einzelnen übergeordneten Container verfügbar sind.Verknüpfte Docker-Container mit Mesos/Marathon

Normalerweise würde ich den Hilfsdienst zuerst mit einem Namen starten, dann, wenn ich den echten Dienst begann, würde ich es mit dem Helfer verknüpfen und alles würde gut gehen. Wie passt dieses Modell zu Marathon und Mesos? Es scheint zumindest jetzt, dass die Containerisierung einen einzigen Container voraussetzt.

Ich hatte eine Idee, den Hilfsdienst zuerst zu starten, auf welchem ​​Host es auch finden konnte, und dann eine Einschränkung zum realen Dienst hinzuzufügen, die Hostname = Hilfsdienst-Hostname, aber das würde Probleme mit Ressourcenangeboten verursachen und Rassenbedingungen für diese Ressourcen.

Ich habe auch gedacht, um eine "Embed" oder "Deep-Link" -Funktionalität zu Docker, oder zu den Executor-Skripten, die die Docker-Container starten.

Bevor ich einen dieser Pfade hinunter ging, wollte ich herausfinden, ob jemand anderes dieses Problem gelöst hat, oder ob ich einfach nur furchtbar darüber nachgedacht habe.

Danke!

Antwort

26

Sie wandern in unbekanntes Gebiet! ☺

Es gibt mehrere Ansätze hier; und keiner von ihnen ist perfekt, aber die Situation wird sich in zukünftigen Versionen von Docker dank Orchestrierungs-Hooks verbessern.

Ein Weg ist, gute alte Service-Entdeckung und Registrierung zu verwenden. Wenn ein Dienst gestartet wird, wird er seine öffentlich verfügbare Adresse herausfinden und sich z. Zoowärter, Etcd oder sogar Redis. Da es für einen Dienst nicht trivial ist, seine öffentlich verfügbare Adresse herauszufinden (es sei denn, Sie treffen einige Konventionen, z. B. immer Zuordnung von Port X: X, anstatt Docker zufällige Ports zuweisen zu lassen), sollten Sie die Registrierung von außen vornehmen. Das bedeutet, dass Ihre Orchestrierungsschicht (in diesem Fall Mesos) den Container startet, dann den Host und den Port ermittelt und in Ihr Service Discovery System einfügt. Ich bin mit Marathon nicht sehr vertraut, aber Sie sollten einen Haken dafür registrieren können. Dann werden andere Container einfach die Endpunktadresse in der Dienstermittlungsregistrierung suchen, ganz einfach.

Sie können auch Skydock betrachten, die automatisch DNS-Namen für Ihre Container mit Skydns registriert. Es ist jedoch derzeit Single-Host, wenn Sie also diese Idee mögen, müssen Sie es irgendwie erweitern, um mehrere Hosts und vielleicht SRV-Datensätze zu unterstützen.

Ein anderer Ansatz besteht darin, "bekannte Einstiegspunkte" zu verwenden. Dies ist tatsächlich der vereinfachte Fall der Dienstsuche. Das bedeutet, dass Sie sicherstellen werden, dass Ihre Dienste immer auf vordefinierten Hosts und Ports ausgeführt werden, sodass Sie diese Adressen statisch verwenden können. Natürlich ist das schlecht (weil es Ihr Leben schwieriger macht, wenn Sie die Umgebung für Test-/Staging-Zwecke reproduzieren wollen), aber wenn Sie überhaupt keine Ahnung von Service-Entdeckung haben, könnte es ein Anfang sein. Sie können auch Pipework verwenden, um ein (oder mehrere) virtuelles Netzwerk zu erstellen, das sich über mehrere Hosts erstreckt und Ihre Container miteinander verbindet. Mit Pipework können Sie IP-Adressen manuell oder automatisch über DHCP zuweisen. Dieser Ansatz wird jedoch nicht empfohlen, aber er eignet sich gut, wenn Sie Ihre Container auch in eine vorhandene Netzwerkarchitektur (z. B. VLANs ...) einbinden möchten.

Egal für welche Lösung Sie sich entscheiden, ich empfehle Ihnen, "vorzugeben", dass Sie Links verwenden. I.e. Anstatt die App-Konfiguration hart zu codieren, um eine Verbindung herzustellen (zufälliges Beispiel) my-postgresql-db:5432, verwenden Sie die Umgebungsvariablen DB_PORT_5432_TCP_ADDR und DB_PORT_5432_TCP_PORT (als wäre es ein Link) und legen Sie diese Variablen beim Starten des Containers fest. Auf diese Weise können Sie, wenn Sie Ihre Container in eine einfachere Umgebung ohne Service-Erkennung usw. "herunterklappen", problemlos auf Links zurückgreifen.

+2

Eine Sache, die mir wichtig ist, ist die Lokalität von Containern. Ich könnte relativ leicht eine Art von Entdeckung finden, um andere Container zu finden, aber ich suche nach einer Optimierung darüber hinaus, die den Marathon zwingt, eine Gruppe von Containern (Think Nginx + Rails + Anmeldeinformationen Daemon) jeweils in ihren eigenen Containern zu starten. Offensichtlich muss ich einen Patch einreichen, sollte ich Marathon statt Docker ansehen? –

+0

Nur um sicher zu gehen, dass ich es richtig verstehe - meinst du "... was den Marathon zwingt, eine Gruppe von Containern (...) in ihrem eigenen Host zu starten"? I.e. Force Container auf verschiedenen Hosts sein? – jpetazzo

+0

Sorry, ich möchte die Gruppe auf einem einzelnen Host, eine lokale Haproxy an jeden Dienst zum Beispiel angeschlossen. Ich denke, der richtige Pfad ist hier ein benutzerdefinierter Mesos-Executor, der weiß, wie man zusätzliche Argumente von Marathon, fork und selbst verwaltet, um sicherzustellen, dass die gesamte Gruppe neu gestartet wird, wenn ein Teil stirbt. –