Das Docker-Ökosystem: Dienstermittlung und verteilte Konfigurationsspeicher

Einführung

Container bieten eine elegante Lösung für diejenigen, die Anwendungen maßstabsgetreu entwerfen und bereitstellen möchten. Während Docker die eigentliche Containerisierungstechnologie bereitstellt, helfen viele andere Projekte bei der Entwicklung der Tools, die für ein geeignetes Bootstrapping und die Kommunikation in der Bereitstellungsumgebung erforderlich sind.

Eine der Kerntechnologien, auf die sich viele Docker-Umgebungen verlassen, ist die Serviceerkennung. Mithilfe der Diensterkennung kann eine Anwendung oder Komponente Informationen zu ihrer Umgebung und ihren Nachbarn ermitteln. Dies wird normalerweise als verteilter Schlüsselwertspeicher implementiert, der auch als allgemeinerer Speicherort für Konfigurationsdetails dienen kann. Durch das Konfigurieren eines Service Discovery-Tools können Sie Ihre Laufzeitkonfiguration vom eigentlichen Container trennen, sodass Sie dasselbe Image in einer Reihe von Umgebungen wiederverwenden können.

In diesem Handbuch werden die Vorteile der Serviceerkennung in einer Docker-Clusterumgebung erläutert. Wir konzentrieren uns hauptsächlich auf allgemeine Konzepte, geben jedoch gegebenenfalls spezifischere Beispiele.

Dienstermittlung und global zugreifbare Konfigurationsspeicher

Die Grundidee der Serviceerkennung besteht darin, dass jede neue Instanz einer Anwendung in der Lage sein sollte, die Details ihrer aktuellen Umgebung programmgesteuert zu identifizieren. Dies ist erforderlich, damit sich die neue Instanz ohne manuelles Eingreifen in die vorhandene Anwendungsumgebung „einbinden“ kann. Diensterkennungstools werden im Allgemeinen als global zugängliche Registrierung implementiert, in der Informationen zu den Instanzen oder Diensten gespeichert werden, die derzeit ausgeführt werden. In den meisten Fällen wird die Registrierung auf die verfügbaren Hosts in der Infrastruktur verteilt, um diese Konfiguration fehlertolerant und skalierbar zu machen.

Während der Hauptzweck von Service Discovery-Plattformen darin besteht, Verbindungsdetails bereitzustellen, um Komponenten miteinander zu verknüpfen, können diese allgemeiner zum Speichern beliebiger Konfigurationstypen verwendet werden. Viele Bereitstellungen nutzen diese Möglichkeit, indem sie ihre Konfigurationsdaten in das Ermittlungstool schreiben. Wenn die Container so konfiguriert sind, dass sie nach diesen Details suchen, können sie ihr Verhalten basierend auf den gefundenen Informationen ändern.

Wie funktioniert die Serviceerkennung?

Jedes Diensterkennungstool bietet eine API, mit der Komponenten Daten festlegen oder abrufen können. Aus diesem Grund muss die Diensterkennungsadresse für jede Komponente entweder in der Anwendung / im Container selbst fest codiert oder zur Laufzeit optional angegeben werden. In der Regel wird der Discovery-Service als Schlüsselwertspeicher implementiert, auf den mithilfe von http-Standardmethoden zugegriffen werden kann.

Die Funktionsweise eines Service Discovery-Portals besteht darin, dass sich jeder Service, wenn er online geschaltet wird, beim Discovery-Tool registriert. Es zeichnet alle Informationen auf, die eine zugehörige Komponente möglicherweise benötigt, um den von ihr bereitgestellten Dienst in Anspruch zu nehmen. Beispielsweise registriert eine MySQL-Datenbank möglicherweise die IP-Adresse und den Port, an dem der Dämon ausgeführt wird, sowie optional den Benutzernamen und die Anmeldeinformationen, die für die Anmeldung erforderlich sind.

Wenn ein Benutzer dieses Dienstes online geschaltet wird, kann er Informationen an einem vordefinierten Endpunkt aus der Diensterkennungsregistrierung abfragen. Es kann dann basierend auf den gefundenen Informationen mit den benötigten Komponenten interagieren. Ein gutes Beispiel hierfür ist ein Load Balancer. Es kann jeden Back-End-Server finden, dem es Datenverkehr zuführen muss, indem es das Service Discovery-Portal abfragt und seine Konfiguration entsprechend anpasst.

Dadurch werden die Konfigurationsdetails aus den Containern selbst entfernt. Dies hat unter anderem den Vorteil, dass die Komponentencontainer flexibler und weniger an eine bestimmte Konfiguration gebunden sind. Ein weiterer Vorteil ist, dass Ihre Komponenten auf einfache Weise auf neue Instanzen eines verwandten Dienstes reagieren können, was eine dynamische Neukonfiguration ermöglicht.

Wie hängt der Konfigurationsspeicher zusammen?

Ein Hauptvorteil eines global verteilten Service Discovery-Systems besteht darin, dass es alle anderen Arten von Konfigurationsdaten speichern kann, die Ihre Komponenten möglicherweise zur Laufzeit benötigen. Dies bedeutet, dass Sie noch mehr Konfiguration aus dem Container in die größere Ausführungsumgebung extrahieren können.

Damit dies möglichst effektiv funktioniert, sollten Ihre Anwendungen in der Regel mit angemessenen Standardeinstellungen entworfen werden, die zur Laufzeit durch Abfragen des Konfigurationsspeichers überschrieben werden können. Auf diese Weise können Sie den Konfigurationsspeicher ähnlich wie Befehlszeilenflags verwenden. Der Unterschied besteht darin, dass Sie durch die Verwendung eines global zugänglichen Speichers jeder Instanz Ihrer Komponente die gleichen Optionen anbieten können, ohne dass zusätzliche Arbeit anfällt.

Wie hilft der Konfigurationsspeicher bei der Clusterverwaltung?

Eine Funktion von verteilten Schlüsselwertspeichern in Docker-Bereitstellungen, die auf den ersten Blick möglicherweise nicht erkennbar ist, ist die Speicherung und Verwaltung der Clustermitgliedschaft. Konfigurationsspeicher sind die perfekte Umgebung, um die Hostmitgliedschaft für die Verwaltungstools nachzuverfolgen.

Einige der Informationen, die über einzelne Hosts in einem verteilten Schlüsselwertspeicher gespeichert werden können, sind:

  • Host-IP-Adressen

  • Verbindungsinformationen für die Hosts selbst

  • Beliebige Metadaten und Labels, die für die Planung von Entscheidungen verwendet werden können

  • Rolle im Cluster (bei Verwendung eines Leader / Follower-Modells)

Mit diesen Details müssen Sie sich wahrscheinlich nicht befassen, wenn Sie eine Service Discovery-Plattform unter normalen Umständen verwenden. Sie bieten jedoch einen Speicherort, an dem Verwaltungstools Informationen zum Cluster selbst abfragen oder ändern können.

Was ist mit der Fehlererkennung?

Die Fehlererkennung kann auf verschiedene Arten implementiert werden. Die Sorge ist, ob bei einem Ausfall einer Komponente der Erkennungsdienst aktualisiert wird, um die Tatsache widerzuspiegeln, dass er nicht mehr verfügbar ist. Diese Art von Informationen ist wichtig, um Anwendungs- oder Dienstausfälle zu minimieren.

Auf vielen Service Discovery-Plattformen können Werte mit einem konfigurierbaren Zeitlimit festgelegt werden. Die Komponente kann einen Wert mit einer Zeitüberschreitung festlegen und den Erkennungsdienst in regelmäßigen Abständen anpingen, um die Zeitüberschreitung zurückzusetzen. Wenn die Komponente ausfällt und das Timeout erreicht ist, werden die Verbindungsinformationen dieser Instanz aus dem Speicher entfernt. Die Länge des Timeouts hängt hauptsächlich davon ab, wie schnell die Anwendung auf einen Komponentenfehler reagieren muss.

Dies kann auch erreicht werden, indem jeder Komponente ein "Hilfscontainer" zugeordnet wird, der allein dafür verantwortlich ist, den Zustand der Komponente regelmäßig zu überprüfen und die Registrierung zu aktualisieren, wenn die Komponente ausfällt. Das Problem bei dieser Art von Architektur besteht darin, dass der Hilfscontainer ausfallen und zu falschen Informationen im Geschäft führen kann. Einige Systeme lösen dieses Problem, indem sie Integritätsprüfungen im Diensterkennungstool definieren können. Auf diese Weise kann die Discovery-Plattform selbst regelmäßig überprüfen, ob die registrierten Komponenten noch verfügbar sind.

Was ist mit der Neukonfiguration von Diensten, wenn sich Details ändern?

Eine wesentliche Verbesserung des grundlegenden Service Discovery-Modells ist die dynamische Rekonfiguration. Während Sie mit der normalen Diensterkennung die Erstkonfiguration von Komponenten beeinflussen können, indem Sie die Erkennungsinformationen beim Start überprüfen, müssen Sie bei der dynamischen Neukonfiguration Ihre Komponenten so konfigurieren, dass sie auf neue Informationen im Konfigurationsspeicher reagieren. Wenn Sie beispielsweise einen Lastenausgleich implementieren, zeigt eine Integritätsprüfung auf den Back-End-Servern möglicherweise an, dass ein Mitglied des Pools inaktiv ist. Die ausgeführte Instanz des Lastenausgleichs muss informiert sein und muss in der Lage sein, seine Konfiguration anzupassen und neu zu laden, um dies zu berücksichtigen.

Dies kann auf verschiedene Arten implementiert werden. Da das Load-Balancing-Beispiel einer der wichtigsten Anwendungsfälle für diese Funktion ist, gibt es eine Reihe von Projekten, die sich ausschließlich auf die Neukonfiguration eines Load-Balancers konzentrieren, wenn Konfigurationsänderungen festgestellt werden. Die Anpassung der HAProxy-Konfiguration ist aufgrund ihrer Allgegenwart im Bereich des Lastenausgleichs üblich.

Bestimmte Projekte sind flexibler, da sie dazu verwendet werden können, Änderungen an jeder Art von Software auszulösen. Diese Tools fragen regelmäßig den Discovery-Service ab. Wenn eine Änderung festgestellt wird, generieren Sie mithilfe von Template-Systemen Konfigurationsdateien, die die am Discovery-Endpunkt gefundenen Werte enthalten. Nachdem eine neue Konfigurationsdatei generiert wurde, wird der betroffene Dienst neu geladen.

Diese Art der dynamischen Rekonfiguration erfordert mehr Planung und Konfiguration während des Erstellungsprozesses, da alle diese Mechanismen im Container der Komponente vorhanden sein müssen. Dadurch ist der Komponentencontainer selbst für die Anpassung seiner Konfiguration verantwortlich. Das Herausfinden der erforderlichen Werte für das Schreiben an den Discovery-Service und das Entwerfen einer geeigneten Datenstruktur für den einfachen Verbrauch ist eine weitere Herausforderung, die dieses System erfordert. Die Vorteile und die Flexibilität können jedoch erheblich sein.

Was ist mit Sicherheit?

Eine Sorge, die viele Menschen haben, wenn sie zum ersten Mal etwas über global zugänglichen Konfigurationsspeicher erfahren, ist zu Recht die Sicherheit. Ist es wirklich in Ordnung, Verbindungsinformationen an einem global zugänglichen Ort zu speichern?

Die Antwort auf diese Frage hängt weitgehend davon ab, was Sie im Geschäft ablegen und wie viele Sicherheitsebenen Sie für erforderlich halten, um Ihre Daten zu schützen. Fast jede Service Discovery-Plattform ermöglicht die Verschlüsselung von Verbindungen mit SSL / TLS. Für einige Dienste ist der Datenschutz möglicherweise nicht sonderlich wichtig, und das Einbinden des Suchdienstes in ein privates Netzwerk kann sich als zufriedenstellend erweisen. Die meisten Anwendungen würden jedoch wahrscheinlich von zusätzlicher Sicherheit profitieren.

Es gibt verschiedene Möglichkeiten, dieses Problem zu lösen, und verschiedene Projekte bieten ihre eigenen Lösungen an. Eine Lösung des Projekts besteht darin, weiterhin den offenen Zugriff auf die Discovery-Plattform selbst zuzulassen, die darauf geschriebenen Daten jedoch zu verschlüsseln. Der Anwendungskonsument muss über den zugeordneten Schlüssel verfügen, um die im Speicher gefundenen Daten zu entschlüsseln. Andere Parteien können nicht auf die unverschlüsselten Daten zugreifen.

Bei einem anderen Ansatz implementieren einige Diensterkennungstools Zugriffssteuerungslisten, um den Schlüsselbereich in separate Zonen zu unterteilen. Sie können dann basierend auf den Zugriffsanforderungen, die von einem bestimmten Schlüsselbereich definiert werden, Besitzrechte oder den Zugriff auf Bereiche festlegen. Dies stellt eine einfache Möglichkeit dar, Informationen für bestimmte Parteien bereitzustellen und sie gleichzeitig für andere nicht zugänglich zu machen. Jede Komponente kann so konfiguriert werden, dass sie nur Zugriff auf die explizit benötigten Informationen hat.

Was sind einige gängige Dienstermittlungstools?

Nachdem wir nun einige der allgemeinen Funktionen von Service Discovery-Tools und global verteilten Schlüsselwertspeichern erörtert haben, können wir einige der Projekte erwähnen, die sich auf diese Konzepte beziehen.

Einige der gebräuchlichsten Diensterkennungstools sind:

  • etcd: Dieses Tool wurde von den Herstellern von CoreOS erstellt, um sowohl den Containern als auch den Hostsystemen selbst eine Serviceerkennung und eine global verteilte Konfiguration bereitzustellen. Es implementiert eine http-API und verfügt über einen Befehlszeilenclient, der auf jedem Hostcomputer verfügbar ist.

  • consul: Diese Service Discovery-Plattform verfügt über viele erweiterte Funktionen, die sie hervorheben, einschließlich konfigurierbarer Integritätsprüfungen, ACL-Funktionen, HAProxy-Konfiguration usw.

  • zookeeper: Dieses Beispiel ist etwas älter als die beiden vorherigen und bietet eine ausgereiftere Plattform auf Kosten einiger neuerer Funktionen.

Einige andere Projekte, die die Ermittlung grundlegender Dienste erweitern, sind:

  • crypt: Mit Crypt können Komponenten die von ihnen geschriebenen Informationen mithilfe der Verschlüsselung mit öffentlichem Schlüssel schützen. Die Komponenten, die die Daten lesen sollen, können mit dem Entschlüsselungsschlüssel versehen werden. Alle anderen Parteien können die Daten nicht lesen.

  • confd: Confd ist ein Projekt, das die dynamische Neukonfiguration beliebiger Anwendungen basierend auf Änderungen im Service Discovery-Portal ermöglichen soll. Das System umfasst ein Tool zum Überwachen relevanter Endpunkte auf Änderungen, ein Vorlagensystem zum Erstellen neuer Konfigurationsdateien auf der Grundlage der gesammelten Informationen und die Möglichkeit, betroffene Anwendungen erneut zu laden.

  • vulcand: Vulcand dient als Load Balancer für Komponentengruppen. Es ist etcd-fähig und ändert seine Konfiguration basierend auf den im Geschäft festgestellten Änderungen.

  • marathon: Während Marathon hauptsächlich ein Scheduler ist (wird später behandelt), implementiert er auch eine grundlegende Fähigkeit zum erneuten Laden von HAProxy, wenn Änderungen an den verfügbaren Diensten vorgenommen werden, zwischen denen ausgeglichen werden soll.

  • frontrunner: Dieses Projekt ist Teil des Marathons, um eine robustere Lösung für die Aktualisierung von HAProxy bereitzustellen.

  • synapse: In diesem Projekt wird eine eingebettete HAProxy-Instanz eingeführt, die Datenverkehr an Komponenten weiterleiten kann.

  • nerve: Nerv wird in Verbindung mit Synapse verwendet, um Gesundheitsprüfungen für einzelne Komponenteninstanzen durchzuführen. Wenn die Komponente nicht mehr verfügbar ist, werden Nervenaktualisierungen synchronisiert, um die Komponente außer Rotation zu bringen.

Fazit

Mithilfe von Service Discovery- und globalen Konfigurationsspeichern können Docker-Container an ihre aktuelle Umgebung angepasst und in vorhandene Komponenten integriert werden. Dies ist eine wesentliche Voraussetzung für eine einfache, freihändige Skalierbarkeit und Bereitstellung, da die Komponenten Änderungen in ihrer Umgebung nachverfolgen und auf diese reagieren können.

Innext guide werden Möglichkeiten erläutert, wie Docker-Container und -Hosts mit benutzerdefinierten Netzwerkkonfigurationen kommunizieren können.