Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 33 Min.

Network- und Service-Discovery mit Consul

Consul eignet sich als Baukasten für verteilte Systeme in verschiedenen Umgebungen mit dem primären Ziel, den Aufwand im DevOps zu minimieren.
Mit Consul entwickelt und betreibt man lose gekoppelte, verteilte Software-Systeme für die verschiedensten Umgebungen: Cloud, Container, Virtuelle Maschinen aber auch lokal Vor-Ort (On-Promise). Basis der Consul-Systeme stellt ein optimiertes Services-of-Services-System dar, das mit Auto-Scaling und Self-Healing zwei wichtige Anforderungen der Hochverfügbarkeit erfüllt. Zudem lassen sich die über Consul bereitgestellten Dienste in den verschiedensten Programmiersprachen nutzen.

Hauptfunktionen von Consul zielen auf Hochverfügbarkeit ab

Consul unterstützt Microservices als Architekturkonzept für Anwendungen. Dabei handelt es sich um eine Softwaretechnik der Anwendungsentwicklung, die für DevOps (Entwicklung, Betrieb/Produktion) und CI/CD (Continuous Integration/Continuous Delivery beziehungsweise Continuous Deployment) gleichzeitig optimiert ist: Fehler in einzelnen Services führen nicht zu einem Gesamtausfall einer Anwendung. Microservices bieten den Vorteil, schnell Bausteine bereitstellen zu können, die den sich ändernden Anforderungen gerecht werden.
Das Deploymenteines Consul-Clusters erfolgt in einem Datacenter mit verschiedenen Servern und Clients(Bild 1) © Simon
HashiCorp hat Consul in der Programmiersprache Go (auch Golang genannt) realisiert, die von Google speziell mit Hinblick auf skalierbare Netzwerkdienste, Cloud- und Cluster-Computing entwickelt wurde. Beim Einsatz von Consul stehen Discovery und Konfiguration verschiedener Services für den Betrieb auf der vorhandenen Infrastruktur im Mittelpunkt. Consul stellt Services und Knoten über ein flexibles und mächtiges Interface bereit, mit dem Clients immer eine aktuelle Sicht auf die ihnen zugrundeliegende Infrastruktur besitzen. Zum Leistungsumfang von Consul gehören die folgenden Hauptmerkmale:HashiCorp liefert Consul in drei Produkt-Editionen aus, wobei man eine Auswahl aufgrund der eigenen Anforderungen treffen sollte. Zwischen den drei Produkt-Editionen existiert lediglich eine Aufwärtskompatibilität:Für eine lokale Installation (On-Promise) stellt HashiCorp über die Download-Site von Consul eine Binärversion für macOS, Windows, FreeBSD und Solaris bereit. Zusätzlich unterstützt HashiCorp für die Linux-Derivate (Ubuntu/Debian, CentOS/RHEL, Fedora, Amazon Linux) den für das jeweilige Betriebssystem gängigen Package-Manager.Ergänzend steht die Binärversion von Consul auch als Homebrew- ocer Chocolatey-Package zur Verfügung. Für eine Installation über den Go-Quellcode hat HashiCorp ein GitHub-Repository eingerichtet. Ferner ist dazu ein Git-Client und ein Go-Compiler-System (siehe Teil 1) erforderlich.

Lokale Installation von Consul Vor-Ort/On-Promise für Test/Entwicklung

Nach einem Download genügt ein Entpacken des ZIP-Archives für die Binärversion oder die Ausführung eines Compile-Vorgangs anhand des Quellcodes und dem Go-System. Abschließend muss nur noch das Installationsverzeichnis über die PATH-Umgebungsvariable zugänglich gemacht werden, um das CLI von Consul anzusprechen.

AuthO für eine sichere Autorisierung über ein API

Mithilfe von AuthO realisiert man eine Autorisierung für Dritte ohne die eigene geheime Zugangsberechtigung (Authentifizierung) preiszugeben. Dies erlaubt einen Zugriff auf Ressourcen/Services und verhindert gleichzeitig eine Übermittlung von Passwörtern an Dritte. Das AuthO-API basiert auf der Version 2 der OAuth-Spezifikation, die ein Mitentwickler als weniger sicher als OAuth 1.0 kritisiert.
Die Versionsnummer des aktuell installierten Consul-Systems gibt die Anweisung consul --version aus. Die Kommandos des CLI erkundet der Terminalbefehl consul --help <command> <[args]>. Darüber erhält man ausführliche Anleitungen zur Arbeitsweise der einzelnen Befehle und den verfügbaren Optionen.Der Befehl consul -autocomplete-install aktiviert eine automatische Vervollständigung der Kommandos mittels der Tabulatortaste – allerdings erst nach dem Neustart eines Terminalfensters/Eingabeaufforderung. Sollte man eine andere, ganz spezielle Version von Consul benötigten, so hat HashiCorp eine weitere Download-Site eingerichtet: releases.hashicorp.com/consul/. Dort findet man neben der freigegebenen offiziellen Version, auch Alpha- und Beta-Versionen sowie Release-Kandidaten. Für eine schnellere Befehlsausführung und um die Eingabe der CLI-Optionen zu erleichtern, kennt Consul eine Reihe von Umgebungsvariablen. Nach der Definition einer dieser Umgebungsvariablen berücksichtigt Consul deren Einstellung bei der Befehlsausführung.

Consul auf Docker und Kubernetes

Neben einer lokalen Installation bietet HashiCorp auch eine Installation von Consul in den Container-Plattformen Docker und Kubernetes an. Für eine Installation in Docker benötigt man die Docker Desktop-Software, welche unter anderem die Engine, das CLI (Call Lever Interface) und Compose von Docker enthält. Docker Compose benötigt man für die Ausführung und Konfiguration der Services einer Anwendung. Zusätzlich muss man einen Account zum Docker Hub eingerichtet haben, um Verbindungen für Abfragen des Repositorys oder das Herunterladen von Images vornehmen zu können. HashiCorp verwaltet auf Docker Hub ein selbst erstelltes Docker-Image für Consulüber die Adresse https://hub.docker.com/_/consul.Mit dem CLI-Befehl docker pull consul stellt man das letzte offizielle Docker-Image von Consul bereit. Nach dessen Download befindet sich das Docker-Image im lokalen Repository; dieses zeigt Docker Desktop im Bereich Images an. Bewegt man im Eintrag von consul den Mauszeiger nach rechts, erscheint eine Run-Schaltfläche. Ein Klick darauf öffnet das Dialogfenster New Container und bietet über eine weitere Run-Schaltfläche die Ausführung von Consul im Hintergrund (docker run -d consul) an. Anschließend erscheint ein neuer Eintrag im Containers/Apps-Bereich von Docker Desktop mit dem laufenden Consul-System.
Ein Klick auf einen Listeneintragim Containers/Apps-Bereich von Docker Desktop zeigt Informationen zum ausgewählten Container/App an(Bild 2) © Simon
Klickt man links auf dessen Namen, so öffnet sich ein Inspector, dessen Toolleiste nähere Informationen zu den Log-Daten (Bild 2), Systemeinstellungen (Inspect) und Ressourcen-Verbrauch (Stats) anzeigt.

Installation von Consul über Docker-Image

Eine schnelle Installation von Consul in einem Kubernetes (K8)-Container nimmt man über minikube vor. Bei minikube handelt es sich um einen Docker-Image, das auf einem lokalen Kubernetes-Cluster in Docker läuft. Das Tool eignet sich besonders für Entwicklung und Test eines Consul-Systems in Kubernetes. Neben einer Installation von minikube benötigt man noch kubernetes-cli und (kubernetes-)helm.Das kubernetes-cli (kubectl) stellt ein CLI für K8s-Cluster dar, während helm einem K8s-Package-Manager entspricht. Der Betrieb von Consul in K8s benötigt mindestens 4 GB-Memory. Daher startet man minkube mit dem Befehl minikube start --memory 4096.Der Start-Befehl von minikube lädt das Consul-Image aus dem Docker-Hub herunter, erstellt einen Container für minikube in Docker, richtet einen K8s-Cluster mit dem Namespace default ein. Um Consul über helm zu installieren, richtet man einen Zugriff auf das HashiCorp-Repository ein: helm repo add hashicorp https://helm.releases.hashicorp.com. Anschließend zeigt der Befehl helm search repo consul die im HashiCorp-Repository enthaltene Chart- und Consul-Version an. Vor der eigentlichen Installation von Consul überprüft der Befehl kubectl get namespace, ob der Namespace von Consul in K8s zur Verfügung steht. Abschließend nimmt helm install consul hashicorp/consul --set global.name=consul --create-namespace --namespace consul ein Deployment von Consul in K8s vor. Damit steht Consul bei jedem Start von minikube auf K8s zur Verfügung.

Consul-Architektur für verteilte Systeme rückt Resilienz ins Zentrum

HashiCorp hat die Architektur eines Consul-Clusters so ausgerichtet, dass Störungen oder Probleme bei einzelnen Komponenten nicht zu einem gesamten Systemausfall führen. Dazu setzt man entsprechende Maßnahmen wie redundante Komponenten ein, damit das Gesamtsystem die Anwender weiterhin mit den von ihnen benötigten Services bedient.Beim traditionellen Stabilitätsansatz des Software-Designs trifft man im Vorfeld Vorkehrungen, um die Wahrscheinlichkeit für das Auftreten eines Fehlers zu vermeiden. Im Zuge der Verbreitung verteilter Systeme über das Internet, im Cloud-Computing oder in der Mobile World gewann man eine wichtige Erkenntnis: Fehlerzustände in verteilten Systemen entsprechen dem Normalfall und nicht der Ausnahme – insofern ist ihre Vorhersage nicht möglich.Der Versuch Fehler zu vermeiden, führt bei immer komplexeren, immer höher vernetzten Systemlandschaften auf einen Irrweg. Es ist nahezu unmöglich alle denkbaren Vorkehrungen zu treffen, da die auftretenden Fehlermuster sich als nicht mehr vorhersagbar erweisen. Deshalb verfolgt HashiCorp mit Consul einen anderen Stabilitätsansatz – der auf Resilienz basiert: Fehler treten auf, das System erhält die Fähigkeit mit ihnen so umzugehen, ohne dass der Anwender davon etwas mitbekommt.Dazu schafft man Redundanzen innerhalb von Komponenten, um die Folgen auftretender Fehler abzufedern. Mittels Isolation schottet man Komponenten ab, um über mehrere Einheiten fortpflanzende (kaskadierende) Fehler zu verhindern. Anhand einer losen Kopplung wirkt man kaskadierenden Fehlern nochmals entgegen, so dass deren Wahrscheinlichkeit abermals sinkt. Eine eigens entworfene Fallback-Strategie legt für einen kritischen Fehler die Notfallreaktion fest. In einem verteilten System will man die Eigenschaften Konsistenz (C steht für Consistency), Verfügbarkeit (A für Availability) und Ausfalltoleranz (P für Partion Tolerance) garantieren: Alle Clients sollen jederzeit die gleichen Daten sehen (Konsistenz), alle Anfragen an das System werden stets durchgeführt (Verfügbarkeit) und das System soll auch bei Ausfall einzelner Knoten als Ganzes weiterarbeiten (Ausfalltoleranz). Zeichnet man drei Punkte CAP so bilden die drei genannten Systemeigenschaften geometrisch gesehen ein Dreieck. Dabei gilt das CAP- auch Brewers-Theorem – von den drei genannten Eigenschaften können immer nur zwei erfüllt sein, jedoch nicht alle drei.

Mittels Konsens zur endgültigen Entscheidung

In einem fehlertoleranten verteilten System wie Consul müssen Server Entscheidungen treffen – diese entstehen durch Einigung (Konsensbildung). Consul setzt Raft einen fehlertoleranten verteilten Konsens-Algorithmus ein, der äquivalent zu Paxos ist. Im Unterschied zu Paxos besteht Raft aus relativ unabhängigen Unterproblemen, über die man viele praktische Fragestellungen lösen kann.
Insgesamt ergeben sich die folgenden drei Systemkonstellationen: AP, CA und CP. Bekanntes Beispiel für ein AP-System ist ein Domain Name System (DNS). Ein RDMBS (Relationales Datenbank-Management-System) fällt in die Kategorie CA. CP entsprechen Finanzanwendungen, auch bei Störungen muss ein konsistenter Betrieb möglich sein. In diese CP-Kategorie gehört auch ein Consul-System.

Multiple-Datacenters für Consul-Cluster stellen den Normalfall dar

Im Zentrum von Consul steht der Begriff des Agenten, dabei handelt es sich um den Hauptprozess von Consul. Auf jedem Knoten der Bestandteil eines Consul-Clusters ist läuft ein Agent. Der Agent übernimmt alle Hauptaufgaben wie die Registrierung von Services, die Durchführung von Prüfungen, das Beantworten von Anfragen und ähnliches.Ein Agent läuft entweder im Client- oder im Server-Mode. Clients entsprechen leichtgewichtigen Prozessen, sie machen prinzipiell die Mehrheit der Konten im Cluster aus. Für die meisten Operationen interagieren Clients mit Server-Knoten und besitzen nur wenig Zustandsinformationen. Im Unterschied dazu beanspruchen Server-Knoten mehr Ressourcen und nehmen am Konsensus-Quorum teil.Dabei legen die Server zusammen als Gruppe ein gemeinsames Ergebnis in Übereinstimmung fest – es kommt das Raft-Protokoll zum Einsatz, einen auf Paxos basierenden Konsensus-Algorithmus. Fallen n Server gleichzeitig aus, so erzielt der Paxos-Algorithmus bei 2n+1 Servern immer noch Fortschritte. Daher empfiehlt es sich, in einem Cluster die Anzahl der Server aus der ungeraden Zahlenfolge: 3, 5, 7, 9 festzulegen; im Falle von HashiCorp sollte man 3 oder 5 Server wählen.Einer der Server wird als Leader vom Raft-Protokoll ausgewählt, die anderen stellen Follower dar (Bild 3). Wie bereits der Name Follower ausdrückt, folgen diese den Entscheidungen des Leaders. Im Prinzip handelt es sich bei den Followern um einen replizierten Knoten des Leaders. Das heißt das Raft-Protokoll bildet die Grundlage für die Replizierung der Datenbank des Consul-Clusters.
Der Betrieb eines Consul-Clusterserfolgt in einem Datacenter, das aus mehreren Servern und Clients besteht. Die Kommunikation zwischen Datacenter findet über das Internet mit speziellen Protokollen statt(Bild 3) © Simon
Jedes Consul-Cluster aus Servern und Clients läuft innerhalb eines Datacenters – für den Betrieb eines Consul-Systems in der Produktion gibt HashiCorp konkrete Empfehlungen anhand einer Consul Referenz-Architektur. Diese macht Vorgaben was die Hardware-Anforderungen, Provider (AWS, Azure, GCP) oder das Deployment auf K8s betrifft. Jeder Server kommuniziert mit seinen Clients über RPC, vergleichbar dem hochperformanten gRPC.Die Kommunikation innerhalb der Clients ermöglicht das Gossip-Protokoll; es bildet die Basis um Fehlerzustände zwischen den Clients zu entdecken und anderen Knoten mitzuteilen. Gossip verwaltet die Mitgliedschaft zum Cluster, sendet und empfängt Nachrichten innerhalb des Clusters. Dabei läuft Gossip innerhalb des WAN (Wireless Area Network) und dem LAN (Local Area Network). Anfragen über Datencenter hinweg reicht der Consul-Server an den Remote-Consul-
Server weiter; die Ergebnisse liefert der letztere an den
ursprünglichen Consul-Server zurück.

Starten eines Consul-Agenten als Server zum Aufbau eines Clusters

Das wichtigste Kommando für Consul stellt das Starten eines Agenten dar: consul agent -config-file=<value> -node=<value> -dev. Dieses CLI-Kommando startet einen Consul-Agenten mit dem Knotennamen value im Entwicklungsmodus und konfiguriert ihn anhand der in -config-file übergebenen Datei. Einen im Entwicklungsmodus laufenden Consul-Cluster sollte man nie in der Produktion zum Einsatz bringen, da in diesem Modus das sehr wichtige Feature der Persistenz ausgeschaltet bleibt.Normalerweise konfiguriert Consul selbständig Agenten anhand sinnvoll vorgegebener Einstellungen. Um für die Knoten eines Agenten individuelle Werte für den Aufbau und den Betrieb eines eigenen Consul-Clusters vorzugeben, spezifiziert man diese in HCL (siehe Teil 1) oder JSON. So empfiehlt es sich, für Client-Knoten eine hcl-Datei client.hcl, für Server-Knoten eine andere server.hcl und für den Bootstrap-Server eine weitere bootstrap.hcl einzurichten. Für den Betrieb eines Consul-Clusters in der Produktion sollte man einen speziellen Benutzer zum Beispiel adduser consul anlegen und anschließend alle Prozesse unter diesem consul-Benutzer starten. Zu den wichtigsten Einstellungen in der HCL-Konfigurationsdatei zählen: bootstrap, server, datacenter und data_dir:

# Datei server.hcl
bootstrap = false
server = true
datacenter = <span class="hljs-string">"germany"</span>
dat<span class="hljs-built_in">a_dir</span> = <span class="hljs-string">"consul/produktion"</span>
log_level = <span class="hljs-string">"INFO"</span>
enable_syslog = <span class="hljs-literal">true</span>
 
 
Bei bootstrap und server handelt es sich um boolesche Werte: Setzt man bootstrap = true, so muss server = true stehen und der Agent führt als Server-Knoten das Bootstrapping für den gesamten Consul-Cluster durch. Den Namen für das Datacenter gibt man über datacenter und das Verzeichnis für die Ablage persistenter Daten über data_dir vor.Selbst vorgegebene Einstellungen einer Konfigurationsdatei prüft das CLI-Subkommando validate auf formale Korrektheit. Dieser Befehl führt dieselben Prüfungen durch, wie sie der Befehl consul agent vornimmt. Einem CLI-Befehl consul validate muss mindestens ein Ordner oder eine Konfigurationsdatei übergeben werden. Ruft man consul validate mit einem Ordner auf, so überprüft Consul sämtliche in ihm befindlichen Konfigurationsdateien auf formale Korrektheit.Findet Consul keine fehlerhaften Einträge in einer Konfigurationsdatei erscheint die Meldung Configuration is valid! Zusätzlich überprüft consul validate weitere mögliche Fehlerquellen – so stellt validate zum Beispiel fest, ob sich im hostname der aktuellen Hardware ein Punkt befindet. Ein hostname mit einem Punkt stellt eine Fehlersituation dar, da der DNS-Service von Consul einen Hostnamen mit Punkt nicht lokalisieren kann.Um den Hauptprozess von Consul im Entwicklungsmodus als Server-Knoten zu starten, greift man auf das CLI-Kommando consul agent -config-file=server.hcl -node=macMini -dev zurück. Dadurch erhält der neu gestartete Server-Knoten den über node übergebenen Namen, im Beispiel macMini. Das Subkommando agent kommt zur Ausführung und gibt Informationsmeldungen im Terminalfenster aus (Bild 4): ==> Starting Consul agent…, Version: ‚1.11.4‘, Node ID:… und weitere.
Den Hauptprozess von Consulstartet der CLI-Befehl consul agent; dieser nimmt die erforderlichen Initialisierungen und Prüfungen vor(Bild 4) © Simon
So erscheint die Versionsnummer der installierten Consul-Software, die ID und der Name des Knotens (Node name) und des Datacenter, die IP-Adresse von Client und Cluster sowie die Verschlüsselung der verschiedenen Protokolle (Gossip, TLS). Da es sich beim gestarteten Server um den einzigen Knoten des Consul-Clusters handelt, wählt Consul diesen automatisch als Koordinator (Leader) aus. Im Anschluss an die Ausgabe ==> Log data will now stream in as it occurs: gibt Consul sämtliche Log-Meldungen aus. Zusätzlich erfolgen Informationsmeldungen zu eventuell von Consul festgestellten Fehlersituationen.

Consul-Cluster mit Client- und Server-Knoten über Docker bereitstellen

Der Befehl docker pull consul:1.9.16 lädt das von HashiCorp ausgelieferte Docker-Image von Consul in der Version 1.9.16 (auch TAG genannt) über die öffentliche Registry hub.docker.com herunter. Alle im lokalen Docker-System vorhanden Docker-Images von Consul zeigt der Befehl docker images --filter "reference=con*" an. Sollte noch ein weiteres Consul-Image vorhanden sein, so entfernt der Befehl docker image rm consul:TAG dieses Docker-Image aus dem lokalen Docker-System.

Domain Information Groper für Windows einrichten

dig for Windows (Bind 9) liefert das Internet Systems Consortium (ISC) auf deren Download-Seite https://www.isc.org/download/ aus. Leider findet ein Besucher die Software auf dieser Download-Seite nicht leicht. Über das Register BIND9 klickt man beim letzten Listeneintrag auf die Download-Schaltfläche. Jetzt erscheint ein Popup-Fenster, auf diesem befindet sich gleich links oben ein Download-Link zur aktuellen Windows-Version, derzeit <em>BIND9.16.28.x64.zip</em>.
Danach startet das nachfolgende Docker-Kommando docker run -d --name=docker-server consul:1.9.16 agent -server -ui -node=server-one -bootstrap-expect=1 -client=0.0.0.0 das Docker-Image mit dem TAG 1.9.16 in einem Container mit dem Namen docker-server. Consul vergibt für den Knoten den Namen server-one und startet ihn als Server-Knoten; entsprechend der vorgegebenen Kommandooptionen. Zusätzlich führt der consul agent-Befehl, sobald der Server zur Verfügung steht, sofort ein Bootstrapping durch und richtet ein Datacenter ein.Der über die Option -bootstrap-expect übergebene Wert 1 bewirkt während des Bootstrapping eine Verzögerung beim Aufbau des Datacenters. Der Wert entspricht der im Consul-Cluster benötigten Server-Anzahl, um das Datacenter betreiben zu können. Sobald der Wert größer als 1 ist, versetzt dieser jeden Knoten im Consul-System in einen Wartezustand. In diesem Fall wartet Consul mit dem Bootstrapping des Clusters solange bis die gewünschte Anzahl der über -bootstrap-expect erzeugten Server für das Datacenter vorhanden ist.Sobald die über -bootstrap-expect notwendige Anzahl der Server für das Datacenter erzeugt ist, führt Consul das Bootstrapping für den gesamten Cluster durch. Die Option -bootstrap-expect setzt voraus, dass der Knoten im consul agent-Befehl die Option -server besitzt. Ferner darf -bootstrap-expect nicht zusammen mit -bootstrap verwendet werden, da die beiden Optionen sich widersprechen. Da oben die Client-IP-Adresse auf 0.0.0.0 gesetzt wird, kann man von der lokalen Maschine aus über localhost arbeiten, um auf den Consul-Cluster zuzugreifen.Das Subkommando members des Consul-CLI zeigt alle Knoten eines Consul-Clusters zusammen mit ihrem Namen, IP-Adresse, Zustand (alive, left, failed), Knoten-Typ (server, client) und dem zugehörigen Datacenter an. Um den CLI-Befehl consul members im Docker-Container docker-server auszuführen, gibt man den Befehl docker exec docker-server consul members ein. Einen Client-Knoten fügt der Befehl docker run --name=docker-client-1 consul:1.9.16 agent -node=client-1 -join IP-AdresseX in den bestehenden Consul-Cluster ein. Dabei entspricht IP-AdresseX der über das Subkommando members beim Server-Knoten angezeigten IP-Adresse.

Client-Knoten dem Consul-Cluster hinzufügen und Monitoring starten

Mit dem Befehl docker exec docker-server consul members erhält man einen Überblick zu den im Consul-Cluster aktuell enthaltenen Knoten. Dasselbe Ergebnis erhält man, wenn man den Befehl docker exec docker-client-1 consul members anstatt im Container docker-server im Container docker-client-1 ausführt. Der nächste Schritt soll dem Consul-Cluster einen weiteren Client-Knoten hinzufügen, der mit dem gerade erzeugten client-1 verknüpft ist.Dazu setzt man den Befehl docker run --name=docker-client-2 consul:1.9.16 agent -node=client-2 -join IP-AdresseY ein; wobei IP-AdresseY der beim consul members-Befehl beim Client-Knoten client-1 angezeigten IP-Adresse entspricht. Die über docker exec docker-server consul members angezeigte Liste der Knoten des Consul-Clusters enthält jetzt drei Einträge: server-one, client-1 und client-2.Eine besondere Wirkung hat die Option -retry-join des CLI-Befehls consul agent – verwendet man -retry-join anstelle von -join, so erfolgt nachdem die Verbindung zwischen den Knoten verloren ging, automatisch ein erneuter Verbindungsaufbau. Dabei schließt die Option -retry-join auch einen Restart des Knoten mit ein.Sollen Änderungen in einem bestimmten Datentyp beobachtet werden, so steht der CLI-Befehl consul watch -type zur Verfügung. Mittels der obligatorischen -typ-Option legt man den zu beobachtenden Datentyp (Schlüssel, Service, Knoten, Event, et cetera) fest. Sobald Änderungen auftreten, kann man einen externen Prozess starten und geeignete Aktionen ausführen.Soll für einen bestimmten Knoten des Clusters ein Logging durchgeführt werden, so erreicht man dies über den consul monitor-Befehl mit der Option -http-addr, der man die IP-Adresse des betroffenen Knoten übergibt. Schickt man jetzt an diesen Knoten zum Beispiel eine ungültige Nachricht, so wird eine Fehlermeldung protokolliert (Bild 5).
Der CLI-Befehl consul monitorprotokolliert für den über die Option -http-addr erreichbaren Knoten alle mit ihm durchgeführten Aktionen(Bild 5) © Simon
Entfernt man anschließend den beobachteten Knoten aus dem Cluster mit dem CLI-Befehl consul leave, so erhält dieser den Status left und eine Informationsmeldung wird ins Log eingetragen. Für einen entfernten Knoten wird keine -retry-join-Option mehr ausgeführt. Alle anderen weiterhin im Cluster enthaltenen Knoten sehen, aufgrund des Status left, dass der Knoten nicht aufgrund eines Fehlers seine Aktivitäten eingestellt hat – in diesem Fall wäre der Zustand des Knotens nicht left sondern failed.

Das Service Mesh von Consul bietet vielfältige Erleichterungen

Ein Service Mesh übernimmt als dedizierte Infrastruktur die Steuerung der Kommunikation und damit die Abwicklung der Dienste zwischen den Services. Diese eigenständige Schicht oder Komponente erleichtert die Durchführung und das Nachvollziehen der Kommunikation zwischen den Teilnehmern, insbesondere wenn deren Anzahl sehr groß ist. Eigenständige Teile einer Anwendung, die man Services nennt, kommunizieren über ein Service Mesh miteinander.Das Service Mesh kontrolliert das Verteilen von Serviceanfragen in einer Anwendung. Ein Service Mesh kommt häufig bei cloudbasierten Anwendungen, Containern und Microservices zum Einsatz. Anwendungen mit Microservice-Architektur bestehen aus einer Vielzahl von Services, die alle ihre eigenen Instanzen betreiben. Somit eignet sich ein Service Mesh insbesondere für den Betrieb von Microservices.Ergänzend zur Kommunikation übernimmt ein Service Mesh weitere zentrale Aufgabenstellungen wie Diensterkennung, Hochverfügbarkeit, Load Balancing, Verschlüsselung, Traffic-Management, Fehlerbehandlung, Health-Monitoring, Authentifikation und Autorisierung. Die von Consul realisierte Service Mesh-Lösung basiert auf einem software-getriebenen Ansatz. Typischerweise besteht ein Service Mesh aus einem Control Pane und einem Data Pane. Das Data Pane führt die Kommunikation zwischen den Services durch. Alle anderen zuvor genannten Aufgaben übernimmt das Control Pane.

Kommunikation des Data Pane

In der Regel findet die Kommunikation des Data Pane über ein Proxy statt; damit erhöht man die Sicherheit, da sich über das Proxy weniger Angriffspunkte ergeben. Zusätzlich grenzt man das benötigte, das heißt das erforderliche Wissen über das gesamte Netzwerk innerhalb der Services ein. Sobald das Service Mesh aktiviert ist, baut jeder Service innerhalb der Anwendung eine Verbindung zum Proxy auf.Das von Consul bereitgestellte Service Mesh, nennt man gelegentlich auch Consul Connect, es positioniert Aufgaben des Netzwerks wie Routing oder Autorisierung an die Endpunkte des Netzwerks. Consul stellt ein auf einem API-basierenden Control Pane dar, in das man als Data Pane zusätzlich Proxies wie Envoy, HAProxy oder NGINX integrieren kann. Damit erhält man ein Zero-Trust-Netzwerk, das eine Service-to-Service-Kommunikation mittels automatischer TLS-Verschlüsselung und identitäts-basierter Autorisierung absichert.

Authentifizierung und Autorisierung

Eine Authentifizierung identifiziert einen Service oder Benutzer gegenüber dem System, so dass es danach den Service/Benutzer kennt. Während eine Autorisierung eine Erlaubnis erteilt, etwas zu tun oder etwas zu bekommen – wobei eine Authentifizierung vorausgeht.
In diesem Zero-Trust-Netzwerk basiert die Sicherheitspolitik nicht mehr auf IP-Adressen sondern auf Intentions mit logischen Services. Als zentrale Public-Key-Infrastruktur (PKI) und Zertifikationsmanagement lässt sich das HashiCorp-Produkt Vault in Consul integrieren.Die Konfiguration der Services erfolgt durch einen API-basierten Key/Value-Store; diesen benutzt man, um die Services zur Laufzeit zu konfigurieren.

Services im Consul-Cluster einrichten und für Abfragen bereitstellen

Um einen Service in einem Consul-Cluster auffinden zu können, muss dieser eingerichtet und in der Service-Registry von Consul eintragen werden. Für die Definition eines Service bieten sich in Consul zwei Vorgehensweisen an: Registrierung anhand von Vorgaben in einer Definitionsdatei oder durch Aufruf eines HTTP-APIs mit Übergabe der Service-Definitionen zur Laufzeit.Recht einfach erfolgt die Service-Definition über eine HCL- oder JSON-Konfigurationsdatei. Für jeden individuellen Service sollte man eine eigene service.hcl/json-Datei anlegen – zum Beispiel für MongoDB eine service-mongodb.hcl/json-Datei:

# Datei: service-mongodb.hcl
service {
    name = "mongodb"
    id   = "database"
    port = 27017
    checks = [ { 
        args = ["/consul/scripts/mongo_check.sh"]
        interval = "10s"
    } ]
}
 
 
In einer service.hcl/json-Datei befinden sich die Definitionen des Service mit verschiedenen Parametern, welche die einzelnen Einstellungen des jeweiligen Services repräsentieren.Sobald ein consul agent-Befehl zur Ausführung kommt, liest Consul die Definitionen der services.hcl/json-Datei ein und gibt eine Meldung …Synced service "serviceName" aus. Das heißt, der gestartete Consul-Agent hat die Service-Definition mit dem Namen serviceName aus der HCL/JSON-Konfigurationsdatei gelesen, an einen Consul-Server weitergereicht und dieser hat den Service erfolgreich im Service-Katalog registriert.Generell kann ein Consul-Server jeden Service registrieren, gänzlich unabhängig davon, ob dieser tatsächlich ausgeführt wird. Sobald sich ein Service im Service-Katalog
befindet, kann dieser abgefragt werden. Für diese Abfrage steht das DNS-Interface oder das HTTP-API von Consul zur Verfügung.Consul stellt eine Vielzahl von Parametern für die Definition eines Service in einer HCL- oder JSON-Konfigurationsdatei bereit. Von diesen Parametern müssen lediglich die Einstellungen von service und name obligatorisch also immer vorhanden sein. Die Vorgabe der Parameter verfolgt das Ziel, den extern bereitgestellten Service für andere Partner über den Consul-Cluster zugänglich zu machen.Oder anders ausgedrückt: Die Definition der Parameter eines Service beschreiben, wie dieser durch andere Services im Netzwerk gefunden und benutzt werden kann. Dazu muss man die Schnittstelle des gewünschten Service kennen. Soll zum Beispiel MongoDB als Service bereitgestellt werden, so übergibt man für den port-Parameter den Default-Port 27017 aus dem Verbindungsaufbau von MongoDB. Man greift in diesem Fall also bei der Service-Definition auf die Konventionen beziehungsweise konkret zugrundeliegenden Einstellungen der zu nutzenden Software zurück.

Services mit Health-Checks ausstatten und registrieren

Service können mit Health-Checks verbunden sein – diese ermöglichen Zustandsüberprüfungen (Health-Checks) speziell auf der Anwendungsebene. Zielsetzung dieser Prüfungen ist es, im Falle einer Inkonsistenz alle notwendigen Aufräumarbeiten oder Recovery-Aktionen durchzuführen. Derartige Health-Checks definiert man entweder über eine Konfigurationsdatei oder fügt diese zur Laufzeit über das HTTP-Interface hinzu.Einen über das HTTP-Interface hinzugefügten Health-Check wird persistent mit dem Knoten gespeichert. Consul unterstützt auch das Laden einer geänderten Konfigurationsdatei mit dem Befehl consul reload. Allerdings kann nicht für alle Konfigurationseinstellungen ein Reload durchgeführt werdenb. Alle derart nachträglich eingerichtete Health-Checks speichert Consul nicht im data_dir-Verzeichnis.Für die Definition von Health-Checks besitzt Consul einen speziellen checks-Parameter, über den man verschiedene Arten von Prüfungen: Script, HTTP, TCP, TTL, Docker, gRPC, H2ping oder einen Alias Check definiert. Recht häufig kommen Script-Checks zum Einsatz, um diese zu aktivieren, muss eine der beiden Optionen -enable-local-script-checks oder -enable-script-checks eingeschaltet werden.Für den Betrieb in der Produktion sollte man immer die zweite Option -enable-local-script-checks verwenden, da diese die Einrichtung von Script-Checks über das HTTP-API verhindert. Damit stellt man sicher, dass über Consul durch externe Hacker-Angriffe keine Scripts ungewollt ausgeführt werden.Ein Script-Check besteht immer aus einem args-Feldelement, das ein oder mehrere Shell-Scripts referenziert. Anhand des zweiten Feldelements interval legt man fest, in welchen Zeitabständen die Health-Checks für den Service zu wiederholen sind. Eventuell spezifiziert ein weiteres Feldelement timeout, nach welcher Zeitdauer Consul für den Health-Check ein Timeout-Event erzeugt.Derart übergebene Shell-Scripts stößt Consul eigenständig an und ermittelt anhand des Rückgabewerts den aktuellen Zustand des jeweiligen Service. Dabei bedeutet der Rückgabewert 0 eine korrekte Ausführung, 1 stellt eine Warnung dar und jeder andere Wert entspricht einer Fehlersituation.

Services mit Health-Checks nachträglich anreichern und erkunden

Die Registrierung eines Health-Checks kann auch nachgelagert über das Consul-CLI oder das HTTP-API erfolgen. Dazu legt man eine JSON-Datei an, welche die Deklarationen eines Service zusammen mit dem Health-Check enthält. Führt man anschließend den CLI-Befehl consul services register service-mongodb.json aus, so nimmt Consult eine Registrierung des Service vor. Anschließend erscheint die Informationsmeldung: Registered service: <serviceNameX>.Analog erfolgt auch eine erfolgreich Anlage des Services über das HTTP-Interface mit dem Befehl curl -i -X PUT --data @service-mongodb.json http://127.0.0.1:8500/v1/agent/service/register (Bild 6). Um einen Service zusammen mit seinem Health-Check wieder aus der Registry zu entfernen, steht eine deregister-Variante des CLI- beziehungsweise HTTP-Befehls zur Verfügung.
Die HTTP-Schnittstelleregistriert während des Betriebs eines Consul-Clusters einen Service(Bild 6) © Simon
Die Registrierung eines Service erfolgt immer für den Consul-Agent, der die Registrierung durchführt. Soll der Service für einen anderen Consul-Agent registriert werden, so legt man in der Service-Deklaration ein Address-Feld mit der IP-Adresse des gewünschten Consul-Agenten an. Anschließend trägt Consul dann die Registrierung des Service bei dem über die IP-Adresse erreichbaren Knoten ein.Um die Existenz eines Service über den DNS (Domain Name System) abzufragen, greift man auf den dig-Befehl zurück – die Abkürzung dig steht für domain information groper. Consul empfängt DSN-Abfragen auf der Adresse 127.0.0.1:8600 – der dig-Befehl lautet wie folgt: dig @127.0.0.1 -p <port> [tag.]<service-name>.service[.datacenter]. <domain>; wobei es sich bei tag und datacenter um optionale Angaben handelt. In der Regel erfolgt die Abfrage auf der vorhandenen consul-Domain.Die Anzahl der auf einem Consul-Cluster verfügbaren Services ermittelt man mit dem CLI-Befehl consul info. Er gibt für den jeweiligen Agent über das Feld checks, die Anzahl der auf ihm eingerichteten Health-Checks als Summe aus. Detaillierte Informationen über die Verfügbarkeit eines Service liefert der CLI-Befehl consul watch -type=services (Achtung es muss Plural verwendet werden!). In diesem Fall liefert Consul eine JSON-Datei mit allen registrierten Services zurück.Um gezielt die Definition eines bestimmten Service mit dem Name serviceNameX abfragen, übergibt man diesem CLI-Befehl zusätzlich noch die Option -service=serviceNameX. Setzt man beim consul watch -type=service-Befehl die Option -tag=tagNameX ein, so liefert Consul eine JSON-Datei mit allen Services zurück bei denen ein Tag mit der Bezeichnung tagNameX vorhanden ist.

Hierarchischer Key/Value-Speicher (KV) für alle Clients verfügbar

Eines der Hauptmerkmale von Consul stellt der sogenannte Consul KV (Key/Value-Store) dar, manchmal auch KV-Datastore (Key/Value-Speicher) oder kurz: KV genannt. Der Consul KV dient als zuverlässiger Speicher für Konfigurations- und Metadaten – dabei handelt es sich natürlich um kein vollständiges Datenbanksystem. Consul verwendet den KV-Store auch zur Verwaltung der internen Daten des gesamten Clusters.Dazu gehören die Daten zum dynamischen Aufbau des Clusters, Ergebnisse der Koordination oder zur Auswahl des Leaders. Ein Key (Schlüssel) besitzt einen hierarchischen Aufbau angelehnt an einer Verzeichnisstruktur – als Trennzeichen kommt ein Slash "/" zum Einsatz. Beispielsweise stellt die Zeichenkette "daten/konfig/max-verbindungen" einen gültigen Schlüssel dar. Jeder Schlüssel bekommt einen Wert zugeordnet, den Consul automatisch nach dem Base64-Verfahren kodiert. Ein solcher Wert darf die Größe von 512 KByte nicht überschreiten. Die Base64-Kodierung entspricht keiner Verschlüsselung der Daten. Vielmehr gewährleistet Base64 eine codepage-unabhängige ASCII-Zeichenfolge, um eine systemübergreifende Lesbarkeit der Datenwerte sicherzustellen.Die Ablage der Daten eines Keys erfolgt im dem für jeden Consul-Agent spezifizierten Datenordner (data-dir); dort legt Consul auch die Zustände der Knoten und sicherheits-
relevante Daten wie ACL (Access Control Lists/Zugriffssteuerungslisten)-Token ab. Befindet sich ein Consul-Cluster im Modus -dev (Entwicklungsmodus), so führt Consul keinen externen Schreibvorgang über den Datenordner durch, die Daten werden lediglich im Hauptspeicher gehalten. Im Produktionsbetrieb enthält der Datenordner sämtliche Daten auch die des Key/Value-Stores. Aus Sicherheitsgründen muss der Zugriff auf das data-dir-Verzeichnis eingeschränkt werden. Nach
einem ordnungsgemäßen Shutdown eines Clusters und dessen erneutem Start stehen die Daten wieder zur Verfügung.Consul besitzt ein Transaktionsmanagement, um Operationen im Key/Value-Store fehlerfrei, vollständig unter Wahrung einer logischen Einheit durchzuführen. Das als HTTP-API realisierte Transaktionsmanagement stellt sicher, dass Änderungen mehrerer Clients nicht versehentlich verloren gehen. Mit Hilfe des APIs lassen sich Semaphore oder verteilte Locks/Sperren realisieren. Derartige Sperren implementiert man über eigene Einträge im Key/Value-Store.Zusätzlich besitzt Consul einen optionalen Session-Mechanismus, der als Bindeglied zwischen den Knoten, den Health-Checks und dem Key/Value-Store dient. Startet man über diesen eine Session, so erhält diese eine ID zur Identifikation – die gleichzeitig als Sperre fungiert. Alle innerhalb der Session vorgenommen Operationen an den Daten unabhängig ob Knoten, Health-Checks, Key/Value-Store oder andere, unterliegen dabei einer Transaktion.

Arbeiten mit dem CLI des Key/Value-Stores

Der Key/Value-Store von Consul verfügt über ein CLI: consul kv, das die gängigen CRUD (Create, Read, Update, Delete)-Funktionen unterstützt (Bild 7). Der allgemeine Aufruf des CLIs, um ein Schlüsselpaar in den Key/Value-Store zu schreiben, lautet: consul kv put <schluesselX> <wertY>. So fügt der Befehl consul kv put dev/web "Bestellung" das Schlüsselpaar dev/web "Bestellung" in den Key/Value-Store ein.
Um diesen Eintrag aus dem Key/Value-Store von Consul zu lesen, greift man auf den Befehl consul kv get <schluesselX> zurück. Dabei liefert consul kv get dev/web den zuvor in den KV-Store gespeicherten Wert "Bestellung" zurück.
Der KV-Store von Consulkennt die gängigen CRUD-Operationen für die Anlage, Lesen, Änderen und Löschen von Key/Value-Paaren(Bild 7) © Simon
Um ein Update eines Werts zu einem Schlüssel durchzuführen, überschreibt man einfach dessen Wert mit dem put-Subkommando: consul kv put dev/web "Umsatz". Zum Löschen steht das Subkommando delete zur Verfügung: consul kv delete dev/web. Sämtliche im Key/Value-Store enthaltenen Schlüssel (ohne ihre Werte) gibt der CLI-Befehl consul kv get -keys aus. Um über ein Netzwerk auf ein eingerichtetes Consul-Cluster mittels dem Befehl consul kv zu arbeiten, besitzt dieser Befehl die Option -http-addr. Darüber erreicht man im Netz durch Übergabe der IP-Adresse eines Cluster-Knotens und des Default-Port 8500 einen entfernten Consul-Cluster: -http-addr=192.168.56.10:8500.Organisiert man die Schlüssel im obigen Beispiel als Hierarchie, so erschließt man sich eine mehrstufige Ablagestruktur für die Daten. Im Beispiel dev/web lassen sich Datenwerte für den kompletten Pfad dev/web und zusätzlich für dev ein weiterer Datenwert ablegen. In der Realität findet man oft derartige Hierarchien – man spricht von hierarchisch strukturierten Daten. Derartige Daten liegen immer vor, wenn sich Objekte zu einer übergeordneten Einheit zusammenfassen lassen.Ein Key/Value-Store mit hierarchischen Schlüsseln besitzt für den get-Befehl eine besondere -detailed-Option. Sie gibt für die übergebene Hierarchie eine Informationsmeldung mit den kompletten Metadaten sowie dem Schlüssel und seinem aktuellen Wert aus. Zusätzlich steht mit der -recurse-Option eine rekursive Abfrage der Hierarchie zur Verfügung. Alle Schlüssel mit ihren Werten inklusive des Wurzelknotens (hier: KeyX) entfernt der Befehl: consul kv delete -recurse <KeyX> aus dem KV-Store. Kombiniert man die -detailed-Option mit -resurse, so gibt Consul die Metadaten für alle betroffenen Pfade aus.Das CLI des Key/Value-Stores besitzt auch eine Import- und Export-Schnittstelle, um Daten aus einer JSON-Datei zu lesen oder in eine JSON-Datei zu schreiben. Die Import-Schnittstelle ermöglicht es, alle in einer JSON-Datei eingetragenen Schlüssel-Wert-Paare durch einen einzigen Befehl in den Key/Value-Store von Consul zu schreiben: consul kv import @datei.json. Damit lässt sich ein kompletter Datenbestand zum Beispiel ein Backup in den KV-Store eines Consul-Clusters übernehmen. Mit der Export-Schnittstelle speichert man alle im Key/Value-Store vorhandenen Daten in einer externen JSON-Datei ab. Typischer Anwendungsfall dafür stellt eine Datensicherung für ein Backup dar. Sollen die Daten für einen bestimmten Zweig der Hierarchie des Key/Value-Stores exportiert werden, so übergibt man einfach diesen Pfad an das export-Subkommando. Bei den Datenwerten ist zu beachten, dass diese über Base64 kodiert sind. Um deren Realwerte zu bestimmen, muss man diese entsprechend dekodieren.

Consul-Cluster über virtuelle Maschinen für KV-Store bereitstellen

Das Consul-Cluster in einem Datacenter soll aus drei Server-Maschinen und einer Client-Maschine bestehen, die jede für sich in einem Ubuntu-System läuft. Die Bereitstellung der vier Ubuntu-Systeme erfolgt jeweils über eine eigene virtuelle Maschine. Für den Bau der virtuellen Maschine kommt Vagrant (siehe Teil 2) zum Einsatz – das Vagrantfile enthält die benötigten Spezifikationen:

# Datei: Vagrantfile
# Vagrantfile fuer server-1
Vagrant.configure(2) do |config|
    
    config.vm.box = "ubuntu/xenial64"
    
    config.vm.define "server1" do |server1|
    
      server1.vm.hostname = "server-1"
      server1.vm.network "private_network", ip: "192.168.56.10"
      
      config.vm.provision "shell" do |s|
           s.path = "provision.sh"
           s.args   = ["/vagrant/config.json"]
        end
    end
end
 
 
Dabei greift Vagrant auf die Vagrant Box ubuntu/xenial64 zurück. Alle drei Server erhalten die Hostnamen server-1, server-2 und server-3; die Client-Maschine bekommt den Namen client-1 zugewiesen. Ein dazu passendes Script-Shell erledigt mittels Provisioning die Installation der Consul-Software in alle vier Ubuntu-Systeme, richtet deren Konfiguration ein und startet den Consul-Agenten:

# Datei: provision.sh
 
# System-Update durchfuehren und unzip-Tool installieren
sudo apt-get update
sudo apt-get install -y unzip
 
# Die Consul-Zip-Datei herunterladen und entpacken
cd /usr/local/bin
sudo wget https://releases.hashicorp.com/consul/1.11.4/consul_1.11.4_linux_amd64.zip
sudo unzip *.zip
sudo rm *.zip
 
# Das Consul-Verzeichnis mit der Konfigurationsdatei einrichten
sudo mkdir -p /etc/consul.d
sudo mkdir /var/consul
sudo cp $1 /etc/consul.d/config.json
 
# Den Consul-Agenten starten
sudo consul agent -config-file=/etc/consul.d/config.json
 
 
Die IP-Adressen für die drei Server lauten server-1: 192.168.56.10, server-2: 192.168.56.20, server-3: 192.168.56.30 und für den Client: 192.168.56.40. Diese IP-Adressen trägt man im Vagrantfile für die Definition des Netzwerks der virtuellen Maschinen ein. Zusätzlich nimmt man in die config.json-Datei jedes einzelnen Consul-Knoten die jeweils passende IP-Adresse auf. Die Consul-Software liest die Einträge beim Start eines Consul-Agent aus der config.json-Datei:

{
    "bootstrap": true,
    "server": true,
    "datacenter": "datacenter-1",
    "data_dir": "/var/consul",
    "ui_config": {
          "enabled": true
        },
    "encrypt": "Dt3xUVpKGAR/fNUN1cDirg89",
    "log_level": "INFO",
    "enable_syslog": true,
    "bind_addr": "192.168.56.10",
    "client_addr": "192.168.56.10"
}
 
 
Lediglich der erste Server-Knoten bekommt ein mit true gekennzeichnetes bootstrap-Attribut. Bei allen anderen Servern und dem Client erhält dieses bootstrap-Attribut den booleschen Wert false. Zusätzlich erhalten die anderen Server- und der Client-Knoten passende Werte für das retry_join-Attribut. Dieses Attribut fügt die einzelnen Knoten entsprechend den Servern dem Consul-Cluster hinzu:

{
    "bootstrap": false,
    "server": false,
    "datacenter": "datacenter-1",
    "data_dir": "/var/consul",
    "ui_config": {
          "enabled": true
        },
    "encrypt": "Dt3xUVpKGAR/fNUN1cDirg89",
    "log_level": "INFO",
    "enable_syslog": true,
    "bind_addr": "192.168.56.40",
    "client_addr": "192.168.56.40",
    "retry_join": ["192.168.56.10", "192.168.56.20", "192.168.56.30"]
}
 
 
Mit dem Befehl vagrant up erzeugt man jede einzelne virtuelle Maschine für die drei Server- und den Client-Knoten. Dieser Vorgang wiederholt sich insgesamt vier Mal. Beim erstmaligen Aufruf von vagrant up lädt Vagrant die zugehörige Box ubuntu/xenial64 aus der Vagrant-Cloud über die öffentlich zugänglichen Registry herunter.Anschließend importiert Vagrant die Definitionen aus dieser Box und erzeugt die virtuelle Maschine, legt dabei deren Hostname und die zugehörigen Einstellungen für ihr Netzwerk an. Im nächsten Schritt aktualisiert das Provisioning das Betriebssystem, lädt das unzip-Tool und die Consul-Software herunter.Danach erfolgt die Installation der Consul-Software im Ubuntu Guest-Betriebssystem und das Shell-Script richtet die Konfigurationsdateien für jeden einzelnen Consul-Knoten passend im jeweiligen Ordner ein. Zum Schluss startet das Shell-Script den zugehörigen Consul-Knoten.Nachdem alle drei Server-Knoten und der Client-Knoten vorhanden sind, erzeugt die Consul-Software das definierte Consul-Cluster. Dazu führt Consul das Bootstrapping mit dem Knoten server-1 durch und baut die Verbindungen über das Netzwerk zu den anderen Server- und dem Client-Knoten auf. Anschließend zeigt der Befehl consul members -http-addr=192.168.56.10:8500 alle Knoten des Clusters an. Für die Programmierung mit Consul gibt es eine Reihe von Schnittstellen in verschiedenen Sprachen. Dazu gehören C#, Closure, Dart, Erlang, Go, Haskell, Java, JavaScript, PHP, Python, Ruby, Rust, Scala und Swift.Die offizielle seitens HashiCorp unterstützte Library stellt das in Go realisierte HTTP-API dar. Dieses API stellt eine objektorientierte Schnittstelle für die Programmierung in Go zu Verfügung. Um mit Go zu programmieren, benötigt man die Installation eines Go-Systems und eine passende Einrichtung in der IDE (siehe Teil 1). Anschließend richtet der Befehl go get github.com/hashicorp/consul/api das Go-Package von Consul im Go-System ein.

Zugriff auf den Key/Value-Store des Consul-Clusters mit Golang

Die Ausführung des Go-Progamms setzt ein laufendes Consul-System voraus, dazu eignet sich der über die vier virtuellen Maschinen zugängige Consul-Cluster. Für die Zugriffe vom Go-Programm auf den Consul-Cluster benötigt man ein Config-Objekt, das man durch Aufruf der Funktion DefaultConfig() erzeugt:

package main
 
import (
    "fmt"
    "strconv"
    consulapi "github.com/hashicorp/consul/api"
)
 
func main() {
    var zeichenKette string
 
    // Eine Verbindung zum Client anlagen
    config := consulapi.DefaultConfig()
 
    config.Address = "192.168.56.10:8500"
    consul, err := consulapi.NewClient(config)
    if err != nil {
       panic(err)
    }
 
    // Ein Handle Key/Value-Paar zum KV-API erzeugen
    kv := consul.KV()
 
    for zahl := 0; zahl &lt; 5; zahl++ {
        // Ein Schluessel/Wert-Paar erzeugen
        zeichenKette = "buchhaltung" + strconv.Itoa(zahl) + ".de"
        paar := &amp;consulapi.KVPair{Key: "App/Europe/Germany/" + strconv.Itoa(zahl), Value: []byte(zeichenKette)}
        // Das Schluessl-Paar in den KV des Consul-Clusters schreiben
        _, err = kv.Put(paar, nil)
        if err != nil {
            panic(err)
        }
    }
 
    // Ein Schluessel/Wert-Paar aus dem KV-Store lesen
    paar, _, err := kv.Get("App/Europe/Germany/3", nil)
    if err != nil {
        panic(err)
    }
    // Die Werte des Schluessel/Wert-Paars ausgeben
    fmt.Printf("Schluessel: %v \n", paar.Key)
    fmt.Printf("Wert zum Schluessel: %s \n", paar.Value)
}
 
 
Anschließend setzt man dessen Address-Attribut auf die IP-Adresse eines Consul-Server-Knoten in unserem Fall auf 192.168.56.10:8500. In der Regel initialisiert Consul das Config-Objekt mit passenden Werten. Im Bedarfsfall passt man dieses Config-Objekt an die individuellen Vorgaben im Projekt an.So besitzt es unter anderem die Attribute Datacenter und HttpAuth. Über Datacenter richtet man den Namen des gewünschten Datacenter ein. Mittels der Funktion HttpBasicAuth() setzt man das Attribut config.HttpAuth auf einen Zeiger, der eine Zeichenkette für die HTTP-Basic-Authentifizierung enthält: config.HttpAuth = &consulapi.HttpBasicAuth{Username: "benutzer", Password: "kennwort"}. Danach reicht die Anweisung NewClient(config) diese Einstellungen an das Config-Objekt weiter. Das Consul-Client-Objekt enthält die KV()-Methode, deren Aufruf ein Handle auf ein Key/Value-Paar erzeugt, das einem Go-struct entspricht. Über diese Go-Record-Struktur erhält man Zugriff auf den Key/Value-Store des Consul-Clusters.Das Handle auf ein Key/Value-Paar besitzt als wesentliche Attribute ein Key- und ein Value-Feld, um Schlüssel/Wert-Paare an den Key/Value-Store weiterzureichen. Mittels der Methode Put() des Key/Value-Paar-Handle schreibt man ein Schlüssel/Wert-Paar in den Key/Value-Store. Die Methode Get() des Key/Value-Paar-Handle liest ein Schlüssel/Wert-Paar entsprechend dem übergebenen Schlüssel aus dem Key/Value-Store. Um einen Schlüssel aus dem Key/Value-Store zu löschen, besitzt das Go-API die Methode Delete(). Eine komplette Hierarchie aus dem Key/Value-Store entfernt die Methode DeleteTree(). Dabei löscht DeleteTree() ausgehend von der übergebenen Zeichenkette die nachfolgende Hierarchie vollständig aus dem Key/Value-Store.

KV-Store über Web-App von Consul einsehen und Einträge bearbeiten

Consul verfügt über eine integrierte Web-App mit der man alle wichtigen Komponenten eines Consul-Clusters näher erkunden kann. Um diese Web-App über einen Browser zugänglich zu machen, muss man für den Consul-Agent in der config.json-Datei den Eintrag ui_config auf "enabled": true setzen. Alternativ startet man den Consul-Agenten mit der Option -ui. Betreibt man einen Consul-Cluster im Entwicklungsmodus, ist die Web-App automatisch aktiviert.Standardmäßig startet sich die in Consul integrierte Web-App über die URL http://localhost:8500 (Bild 8); wobei man localhost eventuell durch die konkrete IP-Adresse eines am Consul-Cluster teilnehmenden Knoten ersetzen muss. Den Port in der CLI-Option -http(s)-port oder das ports-Objekt (http/https) in der config.json-Datei kann man von 8500 auf einen beliebig freien, passenderen Port abändern.
Die in Consul integrierte Web-Appbietet eine Benutzungsschnittstelle für das interaktive Arbeiten mit den Objekten in einem Consul-Datacenter(Bild 8) © Simon
In der Web-App lässt sich für jedes Datacenter die vorhandenen Services, Knoten, die Einträge im Key/Value-Store, Intentions, ACLs (Access Control Lists/Zugriffssteuerungslisten) oder andere Settings näher erkunden. Klickt man in der Liste der Knoten eines Consul-Clusters auf einen bestimmten Knoten, so erhält man Einblick zu dessen Innenleben. Es erscheinen verschiedene Registerkarten anhand derer man sich detaillierte Informationen zu den Health-Checks, den Service-Instances, der Round-Trip-Time, den Lock-Sessions und der Metadaten anzeigen kann. Im Bedarfsfall lassen sich auch die Daten der Komponenten des Consul-Clusters ändern. Dabei stellen sich die direkten Verknüpfungen der Web-App mit der Dokumentation von Consul als recht hilfreich heraus.So kann man die Einträge des Key/Value-Stores direkt über die Web-App erstellen, vorhandene ändern oder löschen. Ein Klick auf die Schaltfläche Create im Bereich Key/Value der Web-App öffnet einen Dialogbereich New Key/Value. Trägt man dort im Eingabefeld Key or folder einen (hierarchischen) Schlüssel und im Eingabefeld Value den zugehörigen Wert ein, so trägt ein Klick auf die Save-Schaltfläche das Key/Value-Paar in den KV-Store ein.Beim Erkunden der Einträge im Key/Value-Store erscheint rechts unterhalb von Actions ein -Menü darüber löscht man gegebenenfalls einen Eintrag. Um einen Wert zu ändern, erkundet man diesen über seinen Key, ändert ihn und speichert ihn durch Klick auf die Save-Schaltfläche. Rechts oben befindet sich eine Verknüpfung Settings, um die aktuellen Einstellungen der Web-App einzusehen oder zu ändern.Bei Consul Connect handelt es sich um ein Subsystem von Consul, das Autorisierung und Verschlüsselung verantwortet. Für die Kommunikation zwischen den Services greift Consul auf einen Proxy-Server zurück. Dabei benutzt es entweder den eignen Layer 4-Proxy oder einen anderen – wobei vorzugsweise Envoy zum Einsatz kommt. Der Proxy-Server stellt einen zusätzlichen Schutz dar – als Schaltzentrale mit geringer Komplexität besitzt er weniger Angriffspunkte als das Consul-System als Ganzes betrachtet. Externe Anwendungen nutzen, völlig unabhängig von Consul Connect, den Proxy und bauen TLS-Verbindungen auf. Connect verwendet registrierte Services, verbunden mit einer Zugriffskontrolle über Intentions. Intentions definieren die Zugriffskontrolle für Services und überprüfen, welche Services Verbindungen aufbauen oder Anfragen vornehmen können.

Consul Connect – das integrierte Subsystem für erhöhte IT-Sicherheit

Die Verwaltung von Intentions findet über CLI, API oder die Web UI statt. Abhängig vom Protokoll eines Services erfolgt die Autorisierung entweder über das Layer 4 (Transport-Schicht, TCP) oder über Layer 7 (Anwendungsschicht, HTTP). Bei Layer 4-Intentions handelt es sich um identitätsbasierte Zugriffe, die auf TLS-Zertifikaten basieren. Im Unterschied dazu benötigen Layer 7-Intentions zusätzlich zum Verbindungsaufbau über Identitäten weitere L7-Attribute auf der Protokollebene. Allerdings erfolgt die Zugriffsberechtigung zwischen Services generell nur über eine Art von Autorisierung, entweder Layer 4 oder Layer 7 Intentions.Auf das CLI greift man über die Subkommandos von consul connect zu. Mit dem ca-Subkommando zeigt man sich eine aktuelle Konfiguration einer CA (Certificate Authority/Zertifizierungsstelle) an oder ändert diese ab. Das proxy-Subkommando konfiguriert den Proxy und dessen Einstellungen für TLS-Verbindungen. So kann man Zertifikatsdateien oder Pfade auf Zertifikatsdateien, ACL-Token oder -Dateien festlegen oder IP-Adressen und Ports für den Proxy vorgeben.Für Envoy gibt es ein eigenes Subkommando envoy – darüber spezifiziert man dessen Bootstrapping, den grpc-Port oder die Vorgaben für Zertifikate, TLS oder ACL. Um externe Dienste mit internen Services zu verbinden, setzt Consul Connect Ingress Gateways ein. Dazu steht das expose-Subkommando zur Verfügung, das analoge Einstellungen wie proxy oder envoy besitzt. Mit dem redirect-traffic-Subkommando stellt man sicher, dass Consul Service Mesh stets transparent über Envoy erfolgt.

Sicherheit basiert auf Zugriffskontrolle und Verschlüsselung

Sicherheit in Consul basiert auf ACLs, verschiedenen Security-Modellen und Verschlüsselung. Bei ACLs (Access Control Lists) handelt es sich um ein optionales Feature von Consul, mit dem man Zugriffe auf Daten und APIs im Detail kontrollieren kann. ACLs gehören zu den zentralen Methoden der Authentifizierung in Consul. Sie kommen für Benutzer, Services und zwischen Consul-Agenten zum Einsatz.Definition und Verwaltung von ACLs erfolgt mit dem acl-Befehl des Consul-CLIs – zusätzlich steht ein HTTP-API für ACLs zur Verfügung. ACLs in Consul stellen ein mächtiges Konstrukt dar. So kann man eine ACL mit einer Authentifizierungsmethode, Binding-Rule, dem Bootstrapping, einer Policy, einer Rolle oder Tokens für Consul-Agenten verknüpfen. Eine Authentifizierungsmethode legt eine ACL für einen bestimmten Typ von Service und dessen konkrete Durchführung über einen Host, Account und Zertifikat fest. Die Binding-Rule zielt auf die Verknüpfung der ACL mit einem speziellen Interface ab. Um ACL einzusetzen, muss man ACL aktivieren und ein Bootstrap-Token erzeugen. Über die bootstrap-Option des acl-Befehls erhält man eine AccessorID und SecretID, die als Admin-Token vollständige Berechtigungen besitzt. Eine Policy spezifiziert, welche Operationen (Anlegen, Löschen, Lesen, etc.) man mit einer Ressource durchführen darf. Besitzt man eine bestimmte Rolle, so beschreibt diese ob man ACLs anlegen, löschen, anzeigen, lesen oder verändern kann. ACL Tokens dienen dazu bestimmte Informationen über ACLs aufzuzeichnen.Consul implementiert zwei Security-Modelle: Core und NIA (Network Infrastructure Automation). Beim Core-Modell handelt es sich um das gängige über Consul bereitgestellte Sicherheitsmodell, das Verschlüsselung, Autorisierung und Authentifizierung bietet. Das NIA-Modell unterstützt eine dynamische Aktualisierung der Netzwerk-Infrastruktur mithilfe von Consul Terraform Sync (CTS). CTS steht nicht nur für die Enterprise- sondern bereits auch für die Open-Source-Edition von Consul zur Verfügung.CTS benutzt den Katalog von Consul zusammen mit dem Terraform Provider Ecosystem (siehe Teil 4), um relevante Änderungen der Netzwerk-Infrastruktur festzustellen. Grundsätzlich verschlüsselt jeder Consul-Agent seinen Netzwerk-Verkehr; dabei kommt Gossip- und TSL-Verschlüsselung zum Einsatz. Einen passenden Krypto-Schlüssel erhält man über das consul keygen-Kommando; den man für das encrypt-Attribut verwendet.

Zertifikate mit Consul erzeugen und verwalten

Das mit dem CLI-Befehl consul tls ca create erzeugte Zertifikat nutzt Consul als eine eigene Certificate Authority/Zertifizierungsstelle. Consul generiert wie bei Zertifizierungsstellen üblich zwei Dateien: das eigentliche Zertifikat und einen Key (Bild 9), die beide auf dem PEM (Base64 ASCII)-Kodierungsschema von X.509 basieren. Bei X.509 handelt es sich um den Standard der ITU-T (International Telegraph Union Telecommunication Standardization Sector) für eine Public-Key-Infrastruktur (PKI) zum Erstellen digitaler Zertifikate.
Jeder Consul-Agentbenötigt für die TLS-Kommunikation in einem Trusted-Consul-Cluster einen öffentlichen und privaten Schlüssel(Bild 9) © Simon
Die Zertifikatsdatei consul-agent-ca.pem enthält den öffentlichen Schlüssel mit dem Consul das Zertifikat überprüft. Diese consul-agent-ca.pem-Datei benötigt jeder Knoten auf dem ein Consul-Agent läuft. Die andere pem-Datei consul-agent-ca-key.pem mit dem privaten Schlüssel bleibt unter Verschluss. Anhand dieser privaten Schlüsseldatei kann man einen Trusted Server von Consul einrichten und neue gültige Zertifikate generieren, um darüber Zugriff auf die von Consul verwalteten Daten (inklusive der ACLs) zu erhalten.
Für die Zugriffe in einem Trusted-Consul-Clustersetzt jeder Server einen öffentlichen und einen privaten Schlüssel ein(Bild 10) © Simon
Nachdem dem Einrichten eines Zertifikats mit Consul als Zertifizierungsstelle (CA), benötigt man zusätzlich für jeden Consul-Server und jeden Consul-Client ein individuelles Zertifikat. Dieses erzeugt man am besten direkt auf dem jeweiligen Server beziehungsweise Client. Für einen Server setzt man das CLI-Kommando consul tls cert create -server ein; eventuell erweitert um den Namen des Datacenters (Option -dc <dataCenterName>) beziehungsweise im Falle eines Federated Datacenters mit den Namen aller beteiligten
Datacenter.
Analog den Servernverwenden die Clients für die Zugriffe im Trusted-Consul-Cluster einen öffentlichen und privaten Schlüssel(Bild 11) © Simon
Die dabei erzeugten Zertifikate (CA) dci-server-consul-i.pem und die privaten Schlüsseldateien dci-server-consul-i-key.pem bleiben vor Ort auf dem jeweiligen Datacenter dci gespeichert (Bild 10). Entsprechend generiert man auf den Consul-Clients mithilfe consul tls cert create -client die CA-Dateien und privaten Schlüssel – diese verteilt man auf die jeweiligen Clients (Bild 11). Zum Schluss passt man die Konfiguration der Clients ca_file="consul-agent-ca.pem" und zusätzlich das ca_file-Attribut bei den Servern cert_file="dci-server-consul-i.pem" und key_file="dci-server-consul-i-key.pem" an.

Zertifikate den Clients für Berechtigungen zugänglich machen

Um die Inhalte der CA-Dateien zu lesen, setzen wir das openssl-Programm von OpenSSL ein. Der Befehl openssl x509 -text -noout -in consul-agent-ca.pem zeigt zum Beispiel den Aussteller die HashiCorp Inc. und das Subject eines Zertifikats an. Ähnliche Informationen erhält man über openssl x509 -text -noout -in dci-server-consul-i.pem für die Server- beziehungsweise openssl x509 -text -noout -in dci-client-consul-i.pem für die Client-Knoten. Aus den angezeigten Informationen lässt sich ableiten, dass die Zertifikate sich für eine Authentifizierung von Webclients beim Webserver eignen.Der ebenfalls vorhandene Subject Alternative Name verdeutlicht, dass auch lokale Verbindungen zu den Server-Knoten erlaubt sind. Dazu muss man die öffentlichen Schlüssel zusätzlich in die jeweiligen Host-Systeme integrieren. Auf den jeweiligen Webclient-Systemen benötigt man ein pfx-CA-Bundle, das neben dem SSL-Zertifikat, den privaten Schlüssel und eventuell weitere zusätzliche Zertifikatsdateien enthält. Die pfx-Datei erzeugt der openssl-Befehl nachdem man ein Kennwort für diese Datei eingegeben hat:

openssl pkcs12 -export \
    -inkey ./dci-client-consul-i-key.pem \
    -in ./dci-client-consul-i.pem \
    -certfile ./consul-agent-ca.pem \
    -out consul.pfx
 
 
Alternativ zu openssl steht für Windows auch die DigiCert Certificate Utility for Windows zur Verfügung. Das pfx-CA-Bundle verwendet man für die Zugriffe vom Client auf den Server. In der Regel erfolgen die Zugriffe über einen Webbrowser, so dass man die .PFX-Datei in diesen importiert. Erfolgen die Zugriffe nicht über eine Web-App, sondern über eine Mobile-App oder eine herkömmliche Anwendung, so stehen verschiedene Lösungsmöglichkeiten für die Realisierung einer Berechtigungsverwaltung zur Verfügung. Gängige Lösungen greifen auf ein Repository mit Zertifikaten wie KeyStore (Apple-Welt), Java KeyStore (JKS), Android Keystore oder durch direkten Einsatz des Zertifikationsspeichers einer Zertifizierungsinstanz zurück.

Links zum Thema

<b>◼ <a href="https://www.consul.io/" rel="noopener" target="_blank">Homepage von Consul</a> <br/></b>

Neueste Beiträge

DWX hakt nach: Wie stellt man Daten besonders lesbar dar?
Dass das Design von Websites maßgeblich für die Lesbarkeit der Inhalte verantwortlich ist, ist klar. Das gleiche gilt aber auch für die Aufbereitung von Daten für Berichte. Worauf besonders zu achten ist, erklären Dr. Ina Humpert und Dr. Julia Norget.
3 Minuten
27. Jun 2025
DWX hakt nach: Wie gestaltet man intuitive User Experiences?
DWX hakt nach: Wie gestaltet man intuitive User Experiences? Intuitive Bedienbarkeit klingt gut – doch wie gelingt sie in der Praxis? UX-Expertin Vicky Pirker verrät auf der Developer Week, worauf es wirklich ankommt. Hier gibt sie vorab einen Einblick in ihre Session.
4 Minuten
27. Jun 2025
„Sieh die KI als Juniorentwickler“
CTO Christian Weyer fühlt sich jung wie schon lange nicht mehr. Woran das liegt und warum er keine Angst um seinen Job hat, erzählt er im dotnetpro-Interview.
15 Minuten
27. Jun 2025
Miscellaneous

Das könnte Dich auch interessieren

MAUI-Tools - Steuerelemente der Community
Nützliche Hilfen für besondere Aufgaben.
12 Minuten
14. Okt 2024
WPF/VB: Fenster auf dem richtigen Monitor starten - Tipp der Woche
Das Notebook steht links, der große Monitor rechts daneben. Die Anwendung soll auf dem großen Monitor starten – außer wenn der Anwender unterwegs arbeitet und kein zweiter Monitor angeschlossen ist.
2 Minuten
24. Mär 2022
Von .NET Core 3.0 zu .NET 5 - Microsoft Build
Aus .NET, .NET Core und Mono soll mit .NET 5 wieder eine gemeinsame Plattform für alle Anwendungen entstehen.
2 Minuten
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige