Kapitel 4. Hinzufügen von Diensten zum Mesh
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
Im vorherigen Kapitel hast du gelernt, wie du Consul auf Kubernetes oder VMs einsetzen kannst. Der nächste Schritt bei der Nutzung von Consul ist das Hinzufügen deiner Dienste in das Netz. Dann kannst du Consul nutzen, um die Sicherheit, Beobachtbarkeit und Zuverlässigkeit zu erhöhen.
Ein Dienst wird dem Mesh "hinzugefügt", indem er bei Consul registriert wird, sein Sidecar-Proxy bereitgestellt wird und sichergestellt wird, dass die gesamte Kommunikation über diesen Proxy geleitet wird. In Kubernetes geschieht dies über eine einfache pod-Annotation. Auf VMs hast du etwas mehr zu tun: Du musst deinen Dienst bei Consul registrieren, seinen Sidecar-Proxy bereitstellen und das Routing konfigurieren.
In diesem Kapitel und den folgenden Kapiteln wird eine Beispielanwendung verwendet, die ich für das Buch erstellt habe, um die Funktionen von Consul zu veranschaulichen. Wenn du die Übungen mit der Beispielanwendung gemacht hast, bist du gut gerüstet, um deine eigenen Dienste in das Netz einzufügen.
Birdwatcher Beispielservice
Um das Service Mesh auszuprobieren, musst du zunächst einige Dienste unter einrichten. Du wirst eine einfache Anwendung namens Birdwatcher einsetzen. Birdwatcher besteht aus zwei Microservices: frontend
und backend
.
Der Dienst frontend
bietet eine Benutzeroberfläche wie in Abbildung 4-1 dargestellt. Jedes Mal, wenn du auf "Mischen" klickst, wird ein neuer Vogel angezeigt.
Der frontend
Dienst nutzt die API des backend
Dienstes, um neue Vögel abzurufen. Jedes Mal, wenn frontend
den Endpunkt /bird
von backend
aufruft, erhält es eine JSON-Antwort mit Vogeldaten:
{
"metadata"
:
{
"hostname"
:
"..."
,
"version"
:
"v1"
},
"response"
:
{
"name"
:
"Crimson fruitcrow"
,
"imageURL"
:
"..."
,
"extract"
:
"The crimson fruitcrow..."
}
}
Die Anwendung funktioniert folgendermaßen (siehe Abbildung 4-2):
-
Wenn du den Dienst
frontend
unter dem Pfad/
in deinem Browser aufrufst, wird die Benutzeroberfläche geladen. Wenn du dann auf die Schaltfläche Shuffle klickst, stellt die Benutzeroberfläche eine Anfrage an den Dienstfrontend
unter/shuffle
. -
Der Dienst
frontend
stellt dann eine eigene Anfrage anbackend
, um Daten über einen neuen Vogel bei/bird
abzurufen. -
Der Dienst
backend
antwortet mit einem JSON-Dokument, das einen Vogel beschreibt. -
Der Dienst
frontend
leitet die Antwort an die Benutzeroberfläche weiter, und die Benutzeroberfläche zeigt den neuen Vogel an.
Hinweis
frontend
und backend
sind in Go geschrieben, aber für Consul spielt es keine Rolle, in welcher Sprache deine Dienste geschrieben sind. Solange sie ein Netzwerkprotokoll wie TCP, HTTP oder gRPC verwenden, können sie im Dienstnetz genutzt werden.
Diese Beispielanwendung soll eine einfache Microservices-Architektur mit einem UI-Service und einem API-Service veranschaulichen. Nachdem du nun die Architektur der Birdwatcher-Anwendung verstanden hast, ist es an der Zeit, sie zu implementieren. Du wirst Birdwatcher zunächst ohne das Service-Mesh und bereitstellen und dann lernen, wie du es dem Mesh hinzufügst.
Ich behandle zuerst Kubernetes und gehe dann zu VMs über ("Dienste auf VMs bereitstellen").
Bereitstellung von Diensten in Kubernetes
Um die Dienste frontend
und backend
in Kubernetes zu implementieren, musst du Deployment- und Service-Ressourcen erstellen. Wie in Kapitel 2 beschrieben, ist ein Deployment ein Kubernetes-Ressourcentyp, mit dem du mehrere Replikate eines Dienstes bereitstellen und seinen Lebenszyklus verwalten kannst. Dienste werden in Kubernetes verwendet, um das Routing zu konfigurieren. Indem du eine Service-Ressource anlegst, erstellst du einen DNS-Eintrag, der zu deinem Deployment leitet. Wenn du z. B. eine Service-Ressource für den Dienst backend
erstellst, kann der Dienst frontend
nun backend
über die URL http://backend aufrufen.1
Um Ressourcen in Kubernetes zu erstellen, musst du YAML-Dateien verwenden. Erstelle in demselben Verzeichnis, in dem du die Datei values.yaml für deine Installation erstellt hast, ein neues Verzeichnis namens manifests und cd
:
$ mkdir manifests $ cd manifests
Im Verzeichnis manifests erstellst du vier YAML-Dateien: frontend-deployment.yaml(Beispiel 4-1), frontend-service.yaml(Beispiel 4-2), backend-deployment.yaml(Beispiel 4-3) und backend-service.yaml(Beispiel 4-4).
Beispiel 4-1. frontend-deployment.yaml
apiVersion
:
apps/v1
kind
:
Deployment
metadata
:
name
:
frontend
labels
:
app
:
frontend
spec
:
replicas
:
1
selector
:
matchLabels
:
app
:
frontend
template
:
metadata
:
labels
:
app
:
frontend
annotations
:
spec
:
containers
:
-
name
:
frontend
image
:
ghcr.io/consul-up/birdwatcher-frontend:1.0.0
env
:
-
name
:
BIND_ADDR
value
:
"0.0.0.0:6060"
-
name
:
BACKEND_URL
value
:
"http://backend"
ports
:
-
containerPort
:
6060
Beispiel 4-2. frontend-service.yaml
apiVersion
:
v1
kind
:
Service
metadata
:
name
:
frontend
labels
:
app
:
frontend
spec
:
type
:
LoadBalancer
selector
:
app
:
frontend
ports
:
-
protocol
:
TCP
port
:
6060
targetPort
:
6060
Warnung
Wenn du minikube nicht unter macOS verwendest, ändere den Typ von LoadBalancer
auf ClusterIP
, damit du keinen öffentlichen Load Balancer erstellst.
Beispiel 4-3. backend-deployment.yaml
apiVersion
:
apps/v1
kind
:
Deployment
metadata
:
name
:
backend
labels
:
app
:
backend
spec
:
replicas
:
1
selector
:
matchLabels
:
app
:
backend
template
:
metadata
:
labels
:
app
:
backend
annotations
:
spec
:
containers
:
-
name
:
backend
image
:
ghcr.io/consul-up/birdwatcher-backend:1.0.0
env
:
-
name
:
BIND_ADDR
value
:
"0.0.0.0:7000"
ports
:
-
containerPort
:
7000
Beispiel 4-4. backend-service.yaml
apiVersion
:
v1
kind
:
Service
metadata
:
name
:
backend
labels
:
app
:
backend
spec
:
selector
:
app
:
backend
ports
:
-
protocol
:
TCP
port
:
80
targetPort
:
7000
Verwende kubectl apply
, um diese Ressourcen auf Kubernetes anzuwenden:
$ kubectl apply -f ./ deployment.apps/backend created service/backend created deployment.apps/frontend created service/frontend created
Verwende den Befehl kubectl get
mit dem Flag --selector
, um den Einsatz und den Dienst des Dienstes frontend
anzuzeigen:
$ kubectl get deployment,service --selector app=frontend NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/frontend 1/1 1 1 1s NAME TYPE CLUSTER-IP EXTERNAL-IP ... service/frontend LoadBalancer 10.98.221.236 127.0.0.1 ...
deployment.apps/frontend
sollte 1/1
READY
und 1
AVAILABLE
anzeigen, was bedeutet, dass ein Pod läuft und der eine Container in diesem Pod bereit ist.
Verwende denselben Befehl mit einem anderen Selektor, um den Einsatz und den Dienst des backend
Dienstes anzuzeigen:
$ kubectl get deployment,service --selector app=backend NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/backend 1/1 1 1 1s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/backend ClusterIP 10.96.38.122 <none> 80/TCP 1s
Jetzt, wo deine Dienste eingerichtet sind, , solltest du in der Lage sein, auf die Birdwatcher-Benutzeroberfläche zuzugreifen. Vergewissere dich zunächst, dass du minikube tunnel
verwendest, damit die Ports richtig weitergeleitet werden,2 und wechsle dann mit deinem Browser zu http://localhost:6060. Du solltest die Birdwatcher-Benutzeroberfläche sehen, wie sie in Abbildung 4-1 dargestellt ist.
Du hast die Dienste frontend
und backend
erfolgreich in Kubernetes implementiert und überprüft, ob sie wie erwartet miteinander kommunizieren. Die aktuelle Architektur ist in Abbildung 4-3 dargestellt. Du rufst http://localhost:6060 auf , das von minikube tunnel
über seine Service-Ressource an den Pod frontend
weitergeleitet wird. Der Pod frontend
ruft dann backend
über seinen DNS-Hostnamen http://backend auf, der über seine Service-Ressource an den Pod backend
weitergeleitet wird.
Du hast jetzt einen typischen Satz von Kubernetes-Diensten laufen, aber diese Dienste sind noch nicht Teil des Mesh. Sie sind nicht bei Consul registriert und kommunizieren nicht über Sidecar-Proxys. Der nächste Schritt besteht darin, die Dienste zum Mesh hinzuzufügen.
Hinzufügen von Kubernetes-Diensten zum Mesh
Um einen Kubernetes-Dienst zum Mesh hinzuzufügen, musst du nur die Annotation consul.hashicorp.com/connect-inject: "true"
zu den Pods hinzufügen. Diese Annotation weist Consul an, den Dienst zu registrieren und einen Sidecar-Proxy einzubinden (die Sidebar "Unter der Haube" erklärt, wie das funktioniert).
Du musst beide Bereitstellungen bearbeiten, um die Anmerkung hinzuzufügen. Zuerst bearbeitest du die frontend-deployment.yaml und fügst die Anmerkung unter spec.template.metadata
hinzu:
# frontend-deployment.yaml
apiVersion
:
apps/v1
kind
:
Deployment
# ...
spec
:
# ...
template
:
metadata
:
labels
:
app
:
frontend
annotations
:
consul.hashicorp.com/connect-inject
:
"
true
"
spec
:
containers
:
# ...
Hinweis
Du musst die Anmerkung zum Schlüssel spec.template.metadata
hinzufügen und nicht zum Schlüssel der obersten Ebene metadata
. Der Top-Level-Schlüssel metadata
legt die Metadaten für den Einsatz fest und der Schlüssel spec.template.metadata
die Metadaten für die Pods, aus denen der Einsatz besteht. Consul betrachtet nur Pods (siehe "Unter der Haube") und keine Einsätze.
Nachdem du deine YAML geändert hast, kannst du den Dienst frontend
neu bereitstellen. Verwende dazu kubectl apply
im Verzeichnis manifests:
$ kubectl apply -f frontend-deployment.yaml deployment.apps/frontend configured
Kubernetes kümmert sich um den Start eines neuen Pods und um das Herunterfahren des alten Pods. Du kannst den Befehl kubectl rollout
verwenden, um zu warten, bis die Umverteilung abgeschlossen ist. Das kann ein oder zwei Minuten dauern, weil Kubernetes zusätzliche Docker-Images herunterladen muss:
$ kubectl rollout status --watch deploy/frontend Waiting for deployment "frontend" rollout to finish... deployment "frontend" successfully rolled out
Nachdem der Pod neu verteilt wurde, solltest du, wenn du die Consul UI unter http://localhost:8500 öffnest, den Dienst frontend
in der Liste sehen, wie in Abbildung 4-4 dargestellt (stelle sicher, dass minikube tunnel
oder kubectl port-forward
läuft). Das bedeutet, dass der Dienst frontend
jetzt Teil des Dienstnetzes ist!
Füge nun den Dienst backend
zum Netz hinzu, indem du dieselbe Annotation (und eine zusätzliche Annotation, um einige Metadaten zu setzen) zur backend-deployment.yaml hinzufügst:
# backend-deployment.yaml
apiVersion
:
apps/v1
kind
:
Deployment
# ...
spec
:
# ...
template
:
metadata
:
labels
:
app
:
backend
annotations
:
consul.hashicorp.com/connect-inject
:
"
true
"
consul.hashicorp.com/service-meta-version
:
"
v1
"
spec
:
containers
:
# ...
Diese Annotation legt einen Consul-Metadatenschlüssel fest. Sie wird vorerst nicht verwendet , aber in Kapitel 9, wenn du dich mit Bereitstellungsstrategien beschäftigst, wirst du eine
v2
Version desbackend
Dienstes bereitstellen.
Setze sie mit kubectl apply
wieder ein:
$ kubectl apply -f backend-deployment.yaml deployment.apps/backend configured
Warte, bis der Rollout abgeschlossen ist:
$ kubectl rollout status --watch deploy/backend Waiting for deployment "backend" rollout to finish: 1 old replicas are pending termination... deployment "backend" successfully rolled out
Wenn du jetzt die Benutzeroberfläche anschaust, solltest du sowohl die Dienste frontend
als auch backend
sehen, wie in Abbildung 4-5 dargestellt.
Jetzt, wo die Dienste frontend
und backend
Teil des Dienstnetzes sind, kannst du, wenn du minikube tunnel
verwendest, versuchen, die Birdwatcher-Benutzeroberfläche erneut unter http://localhost:6060 zu laden . Du solltest eine Fehlermeldung ähnlich wie in Abbildung 4-6 sehen.
Du bekommst diese Fehlermeldung, weil der Dienst frontend
jetzt Teil des Netzes ist und sein Sidecar-Proxy den gesamten eingehenden Datenverkehr abfängt. Consul ist standardmäßig sicher und verlangt, dass der gesamte Datenverkehr durch das Servicenetz authentifiziert und autorisiert wird. Wenn du über deinen Browser eine Anfrage an den Dienst frontend
stellst, ist deine Anfrage weder authentifiziert noch autorisiert und wird daher von Consul abgelehnt. Dies ist in Abbildung 4-7 dargestellt.
Wenn du kubectl port-forward
verwendest, wirst du keine Fehlermeldung sehen. Das liegt daran, dass kubectl port-forward
den Sidecar-Proxy tatsächlich umgeht. Du kannst den gleichen Fehler aber auch reproduzieren, indem du kubectl exec
für einen normalen Aufruf des frontend
Dienstes verwendest:
$ kubectl exec consul-server-0 -n consul -- \ curl -sS http://frontend.default:6060 curl: (52) Empty reply from server command terminated with exit code 52
Tipp
Unter Windows, wenn du die PowerShell verwendest, ersetze \
durch `
.
Im nächsten Kapitel wirst du ein Ingress-Gateway einrichten, über das du den Dienst frontend
mit der entsprechenden Berechtigung aufrufen kannst. Im Moment willst du aber noch überprüfen, ob der Datenverkehr zwischen den Diensten frontend
und backend
wie erwartet funktioniert. Dazu kannst du den Proxy von frontend
umgehen, indem du kubectl exec
verwendest, um einen Befehl im Container frontend
auszuführen und backend
direkt aufzurufen:
$ kubectl exec deploy/frontend -c frontend -- \ curl -si http://backend/bird HTTP/1.1 200 OK ...
Wenn alles wie erwartet funktioniert, solltest du eine HTTP 200 OK Antwort vom backend
Dienst erhalten. Diese Anfrage durchläuft jetzt das Dienstnetz, wie in Abbildung 4-8 dargestellt.
Um zu beweisen, dass die Anfragen durch das Servicenetz gehen, kannst du die Topologieansicht der Consul UI verwenden, die die von den Sidecar-Proxys ausgegebenen Metriken anzeigt.
Führe den vorherigen Befehl kubectl exec
noch ein paar Mal aus, um weitere Metriken zu erzeugen, und navigiere dann zur Topologieseite für den Dienst backend
, indem du in der Ansicht Alle Dienste auf den Dienst backend
klickst oder zu http://localhost:8500/ui/dc1/services/backend/topology navigierst . Du solltest etwas Ähnliches wie in Abbildung 4-9 sehen (es kann eine Minute dauern, bis die Metriken angezeigt werden).
Hinweis
Die Warnungen, die du in der Topologieansicht siehst, sind darauf zurückzuführen, dass ACLs nicht aktiviert sind und du keine Absichten erstellt hast. ACLs werden in Kapitel 10 behandelt und du wirst in Kapitel 6 Absichten erstellen. Du wirst auch feststellen, dass die Topologie zeigt, dass backend
frontend
aufruft, was nicht korrekt ist. Das liegt daran, dass Consul alle erlaubten Verbindungen zwischen Diensten anzeigt. Wenn du später Absichten erstellst, um nur bestimmte Verbindungen zuzulassen, wird sich die Topologieansicht ändern.
Wenn du unter in der Topologieansicht Metriken siehst, hast du deine Dienste erfolgreich zum Mesh hinzugefügt! Die Metriken beweisen, dass die Sidecar-Proxys den Datenverkehr erfassen.
Hinweis
Wenn du auf den Dienst frontend
klickst, siehst du keine Metriken. Das liegt daran, dass das Diagramm nur eingehende Anfragen anzeigt und du zurzeit keine Anfragen an den Dienst frontend
stellst. Im nächsten Kapitel wirst du ein Ingress-Gateway einrichten, das es dir ermöglicht, Anfragen an den Dienst frontend
zu stellen, und dann wirst du auch dessen Metriken sehen.
Im nächsten Abschnitt erfährst du, wie du Dienste, die auf VMs laufen, in das Netz einbindest. Wenn du dich nur für Kubernetes interessierst, überspringe bis zur Zusammenfassung des Kapitels.
Dienste auf VMs bereitstellen
In diesem Abschnitt erfährst du, wie du die Birdwatcher-Anwendung auf VMs ohne Mesh bereitstellst und ausführst. Sobald Birdwatcher läuft, erfährst du, wie du ihn zum Mesh hinzufügen kannst. Der Prozess zum Hinzufügen von Birdwatcher zum Mesh ähnelt dem, den du für deine eigenen Dienste befolgst.
Du wirst der Einfachheit halber sowohl frontend
als auch backend
auf der gleichen VM ausführen. Der erste Schritt besteht darin, die Binärdateien frontend
und backend
in die VM zu laden. Wenn du die vorgefertigte VM über Vagrant verwendest, sind die Binärdateien bereits vorhanden. Wenn du deine eigene VM verwendest, findest du die Binärdateien im GitHub-Repository des Buches.
Nachdem du die Binärdateien installiert hast, musst du sie mit systemd
starten, genauso wie du es mit Consul getan hast. Zuerst erstellst du zwei systemd
Unit-Dateien, frontend.service und backend.service, in /etc/systemd/system/ (stelle sicher, dass du zuerst vagrant ssh
ausgeführt hast).
$ sudo touch /etc/systemd/system/frontend.service $ sudo touch /etc/systemd/system/backend.service
Bearbeite /etc/systemd/system/frontend.service und füge den Inhalt aus Beispiel 4-5 hinzu.
Tipp
Du musst sudo
verwenden, um Dateien in /etc/systemd/systemzu bearbeiten - zumBeispiel sudo vim /etc/systemd/system/frontend.service
.
Beispiel 4-5. /etc/systemd/system/frontend.service
[Unit]
Description
=
"Frontend service"
# The service requires the VM's network
# to be configured, e.g., an IP address has been assigned.
Requires
=
network-online.target
After
=
network-online.target
[Service]
# ExecStart is the command to run.
ExecStart
=
/usr/local/bin/frontend
# Restart configures the restart policy. In this case, we
# want to restart the service if it fails.
Restart
=
on-failure
# Environment sets environment variables.
# We will set the frontend service to listen
# on port 6060.
Environment
=
BIND_ADDR=0.0.0.0:6060
# We set BACKEND_URL to http://localhost:7000 because
# that's the port we'll run our backend service on.
Environment
=
BACKEND_URL=http://localhost:7000
# The Install section configures this service to start
# automatically if the VM reboots.
[Install]
WantedBy
=
multi-user.target
Als nächstes bearbeitest du /etc/systemd/system/backend.service so, dass sie mit Beispiel 4-6 übereinstimmt.
Beispiel 4-6. /etc/systemd/system/backend.service
[Unit]
Description
=
"Backend service"
Requires
=
network-online.target
After
=
network-online.target
[Service]
ExecStart
=
/usr/local/bin/backend
Restart
=
on-failure
# We will set the backend service to listen
# on port 7000.
Environment
=
BIND_ADDR=0.0.0.0:7000
[Install]
WantedBy
=
multi-user.target
Wenn die Unit-Dateien vorhanden sind, kannst du deine5 und deine Dienste zu starten:
$ sudo systemctl enable frontend backend Created symlink ... Created symlink ...
Starte jetzt die Dienste:
$ sudo systemctl start frontend backend
Hinweis
Für diese Übung führst du all diese Schritte manuell aus, aber für eine produktive Bereitstellung solltest du ein Provisioning-Tool wie Ansible oder Terraform und Packer verwenden.
Du kannst ihren Status mit systemctl status
überprüfen:
$ sudo systemctl status frontend backend frontend.service - "Frontend service" Loaded: loaded... Active: active (running)... ... backend.service - "Backend service" Loaded: loaded... Active: active (running)...
Jetzt, wo frontend
und backend
laufen, solltest du in der Lage sein, die Birdwatcher-Anwendung aufzurufen, indem du mit deinem Browser zu http://localhost:6060 navigierst . Du solltest die Benutzeroberfläche sehen, wie sie in Abbildung 4-1 dargestellt ist.
Die aktuelle Architektur ist in Abbildung 4-10 dargestellt.
Deine Dienste laufen jetzt, aber sie sind noch nicht im Mesh registriert und ihr Datenverkehr fließt nicht durch die Sidecar-Proxys. In den nächsten Abschnitten wirst du die Dienste bei Consul registrieren und die Sidecar-Proxys starten. Dies sind die gleichen Schritte, die du auch für deine eigenen Dienste durchführen musst.
Registrierung von VM-Diensten bei Consul
Du musst Dienste bei Consul registrieren, damit weiß, welche Dienste auf welchen IPs und Ports laufen. Dienste können über Konfigurationsdateien oder über die API von Consul registriert werden. Bei dynamischen Systemen wie Container-Orchestratoren ist es sinnvoll, die API zu verwenden, aber bei VMs ist es oft einfacher, Konfigurationsdateien zu verwenden, weil du normalerweise schon bei der Bereitstellung weißt, welche Dienste auf einer bestimmten VM laufen werden.
Erstelle die Dienstkonfigurationsdateien im Konfigurationsverzeichnis von Consul /etc/consul.d:6
$ sudo touch /etc/consul.d/frontend.hcl $ sudo touch /etc/consul.d/backend.hcl
Füge den Inhalt aus Beispiel 4-7 zu /etc/consul.d/frontend.hcl hinzu.
Beispiel 4-7. /etc/consul.d/frontend.hcl
service
{
name
=
"frontend"
# frontend runs on port 6060.
port
=
6060
# The "connect" stanza configures service mesh
# features.
connect
{
sidecar_service
{
# frontend's proxy will listen on port 21000.
port
=
21000
proxy
{
# The "upstreams" stanza configures
# which ports the sidecar proxy will expose
# and what services they'll route to.
upstreams
=
[
{
# Here you're configuring the sidecar proxy to
# proxy port 6001 to the backend service.
destination_name
=
"backend"
local_bind_port
=
6001
}
]
}
}
}
}
Hinweis
Normalerweise legst du den Port des Proxys nicht fest und lässt ihn stattdessen dynamisch von Consul zuweisen. In dieser Übung legst du den Port des frontend
Proxys auf 21000 fest, damit im gesamten Buch klar ist, welche Proxys an welchen Ports liegen.
Für /etc/consul.d/backend.hcl verwendest du den in Beispiel 4-8 gezeigten Code.
Beispiel 4-8. /etc/consul.d/backend.hcl
service
{
name
=
"backend"
# backend runs on port 7000.
port
=
7000
meta
{
version
=
"v1"
}
# The backend service doesn't call
# any other services so it doesn't
# need an "upstreams" stanza.
#
# The connect stanza is still required to
# indicate that it needs a sidecar proxy.
connect
{
sidecar_service
{
# backend's proxy will listen on port 22000.
port
=
22000
}
}
}
Deine eigenen Dienste benötigen ähnliche Konfigurationsdateien. Du musst den Namen des Dienstes, den Port, auf dem er lauscht, und alle Upstream-Abhängigkeiten festlegen (siehe "Upstreams").
Du musst Consul anweisen, seine Konfiguration neu zu laden, damit es die neuen Dateien übernimmt. Verwende dazu den Befehl consul reload
:
$ consul reload Configuration reload triggered
Du kannst den Befehl consul catalog services
verwenden, um zu überprüfen, ob deine Dienste erfolgreich registriert wurden:
$ consul catalog services backend backend-sidecar-proxy consul frontend frontend-sidecar-proxy
Du solltest frontend
und backend
zusammen mit ihren Sidecar-Proxys aufgelistet sehen.
Hinweis
Warum sind frontend-sidecar-proxy
und backend-sidecar-proxy
aufgeführt? Unter der Haube behandelt Consul die Sidecar-Proxys als separate Dienste. Du wirst die Proxys nicht in der Benutzeroberfläche sehen, weil sie versteckt sind, aber du wirst sie in der API oder CLI sehen.
In der Benutzeroberfläche unter http://localhost:8500 sollten frontend
und backend
aufgelistet sein(Abbildung 4-11), obwohl sie als ungesund angezeigt werden. Das liegt daran, dass ihre Sidecar-Proxys noch nicht laufen.
Jetzt, wo deine Dienste in Consul registriert sind, ist es an der Zeit ihre Sidecar-Proxys einzusetzen.
Einsatz von Sidecar Proxies auf VMs
Damit deine Dienste funktionsfähig sind, müssen die Proxys der Sidecars laufen. Auf den Sidecar-Proxys läuft Envoy, das bereits auf der Vagrant-VM installiert ist. Wenn du deine eigenen VMs verwendest, schau dir die Installationsanleitung von Envoy an.
Wie bei den Diensten frontend
und backend
konfigurierst du einen Dienst systemd
, um jeden Sidecar-Proxy auszuführen. Der Befehl, mit dem systemd
die Sidecar-Proxys ausführt, lautet:
consul connect envoy
Dieser Befehl akzeptiert ein Flag, -sidecar-for
, mit dem du den Envoy-Proxy für einen bestimmten Dienst konfigurieren kannst.
Hinweis
Consul unterstützt nicht den Betrieb eines einzelnen Envoy-Proxys für mehrere Dienste, da jeder Envoy-Proxy die Identität des Quelldienstes in jeder Anfrage verschlüsseln muss. Außerdem musst du für jeden Dienst unterschiedliche Regeln für den Proxy konfigurieren.
Erstelle zunächst die beiden Einheitsdateien:
$ sudo touch /etc/systemd/system/frontend-sidecar-proxy.service $ sudo touch /etc/systemd/system/backend-sidecar-proxy.service
/etc/systemd/system/frontend-sidecar-proxy.service sollte Beispiel 4-9 entsprechen.
Beispiel 4-9. /etc/systemd/system/frontend-sidecar-proxy.service
[Unit]
Description
=
"Frontend sidecar proxy service"
Requires
=
network-online.target
After
=
network-online.target
[Service]
ExecStart
=
/usr/bin/consul connect envoy -sidecar-for frontend \
-admin-bind 127.0.0.1:19000
Restart
=
on-failure
[Install]
WantedBy
=
multi-user.target
Und /etc/systemd/system/backend-sidecar-proxy.service sollte dem Beispiel 4-10 entsprechen.
Beispiel 4-10. /etc/systemd/system/backend-sidecar-proxy.service
[Unit]
Description
=
"Backend sidecar proxy service"
Requires
=
network-online.target
After
=
network-online.target
[Service]
ExecStart
=
/usr/bin/consul connect envoy -sidecar-for backend \
-admin-bind 127.0.0.1:19001
Restart
=
on-failure
[Install]
WantedBy
=
multi-user.target
Als nächstes aktivierst du die beiden Dienste:
$ sudo systemctl enable frontend-sidecar-proxy $ sudo systemctl enable backend-sidecar-proxy
Jetzt starte sie!
$ sudo systemctl start frontend-sidecar-proxy $ sudo systemctl start backend-sidecar-proxy
Überprüfe, ob ihr Status aktiv und in Betrieb ist:
$ sudo systemctl status frontend-sidecar-proxy frontend-sidecar-proxy.service - "Frontend sidecar proxy service" Loaded: loaded... Active: active (running)...
$ sudo systemctl status backend-sidecar-proxy backend-sidecar-proxy.service - "Backend sidecar proxy service" Loaded: loaded... Active: active (running)...
Wenn die Proxys jetzt laufen, sollte die Benutzeroberfläche alles als gesund anzeigen (sieheAbbildung 4-12).
Lade die Birdwatcher-Benutzeroberfläche unter http://localhost:6060 neu, um zu sehen, ob sich etwas geändert hat. Die Benutzeroberfläche sollte genauso aussehen und funktionieren wie vorher. Woher weißt du also, ob der Datenverkehr durch das Servicenetz geleitet wird?
Eine Möglichkeit zu prüfen, ob der Verkehr durch das Netz geleitet wird, besteht darin, eine Intention zu erstellen, die den gesamten Verkehr verweigert. Intentionen sind Autorisierungsregeln, die festlegen, welche Dienste kommunizieren dürfen. Intentionen werden in Kapitel 6 ausführlich behandelt, aber du kannst sie jetzt als schnellen Test verwenden, um zu sehen, ob der Verkehr durch das Netz geleitet wird.
Erstelle mit der Consul CLI eine Absicht, um den gesamten Verkehr zwischen den Diensten zu verweigern:
$ consul intention create -deny '*' '*' Created: * => * (deny)
Versuche nun, die Birdwatcher-Benutzeroberfläche erneut zu laden. Die Benutzeroberfläche sollte einen neuen Vogel laden, obwohl die Absicht ist, den Verkehr zu verweigern. Was ist also los?
Anders als in Kubernetes musst du beim Hinzufügen von Diensten zum Service-Mesh auf VMs einige Änderungen an den URLs vornehmen, die deine Dienste verwenden, damit sie den Datenverkehr über ihre Sidecar-Proxys leiten. Im Moment ruft frontend
immer noch backend
direkt auf und umgeht sowohl seinen lokalen Proxy als auch den Proxy von backend
, wie in Abbildung 4-13 dargestellt. Die Intentionen werden von den Proxys durchgesetzt, deshalb lädt die Birdwatcher-Benutzeroberfläche immer noch Vögel.
Routing auf VMs konfigurieren
Du musst frontend
so konfigurieren, dass es Anfragen über seinen Sidecar-Proxy an backend
weiterleitet. Erinnerst du dich daran, wie du die Upstreams von frontend
konfiguriert hast? Du hast den local_bind_port
für den backend
Dienst auf 6001 gesetzt. Jetzt musst du nur noch frontend
so konfigurieren, dass er diesen Port verwendet.
Glücklicherweise stellt der Dienst frontend
die Umgebungsvariable BACKEND_URL
zur Verfügung, mit der die URL für den Aufruf von backend
konfiguriert werden kann.
Tipp
In deinen eigenen Diensten wirst du wahrscheinlich die gleiche Möglichkeit haben, Upstream-URLs über eine Umgebungsvariable oder eine Konfigurationsdatei zu konfigurieren. Wenn nicht, musst du den Code deines Dienstes ändern.
Zurzeit ist diese Umgebungsvariable in deiner frontend.service-Datei auf http://localhost:7000
gesetzt. Du musst sie also nur auf http://localhost:6001
setzen.
Editiere /etc/systemd/system/frontend.service mit sudo
(frontend.service, nicht frontend-sidecar-proxy.service) und ändere die Umgebungsvariable BACKEND_URL
in http://localhost:6001
:
... Environment=BACKEND_URL=http://localhost:6001 ...
Führe nun systemctl daemon-reload
aus, damit systemd
die aktualisierte Konfiguration lädt und benutze dann systemctl restart
, um den Dienst frontend
neu zu starten:
$ sudo systemctl daemon-reload $ sudo systemctl restart frontend
Wenn du die Birdwatcher-Benutzeroberfläche unter http://localhost:6060 erneut lädst, solltest du jetzt einen Fehler sehen:
Unable to call backend: Get "http://localhost:6001/bird": EOF
Dieser Fehler bestätigt, dass frontend
versucht, backend
über seinen Sidecar-Proxy aufzurufen und der Aufruf fehlschlägt, weil der Sidecar-Proxy von backend
die Anfrage ablehnt.
Lösche die Absicht, den Verkehr zuzulassen:
$ consul intention delete '*' '*' Intention deleted.
Gehe zurück zur Benutzeroberfläche und klicke auf die Schaltfläche "Mischen". Die Vögel sollten jetzt wieder geladen werden!
Jetzt hast du bestätigt, dass die Anfragen zwischen frontend
und backend
durch das Service Mesh geleitet werden!7 Abbildung 4-14 zeigt, wie die Architektur jetzt aussieht.
Hinweis
Es gibt zwei Gruppen von Ports für einen Sidecar-Proxy: vorgelagerte und öffentliche Ports. Ein Dienst nutzt die Upstream-Ports seines Proxys, um seine Abhängigkeiten an weiterzuleiten. In diesem Beispiel ist 6001 ein vorgelagerter Port.
Öffentliche Ports sind die Ports, an denen der eingehende Verkehr von anderen Sidecar-Proxys empfangen wird. Wie in Abbildung 4-14 dargestellt, ist der öffentliche Port für den Sidecar-Proxy von backend
22000. Consul konfiguriert alle Proxys so, dass sie die öffentlichen Ports der anderen Proxys kennen. Auf diese Weise kann der Proxy von frontend
den Datenverkehr von an den Proxy von backend
senden.
Zusammenfassung
In diesem Kapitel hast du gelernt, wie du Dienste zum Consul Service Mesh hinzufügen kannst. In Kubernetes musst du dazu lediglich deine Pods mit der Annotation consul.hashicorp.com/inject: "true"
versehen. Unter der Haube sorgte Consul dafür, dass der Sidecar-Proxy automatisch injiziert und der Datenverkehr abgefangen wurde.
Auf VMs hast du die Dienste über Konfigurationsdateien bei Consul registriert und die Sidecar-Proxys mit systemd
ausgeführt. Anschließend hast du gelernt, wie du Dienste so konfigurierst, dass sie über ihre lokalen Sidecar-Proxys mit ihren Upstream-Abhängigkeiten kommunizieren.
Deine Dienste kommunizieren jetzt über das Mesh, aber du hast noch nicht gelernt, wie du sie für Anrufer zugänglich machen kannst, die nicht im Mesh sind. Deshalb kannst du die Benutzeroberfläche von frontend
nicht auf Kubernetes laden und auf VMs umgehst du das Mesh, um die Benutzeroberfläche zu laden.
Im nächsten Kapitel erfährst du, wie du Ingress Gateways verwendest, um benutzerorientierte Dienste bereitzustellen.
1 Wenn die Dienste in verschiedenen Namensräumen liegen, würdest du http://backend.<Namensraum> verwenden .
2 Wenn du Kubernetes in der Cloud oder unter Linux betreibst, verwende kubectl port-forward service/frontend 6060
.
3 Ein Init-Container ist ein Container, der vor den Hauptcontainern für einen Pod läuft.
4 Wenn du immer noch Dienste hast, die nicht im Mesh sein können, kannst du ein Abschluss-Gateway verwenden. Abschließende Gateways werden in Kapitel 10 behandelt.
5 systemctl enable
legt fest, dass die Dienste neu gestartet werden, wenn die VM neu startet.
6 Du kannst deine Dienstkonfiguration in einem beliebigen Verzeichnis ablegen, solange das Verzeichnis mit dem -config-dir
Flag an Consul übergeben wird.
7 Technisch gesehen werden nicht alle Anfragen durch das Dienstnetz geleitet. Dein Browser verbindet sich immer noch direkt mit dem Dienst frontend
und nicht mit dessen Proxy. Im nächsten Kapitel fügst du ein Ingress-Gateway hinzu, um dies zu beheben.
Get Consul: Auf und davon now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.