Entwickler, die an einer Kubernetes-basierten Anwendungsumgebung wie Red Hat OpenShift arbeiten, müssen eine Reihe von Dingen berücksichtigen, um die erheblichen Vorteile dieser Technologien voll auszuschöpfen, darunter:
- Wie kommuniziere ich mit der Orchestrierungsebene, um anzuzeigen, dass die Anwendung ordnungsgemäß funktioniert und für den Empfang von Datenverkehr verfügbar ist?
- Was passiert, wenn die Anwendung einen Systemfehler erkennt, und wie leitet die Anwendung diesen an die Orchestrierungsebene weiter?
- Wie kann ich den Verkehrsfluss zwischen meinen Anwendungen genau nachverfolgen, um potenzielle Engpässe zu identifizieren?
- Welche Tools kann ich verwenden, um meine aktualisierte Anwendung einfach als Teil meiner Standard-Toolchain bereitzustellen?
- Was passiert, wenn ich einen Netzwerkfehler zwischen meinen Diensten einführe, und wie teste ich dieses Szenario?
Diese Fragen sind von zentraler Bedeutung für die Entwicklung containernativer Lösungen. Bei Red Hat definieren wir containernativ als Anwendungen, die den folgenden Grundprinzipien entsprechen:
- DevOps-Automatisierung
- Single-Concern-Prinzip
- Diensterkennung
- Hohe Beobachtbarkeit
- Lebenszykluskonformität
- Laufzeitbeschränkung
- Verfügbarkeit verarbeiten
- Bildunveränderlichkeit
Dies mag neben der Kernanwendungslogik wie eine Menge Overhead erscheinen. Red Hat OpenShift Application Runtimes (RHOAR) und Istio stellen Entwicklern Tools zur Verfügung, mit denen sie diese Prinzipien mit minimalem Overhead in Bezug auf Codierung und Implementierung einhalten können.
In diesem Blogbeitrag konzentrieren wir uns speziell darauf, wie RHOAR und Istio kombiniert werden, um Tools für DevOps-Automatisierung, Lebenszykluskonformität, hohe Beobachtbarkeit und Laufzeitbeschränkung bereitzustellen.
Hinweis:Dieser Artikel basiert auf Version 0.7 von Istio, die zum Zeitpunkt der Erstellung dieses Artikels die neueste Version war. Wir empfehlen, diese Version von Istio nicht für Produktionsbereitstellungen zu verwenden, da sich einige Schlüsselfunktionen noch im Alpha-/Betastatus befinden. Obwohl sich Istio schnell weiterentwickelt, halten wir es für wichtig, dass Entwickler die Fähigkeiten erlernen und verstehen, um diese Technologie voll auszuschöpfen, sobald sie zu einem tragfähigen Produktionsangebot wird.
Voraussetzungen
- Red Hat Openshift Container Platform 3.9 (RHOCP) oder Minishift Istio-Build:https://github.com/openshift-istio/origin/releases
oc
Befehlszeilenzugriff auf RHOCP mit Cluster-Administratorrechten- Node.js-Version 8.6.0
Hinweis:Aufgrund der erforderlichen Administratorrechte während der Installationsphase ist Istio auf Red Hat OpenShift Online nicht verfügbar.
Ein RHOAR-Projekt einrichten
Wir beginnen mit dem RHOAR Health Check Booster Repo:
https://github.com/bucharest-gold/nodejs-health-check-redhat.
Klonen Sie dieses Repo mit dem folgenden Befehl :
$ git clone https://github.com/bucharest-gold/nodejs-health-check-redhat
Wechseln Sie zu nodejs-health-check-redhat
Ordner:
$ cd nodejs-health-check-redhat
Installieren Sie npm
Abhängigkeiten:
$ npm install
Erstellen Sie in OpenShift ein neues Projekt mit dem Namen rhoar-istio
:
$ oc new-project rhoar-istio
Stellen Sie die RHOAR-Booster-Anwendung bereit:
$ npm run openshift
Sobald die Bereitstellung abgeschlossen ist, sollten Sie eine Ausgabe wie diese sehen:
2018-06-01T14:06:35.037Z INFO build nodejs-health-check-redhat-s2i-1 complete 2018-06-01T14:06:37.923Z INFO creating deployment configuration nodejs-health-check-redhat 2018-06-01T14:06:37.927Z INFO creating new route nodejs-health-check-redhat 2018-06-01T14:06:37.963Z INFO creating new service nodejs-health-check-redhat 2018-06-01T14:06:38.063Z INFO route host mapping nodejs-health-check-redhat-rhoar.router.default.svc.cluster.local 2018-06-01T14:06:38.106Z INFO complete
In OpenShift sollte die Anwendung bereitgestellt werden und Pods sollten ausgeführt werden, wie unten gezeigt.
Das Wichtigste, was hier zu beachten ist, ist die URL der Routenhostzuordnung, die in diesem Fall http://nodejs-health-checker-rhoar-istio.router.default.svc.cluster.local
ist . Sobald Ihr DNS richtig konfiguriert ist, sollten Sie zu dieser URL navigieren und die folgende Seite sehen können:
Wir werden diese Benutzeroberfläche in Kürze verwenden, um den Neustart des Containers auszulösen.
Werfen wir einen Blick auf den Code, um zu sehen, was diese Booster-App demonstriert.
Blick auf app.js
, können wir Folgendes sehen, was bedeutet, dass die App eine Instanz des Express-Webframeworks erstellt:
const app = express();
Die folgende Zeile bedeutet, dass die App die Variable isOnline
setzt bis true
beim Start:
let isOnline = true;
Und die App definiert eine benutzerdefinierte Aktivitätsprüfung, die „OK“ zurückgibt, wenn isOnline
auf true gesetzt ist:
const options = { livenessCallback: (request, response) => { return isOnline ? response.send('OK') : response.sendStatus(500); } };
Die App definiert eine Route, /api/stop
, mit dem Benutzer den Wert von isOnline
festlegen können bis false
:
app.use('/api/stop', (request, response) => { isOnline = false; return response.send('Stopping HTTP server'); });
Die App verwendet den kube-probe
npm-Modul zur Bereitstellung von Bereitschafts- und Lebendigkeitsprüfungen:
const probe = require('kube-probe');
Das Sondenmodul wird mit dem App-Objekt (Instanz von Express) aufgerufen:
probe(app, options);
Wenn Sie sich die Pods in der OpenShift-Konsole ansehen, sollten Sie Folgendes sehen:
Dies zeigt, dass die Bereitschaftsprüfung OpenShift korrekt darüber informiert, dass der Container bereit ist.
Über die von der Route bereitgestellte Benutzeroberfläche, wenn Sie auf Stop Service klicken klicken, sollten Sie in OpenShift einen Hinweis darauf sehen, dass OpenShift festgestellt hat, dass die Aktivitätsprüfung fehlgeschlagen ist und versucht, den Container neu zu starten.
Das ist also eine ziemlich coole „out of the box“-Funktionalität, die von RHOAR bereitgestellt wird und drei der Schlüsselprinzipien des Container-nativen Designs berührt:DevOps-Automatisierung, Lebenszykluskonformität und hohe Beobachtbarkeit.
Warum Istio verwenden?
Folgendes stammt von der Istio-Website:
Istio bietet eine Komplettlösung, um die vielfältigen Anforderungen von Microservice-Anwendungen zu erfüllen, indem es Einblicke in das Verhalten und die operative Kontrolle über das Service Mesh als Ganzes bietet. Es stellt eine Reihe von Schlüsselfunktionen einheitlich über ein Netzwerk von Diensten bereit:
Verkehrsmanagement. Kontrollieren Sie den Verkehrsfluss und API-Aufrufe zwischen Diensten, machen Sie Anrufe zuverlässiger und machen Sie das Netzwerk robuster gegenüber widrigen Bedingungen.
Dienstidentität und -sicherheit. Stellen Sie Dienste im Mesh mit einer überprüfbaren Identität bereit und bieten Sie die Möglichkeit, den Dienstdatenverkehr zu schützen, während er über Netzwerke mit unterschiedlichem Grad an Vertrauenswürdigkeit fließt.
Richtliniendurchsetzung. Wenden Sie Unternehmensrichtlinien auf die Interaktion zwischen Diensten an, stellen Sie sicher, dass Zugriffsrichtlinien durchgesetzt werden und Ressourcen gerecht unter den Verbrauchern verteilt werden. Richtlinienänderungen werden durch Konfigurieren des Netzes vorgenommen, nicht durch Ändern des Anwendungscodes.
Telemetrie. Machen Sie sich ein Bild von den Abhängigkeiten zwischen Diensten und der Art und dem Verkehrsfluss zwischen ihnen, um Probleme schnell zu erkennen.
Kurz gesagt, die Einführung von Istio in unser Projekt wird viele Tools rund um das Verkehrsmanagement, die Überwachung und die Fehlertoleranz bereitstellen, die (unter anderem) viele Vorteile für das Prinzip der hohen Beobachtbarkeit bieten.
Mit minimalen Auswirkungen auf die Implementierung seitens des Entwicklers erstellt Istio beispielsweise Ablaufverfolgungsinformationen wie diese:
Der obige Screenshot zeigt die Ablaufverfolgung einer Anfrage, die drei Microservices in einem Service Mesh trifft. Der folgende Screenshot zeigt dasselbe Netz in einem gerichteten azyklischen Diagramm, das ebenfalls aus den von Istio aufgezeichneten Informationen generiert wurde.
Installieren von Istio
Zu Beginn installieren wir Istio anhand der Anweisungen hier:https://github.com/openshift-istio/openshift-ansible/blob/istio-3.9-0.7.1/istio/Installation.md
Auf dem Master-Knoten:
Wechseln Sie in das Verzeichnis mit der Master-Konfigurationsdatei (master-config.yaml
), zum Beispiel /etc/origin/master
.
Erstellen Sie eine Datei namens master-config.patch
mit folgendem Inhalt:
admissionConfig: pluginConfig: MutatingAdmissionWebhook: configuration: apiVersion: v1 disable: false kind: DefaultAdmissionConfig kubernetesMasterConfig: controllerArguments: cluster-signing-cert-file: - ca.crt cluster-signing-key-file: - ca.key
Führen Sie die folgenden Befehle aus, um master-config.yml
zu patchen Datei und starten Sie die atomaren OpenShift-Master-Dienste neu:
cp -p master-config.yaml master-config.yaml.prepatch oc ex config patch master-config.yaml.prepatch -p "$(cat ./master-config.patch)" > master-config.yaml systemctl restart atomic-openshift-master*
Um die Elasticsearch-Anwendung ausführen zu können, muss die Kernel-Konfiguration auf jedem Knoten geändert werden. diese Änderung wird durch sysctl
gehandhabt Dienst.
Erstellen Sie eine Datei namens /etc/sysctl.d/99-elasticsearch.conf
mit folgendem Inhalt:
vm.max_map_count = 262144
Führen Sie den folgenden Befehl aus:
sysctl vm.max_map_count=262144
Auf einer Maschine mit oc
Benutzer, der mit Cluster-Admin-Rechten angemeldet ist, klonen Sie openshift-istio
Repo lokal:
$ git clone https://github.com/openshift-istio/openshift-ansible.git $ cd openshift-ansible/istio
Führen Sie die Vorlage für das Istio-Installationsprogramm aus:
$ oc new-app istio_installer_template.yaml --param=OPENSHIFT_ISTIO_MASTER_PUBLIC_URL=<master public url>
Überprüfen Sie die Installation:
$ oc get pods -n istio-system -w
Sie sollten eine ähnliche Liste wie diese sehen:
Sobald alle Pods erfolgreich ausgeführt werden, wird eine Reihe neuer Routen erstellt, z. B. die im folgenden Screenshot gezeigten:
Nehmen Sie sich etwas Zeit, um sich die Schnittstellen anzusehen, die durch diese Routen offengelegt werden; Zu diesem Zeitpunkt werden jedoch keine Daten vorhanden sein, bis wir beginnen, unsere App mit einem Istio-Proxy-Sidecar zu verwenden.
Nachdem Istio installiert ist und ausgeführt wird, müssen wir unsere Node.js-Anwendungsbereitstellung so konfigurieren, dass sie den Istio-Proxy-Sidecar enthält. Istio ist so konfiguriert, dass das Proxy-Sidecar allen Bereitstellungen hinzugefügt wird, die die Anmerkung sidecar.istio.io/inject: "true"
enthalten .
Ändern Sie den Port, auf dem die Liveness-/Bereitschaftstests lauschen
Der Istio-Sidecar-Proxy funktioniert nicht ordnungsgemäß, wenn sich die Aktivitäts-/Bereitschaftstests auf demselben Port wie die App-Routen befinden. Um dieses Problem zu beheben, ändern wir den Port für die Probes in unserer Node.js-App auf 3000.
Dazu fügen wir eine zusätzliche Express-Web-Framework-Instanz hinzu, die Port 3000 überwacht, indem wir Folgendes zu app.js
hinzufügen :
const health = express(); … probe(health, options); health.listen(3000, function(){ console.log('App ready, probes listening on port 3000'); })
Das vollständige app.js
Datei sieht nun so aus:
const path = require('path'); const express = require('express'); const bodyParser = require('body-parser'); const probe = require('kube-probe'); const app = express(); const health = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})); app.use(express.static(path.join(__dirname, 'public'))); // Expose the license.html at http[s]://[host]:[port]/licences/licenses.html app.use('/licenses', express.static(path.join(__dirname, 'licenses'))); let isOnline = true; // app.use('/api/greeting', (request, response) => { if (!isOnline) { response.status(503); return response.send('Not online'); } const name = request.query ? request.query.name : undefined; return response.send({content: `Hello, ${name || 'World!'}`}); }); app.use('/api/stop', (request, response) => { isOnline = false; return response.send('Stopping HTTP server'); }); const options = { livenessCallback: (request, response) => { return isOnline ? response.send('OK') : response.sendStatus(500); } }; probe(health, options); health.listen(3000, function(){ console.log('App ready, probes listening on port 3000'); }) module.exports = app;
Aktualisieren Sie die Datei „deployment.yml“
Wir müssen die folgenden Änderungen an .nodeshift/deployment.yml
vornehmen Datei. Ergänzungen sind grün markiert.
Änderungen sind rot markiert:
spec: template: metadata: labels: app: nodejs-health-check-redhat name: nodejs-health-check-redhat annotations: sidecar.istio.io/inject: "true" spec: containers: - name: nodejs-health-check-redhat ports: - containerPort: 8080 protocol: TCP name: http readinessProbe: httpGet: path: /api/health/readiness port: 3000 scheme: HTTP failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 livenessProbe: httpGet: path: /api/health/liveness port: 3000 scheme: HTTP failureThreshold: 2 initialDelaySeconds: 60 periodSeconds: 3 successThreshold: 1 timeoutSeconds: 1 resources: limits: cpu: 200m memory: 400Mi requests: cpu: 100m memory: 200Mi
Sehen wir uns diese Änderungen einzeln an.
Damit Istio-Metriken die Anwendung korrekt identifizieren können, muss die Vorlage in metadata
eine „App“-Bezeichnung haben :
metadata: labels: app: nodejs-health-check-redhat name: nodejs-health-check-redhat
Der Sidecar-Injektor von Istio ist so konfiguriert, dass der Sidecar-Proxy zu allen Bereitstellungen hinzugefügt wird, einschließlich sidecar.istio.io/inject: "true"
Anmerkung. Also fügen wir dies unter metadata
hinzu :
annotations:  sidecar.istio.io/inject: "true"
Damit die Daten als HTTP protokolliert werden, muss der Container eine Portdefinition namens http
haben .
- name: nodejs-health-check-redhat ports: - containerPort: 8080 protocol: TCP name: http
Wie bereits erwähnt, ändern wir die Probe-Ports von 8080 auf 3000:
readinessProbe: httpGet: path: /api/health/readiness port: 3000 scheme: HTTP failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 livenessProbe: httpGet: path: /api/health/liveness port: 3000 scheme: HTTP failureThreshold: 2 initialDelaySeconds: 60 periodSeconds: 3 successThreshold: 1 timeoutSeconds: 1
Und schließlich fügen wir auch einige Ressourcenbeschränkungen hinzu, um OpenShift die erforderliche CPU und den Arbeitsspeicher mitzuteilen, die dieser Container verbrauchen wird:
resources: limits: cpu: 200m memory: 400Mi requests: cpu: 100m memory: 200Mi
Erstellen Sie eine service.yml-Datei
Damit Istio den Datenverkehr zu unserer App als HTTP behandeln kann, müssen wir einen service.yml
erstellen Datei im .nodeshift
Ordner und die Datei muss Folgendes enthalten:
spec: ports: - name: http port: 8080 protocol: TCP targetPort: 8080
Stellen Sie die Anwendung erneut bereit
Löschen Sie zunächst die vorhandene Bereitstellungskonfiguration:
$ oc delete dc/nodejs-health-check-redhat $ oc delete service nodejs-health-check-redhat $ oc delete route nodejs-health-check-redhat
Führen Sie npm run openshift
aus um die Anwendung erneut bereitzustellen.
Sobald die Bereitstellung abgeschlossen ist, sollten Sie Folgendes in der OpenShift-Konsole sehen:
Hinweis:Der obige Screenshot zeigt, dass jetzt zwei Container bereit sind (2/2) im Pod nodejs-health-check-redhat, was darauf hinweist, dass der Istio-Sidecar-Proxy neben dem App-Container ausgeführt wird.
Wenn Sie auf den laufenden Pod klicken, sollten Sie die Liste der Container wie folgt sehen:
Navigieren Sie zur UI-Route, z. B. http://nodejs-health-check-redhat-rhoar.router.default.svc.cluster.local/
, und führen Sie eine Reihe von Anfragen aus. Es lohnt sich auch, auf Service stoppen zu klicken klicken, um zu testen, wie Istio damit umgeht, dass der Dienst nicht verfügbar ist.
Überprüfen Sie die Ergebnisse in Istio
Wenn Sie sich jetzt die grafana
ansehen Route, die wir im istio-system
erstellt haben project, sollten Sie so etwas wie den folgenden Screenshot sehen, der den Datenverkehr zu unserer Anwendung mit Antwortzeiten, Fehler- und Erfolgsraten deutlich zeigt.
Wenn Sie sich die Jaeger-Konsole ansehen, sollten Sie auch eine erhebliche Menge an Aktivitäten sehen, zum Beispiel:
Zusammenfassung
Das Erstellen containerbasierter Lösungen kann wie eine herausfordernde Aufgabe erscheinen, die für Anwendungsentwickler viel Overhead bedeutet. Durch die Verwendung einer Kombination aus RHOAR und Istio werden viele dieser Überlegungen erledigt, sodass sich Anwendungsentwickler auf die Implementierung der Geschäftslogik konzentrieren können.
Diese Tools machen es Entwicklern viel einfacher, die Bereitstellung ihrer Anwendung auf OpenShift zu steuern, mit dem Service-Orchestrierungs-Framework zu interagieren, die Leistung ihrer Anwendung zu überwachen, zu verstehen, wie die Anwendung mit anderen Anwendungen (Service Mesh) zusammenhängt, und auch einzuführen und Systemfehler testen. Entwickler müssen nicht lernen, wie sie ihre Anwendung containerisieren oder Metriken oder Tracing-Tools auf Anwendungsebene implementieren. dies alles wird mit minimaler Konfiguration bereitgestellt.