Kubernetes-Handbuch, Teil 2: Erstellen und Arbeiten mit einem Cluster

Letztes Mal haben wir zwei Ansätze für die Arbeit mit Microservices untersucht. Eine davon beinhaltet insbesondere die Verwendung von Docker-Containern, in denen Sie den Code von Microservices und Hilfsprogrammen ausführen können. Heute werden wir unter Verwendung unserer vorhandenen Container-Images mit Kubernetes arbeiten.



Wir stellen vor: Kubernetes


Ich verspreche, und ich übertreibe überhaupt nicht, dass Sie sich beim Lesen dieses Artikels fragen: "Warum heißen Kubernetes nicht Supernetes?"


Supernetes

Wenn Sie den vorherigen Teil dieses Materials gelesen haben, wissen Sie, dass wir uns dort mit vielen Dingen befasst haben, die mit der Vorbereitung von Anwendungen für die Containerisierung und der Arbeit mit Docker-Containern zusammenhängen. Es mag Ihnen so erscheinen, als ob das Schwierigste jetzt auf Sie wartet, aber tatsächlich ist das, worüber wir hier sprechen werden, viel einfacher als das, was wir bereits herausgefunden haben. Der einzige Grund, warum das Erlernen von Kubernetes für jemanden als entmutigende Aufgabe erscheint, liegt in der Menge zusätzlicher Informationen, die Sie benötigen, um Kubernetes zu verstehen und effektiv zu nutzen. Wir haben bereits alle "zusätzlichen Informationen" besprochen, die für die erfolgreiche Entwicklung von Kubernetes erforderlich sind.

▍Was ist Kubernetes?


Im ersten Teil dieses Artikels wurden Sie nach dem Start von Microservices in Containern gebeten, über das Problem der Skalierung containerisierter Anwendungen nachzudenken.
Ich schlage vor, gemeinsam darüber nachzudenken, im Format von Fragen und Antworten:

Frage: Wie skalieren containerisierte Anwendungen?
Antwort: Starten Sie zusätzliche Container.

Frage: Und wie verteilt sich die Last auf sie? Was ist, wenn ein bestimmter Server bereits maximal ausgelastet ist und der Container auf einem anderen Server bereitgestellt werden muss? Wie finde ich den effizientesten Weg, um Hardware zu nutzen?
Antwort: Also ... ich schaue im Internet nach ...

Frage: Wie kann ich Programme aktualisieren, ohne das System zu stören? Und wenn das Update einen Fehler enthält, wie kann man zur Arbeitsversion der Anwendung zurückkehren?

Tatsächlich ist es die Kubernetes-Technologie, die diese und viele andere Fragen würdig beantwortet. Ich werde versuchen, die Definition von Kubernetes auf einen Satz einzugrenzen: "Kubernetes ist ein Containerverwaltungssystem, das die zugrunde liegende Infrastruktur (die Umgebung, in der die Container ausgeführt werden) abstrahiert."

Ich glaube, dass Ihnen das Konzept des „Containermanagements“ jetzt nicht besonders klar ist, obwohl wir dies bereits erwähnt haben. Im Folgenden werden wir diese Technologie in der Praxis betrachten. Das Konzept der "Abstraktion der Basisinfrastruktur" wird jedoch zuerst angetroffen. Deshalb werden wir jetzt darüber nachdenken.

▍Abstraktion der Basisinfrastruktur


Mit Kubernetes können Anwendungen von der Infrastruktur abstrahieren, sodass wir eine einfache API erhalten, an die Sie Anforderungen senden können. Kubernetes versucht, diese Anforderungen mit all seinen Funktionen zu erfüllen. In einer regulären Sprache kann eine ähnliche Anforderung beispielsweise wie folgt beschrieben werden: "Kubernetes, 4 Bildcontainer X erweitern". Nach Erhalt des Befehls findet Kubernetes Knoten, die nicht zu beschäftigt sind (sie werden auch als "Knoten" bezeichnet - vom englischen "Knoten"), auf denen Sie neue Container bereitstellen können.


API-Serveranforderung

Was bedeutet das für den Entwickler? Dies bedeutet, dass er sich keine Gedanken über die Anzahl der Knoten machen muss, darüber, wo genau die Container gestartet werden oder wie sie interagieren. Er muss sich nicht mit Hardwareoptimierung befassen oder sich um Knoten kümmern, die möglicherweise nicht richtig funktionieren (und etwas Ähnliches wird laut Murphys Gesetz sicherlich passieren), da bei Bedarf neue Knoten zum Kubernetes-Cluster hinzugefügt werden können. Wenn mit einigen vorhandenen Knoten etwas nicht stimmt, stellt Kubernetes Container auf den Knoten bereit, die sich noch in einem fehlerfreien Zustand befinden.

Vieles von dem, was in der vorherigen Abbildung gezeigt wird, ist Ihnen bereits bekannt. Es gibt aber auch etwas Neues:

  • API-Server Das Tätigen von Anrufen an diesen Server ist die einzige Möglichkeit, mit dem vorhandenen Cluster zu interagieren, unabhängig davon, ob es sich um das Starten oder Stoppen von Containern, das Überprüfen des Systemstatus, das Arbeiten mit Protokollen oder das Ausführen anderer Aktionen handelt.
  • Kubelet. Dies ist ein Agent, der die Container innerhalb des Knotens überwacht und mit dem Hauptknoten interagiert.

Bitte beachten Sie, dass wir in einigen vorhergehenden Sätzen den Begriff „Container“ verwenden, aber hier wäre es korrekter, den Begriff „Pod“ zu verwenden. Diese Entitäten werden in russischsprachigen Veröffentlichungen oft als „Hülsen“ bezeichnet, und manchmal werden in der Dokumentation „Hülsen“ genannt, um das Konzept der „Hülse“ zu verdeutlichen. Sie sprechen von einer „Herde Wale“ (Hülse der Wale) oder einer „Erbsenschote“. aber niemand nennt sie "Herden" oder "Schoten". Wenn wir von ihnen sprechen, werden wir das Wort "unter" verwenden. Jetzt können Sie sie als Container betrachten. Wir werden weiter unten mehr über Pods sprechen.

Wir werden vorerst damit aufhören, da wir darüber weiter sprechen können, und außerdem gibt es viele gute Materialien zur Theorie der Kubernetes. Dies ist beispielsweise eine offizielle Dokumentation, obwohl sie nicht leicht zu lesen ist, oder Bücher wie dieses .

▍ Standardisierung der Arbeit mit Cloud-Dienstleistern


Eine weitere Stärke von Kubernetes liegt in der Tatsache, dass diese Technologie zur Standardisierung der Arbeit mit Cloud-Service-Providern (Cloud Service Provider, CSP) beiträgt. Dies ist eine kühne Aussage. Betrachten Sie das folgende Beispiel. Ein Spezialist, der Azure oder die Google Cloud Platform gut kennt, muss an einem Projekt arbeiten, das für eine völlig neue Cloud-Umgebung entwickelt wurde, mit der er nicht vertraut ist. In dieser Situation kann viel schief gehen. Beispielsweise können sich die Fristen für die Lieferung des Projekts verzögern, das Kundenunternehmen des Projekts muss möglicherweise mehr Cloud-Ressourcen als geplant mieten und so weiter.

Bei der Verwendung von Kubernetes kann ein solches Problem einfach nicht auftreten, da die Arbeit mit Kubernetes unabhängig davon, um welchen Cloud-Dienstanbieter es sich handelt, immer gleich aussieht. Der Entwickler teilt dem API-Server deklarativ mit, was er benötigt, und Kubernetes arbeitet mit den Ressourcen des Systems, sodass der Entwickler die Details der Implementierung dieses Systems ignorieren kann.

Verweilen Sie ein wenig bei dieser Idee, da dies eine sehr mächtige Gelegenheit für Kubernetes ist. Für Unternehmen bedeutet dies, dass ihre Entscheidungen nicht an einen bestimmten CSP gebunden sind. Wenn ein Unternehmen ein besseres Angebot auf dem Cloud-Service-Markt findet, kann es dieses Angebot frei nutzen, indem es zu einem neuen Anbieter wechselt. Darüber hinaus geht die Erfahrung der Spezialisten des Unternehmens nirgendwo verloren.

Lassen Sie uns nun über die praktische Verwendung von Kubernetes sprechen

Kubernetes Übung: Pods


Wir haben den Start von Microservices in Containern konfiguriert, der Einrichtungsprozess war ziemlich langwierig, aber wir haben es geschafft, zu einem funktionierenden System zu gelangen. Darüber hinaus ist unsere Lösung, wie bereits erwähnt, nicht gut skalierbar und nicht störungsresistent. Wir werden diese Probleme mit Kubernetes lösen. Als nächstes bringen wir unser System in eine Form, die dem folgenden Schema entspricht. Die Container werden nämlich von Kubernetes verwaltet.


Microservices arbeiten in einem von Kubernetes verwalteten Cluster

Hier verwenden wir Minikube für die lokale Bereitstellung des Clusters und zum Testen der Funktionen von Kubernetes. Alles, was wir hier tun, kann jedoch über Cloud-Plattformen wie Azure oder Google Cloud Platform erfolgen.

▍Installation und Start von Minikube


Befolgen Sie zum Installieren von Minikube die Anweisungen in der Dokumentation . Während der Installation von Minikube installieren Sie auch Kubectl. Dies ist ein Client, mit dem Anforderungen an den Kubernetes-API-Server gestellt werden können.

Führen Sie zum Starten von Minikube den Befehl minikube start und führen Sie nach Abschluss den Befehl kubectl get nodes . Infolgedessen sollten Sie Folgendes sehen:

 kubectl get nodes NAME       STATUS ROLES     AGE VERSION minikube   Ready <none>    11m v1.9.0 

Minikube stellt uns einen Cluster zur Verfügung, der nur aus einem Knoten besteht. Das passt zwar ganz gut zu uns. Diejenigen, die mit Kubernetes arbeiten, müssen sich nicht genau darum kümmern, wie viele Knoten sich im Cluster befinden, da Sie mit Kubernetes von solchen Details abstrahieren können.

Sprechen wir jetzt über Pods.

▍Pods


Ich mag Container wirklich, und Sie mögen sie jetzt wahrscheinlich auch. Warum bietet Kubernetes uns die Verwendung von Pods an, Entitäten, die die minimal einsetzbaren Recheneinheiten in diesem System darstellen? Unter welchen Funktionen wird es ausgeführt? Tatsache ist, dass der Herd einen oder mehrere Container enthalten kann, die dieselbe Laufzeit haben.

Aber ist es notwendig, zum Beispiel zwei Container in einem Herd auszuführen? Wie sagt man ... Normalerweise gibt es nur einen Container pro Container, und das werden wir tun. In den Fällen, in denen beispielsweise zwei Container gemeinsam auf dasselbe Data Warehouse zugreifen müssen oder wenn sie mithilfe der Interprozesskommunikationstechnik verbunden sind oder wenn sie aus einem anderen Grund eng miteinander verbunden sind, kann dies alles realisiert werden indem man sie in einem Herd laufen lässt. Eine andere Möglichkeit, in der sich Pods unterscheiden, besteht darin, dass sie keine Docker-Container verwenden müssen. Bei Bedarf können Sie hier andere Technologien für die Containerisierung von Anwendungen anwenden, z. B. Rkt .

Das folgende Diagramm zeigt die nummerierten Herdeigenschaften.


Herdeigenschaften

Berücksichtigen Sie diese Eigenschaften.

  1. Jeder Pod in einem Kubernetes-Cluster verfügt über eine eindeutige IP-Adresse.
  2. Ein Herd kann viele Behälter enthalten. Sie teilen die verfügbaren Portnummern, localhost sie können beispielsweise Informationen über localhost miteinander austauschen (natürlich können sie nicht dieselben Ports verwenden). Die Interaktion mit Containern in anderen Pods wird anhand der IP-Adressen dieser Pods organisiert.
  3. Container in Pods teilen sich Datenspeichervolumen, IP-Adresse, Portnummern und IPC-Namespace.

Es ist zu beachten, dass Container ihre eigenen isolierten Dateisysteme haben, sie jedoch Daten mithilfe der Kubernetes-Ressource namens Volume gemeinsam nutzen können .

Für uns reicht das, was bereits über die Herde gesagt wurde, aus, um die Kubernetes weiterhin zu beherrschen. Lesen Sie hier mehr darüber.

▍ Beschreibung des Herdes


Das Folgende ist eine Manifestdatei für die sa-frontend Anwendung.

 apiVersion: v1 kind: Pod                                            # 1 metadata: name: sa-frontend                                  # 2 spec:                                                # 3 containers:   - image: rinormaloku/sentiment-analysis-frontend # 4     name: sa-frontend                              # 5     ports:       - containerPort: 80 

Lassen Sie uns einige der darin angegebenen Parameter erklären.

  1. Kind : Gibt die Art der Kubernetes-Ressource an, die erstellt werden soll. In unserem Fall ist dies Pod .
  2. Name : Name der Ressource. Wir haben es sa-frontend .
  3. Spec : Ein Objekt, das den gewünschten Status der Ressource beschreibt. Die wichtigste Eigenschaft hierbei ist die Anordnung der Container.
  4. Image : Das Bild des Containers, den wir in diesem Pod ausführen möchten.
  5. Name : Ein eindeutiger Name für den darunter liegenden Container.
  6. ContainerPort : Der Port, den der Container überwacht. Dieser Parameter kann als Hinweis darauf angesehen werden, wer diese Datei liest (wenn Sie diesen Parameter weglassen, wird der Zugriff auf den Port nicht eingeschränkt).

▍Erstellen eines SA-Frontends


Die Pod-Beschreibungsdatei, über die wir gesprochen haben, finden Sie unter resource-manifests/sa-frontend-pod.yaml . Sie müssen entweder mit den Terminal-Tools in diesen Ordner wechseln oder beim Aufrufen des entsprechenden Befehls den vollständigen Pfad zur Datei angeben. Hier ist dieser Befehl und ein Beispiel für eine Systemreaktion darauf:

 kubectl create -f sa-frontend-pod.yaml pod "sa-frontend" created 

Führen Sie den folgenden Befehl aus, um herauszufinden, ob es unter funktioniert:

 kubectl get pods NAME                          READY STATUS RESTARTS AGE sa-frontend                   1/1 Running 0 7s 

Wenn der Status des Herds während der Ausführung dieses Befehls ContainerCreating , können Sie denselben Befehl mit dem --watch . Aus diesem Grund werden Informationen dazu automatisch angezeigt, wenn sich der Herd im Betriebszustand befindet.

▍Zugriff auf die Anwendung von außen


Um den Zugriff auf die Anwendung von außen zu organisieren, ist es richtig, eine Kubernetes-Ressource des Servicetyps zu erstellen, über die wir weiter unten sprechen werden. Der Kürze halber verwenden wir hier jedoch eine einfache Portweiterleitung:

 kubectl port-forward sa-frontend 88:80 Forwarding from 127.0.0.1:88 -> 80 

Wenn Sie jetzt unter 127.0.0.1:88 einen Browser 127.0.0.1:88 , wird die Seite "React-Anwendung" angezeigt.

▍ Falscher Skalierungsansatz


Wir haben bereits gesagt, dass eine der Funktionen von Kubernetes die Anwendungsskalierung ist. Um diese Gelegenheit zu nutzen, führen wir eine weitere unter aus. Erstellen Sie eine Beschreibung einer anderen Pod Ressource, indem Sie den folgenden Code in die Datei sa-frontend-pod2.yaml :

 apiVersion: v1 kind: Pod                                           metadata: name: sa-frontend2      #   spec:                                                containers:   - image: rinormaloku/sentiment-analysis-frontend     name: sa-frontend                                  ports:       - containerPort: 80 

Wie Sie sehen können, ist die einzige Änderung, wenn Sie diese Beschreibung mit der oben untersuchten vergleichen, der Wert der Name Eigenschaft.

Erstellen Sie eine neue unter:

 kubectl create -f sa-frontend-pod2.yaml pod "sa-frontend2" created 

Stellen Sie sicher, dass es ausgeführt wird:

 kubectl get pods NAME                          READY STATUS RESTARTS AGE sa-frontend                   1/1 Running 0 7s sa-frontend2                  1/1 Running 0 7s 

Jetzt haben wir zwei Herde! Es stimmt, hier gibt es nichts Besonderes zu genießen. Bitte beachten Sie, dass die hier gezeigte Lösung für das Problem der Anwendungsskalierung viele Nachteile aufweist. Wie das richtig geht, erfahren Sie im Abschnitt über eine andere Kubernetes-Ressource namens Deployment.

Überlegen Sie nun, was wir nach dem Start von zwei identischen Herden erhalten haben. Der Nginx-Webserver wird jetzt in zwei verschiedenen Pods ausgeführt. In dieser Hinsicht können wir zwei Fragen stellen:

  1. Wie kann ich von außen per URL auf diese Server zugreifen?
  2. Wie organisiere ich den Lastausgleich zwischen ihnen?


Falscher Skalierungsansatz

Unter den Kubernetes-Tools befinden sich Ressourcen des Formulars Service. Reden wir über sie.

Kubernetes Praxis: Dienstleistungen


Kubernetes-Dienste fungieren als Zugangspunkte zu Herdsätzen, die dieselbe Funktionalität wie diese Herde bieten. Services lösen schwierige Aufgaben, indem sie mit Herden arbeiten und die Last zwischen ihnen ausgleichen.


Der Kubernetes-Dienst bedient IP-Adressen

In unserem Kubernetes-Cluster gibt es Pods, die verschiedene Funktionen implementieren. Dies ist eine Front-End-Anwendung, eine Spring-Webanwendung und eine in Python geschriebene Flask-Anwendung. Dies wirft die Frage auf, wie der Dienst verstehen soll, mit welcher Art von Pods er arbeiten muss, dh wie er anhand der Informationen herausfinden kann, welche Informationen das System für die Pods erstellen soll.

Dies geschieht mit einer anderen Kubernetes-Abstraktion namens Label. Die Arbeit mit Tags besteht aus zwei Schritten:

  1. Durch die Zuweisung von Etiketten kann der Dienst bearbeitet werden.
  2. Durch Anwenden eines „Selektors“ auf den Dienst, der bestimmt, welche Pods welchen Etiketten zugewiesen sind, funktioniert der Dienst.

Vielleicht ist dies als Illustration leichter vorstellbar als zu beschreiben.


Beschriftete Pods und ihre Manifestdateien

Wir sehen hier zwei Herde, denen mit der app: sa-frontend Konstrukt die gleichen Bezeichnungen zugewiesen wurden. Der Dienst ist an Pods mit solchen Markierungen interessiert.

▍Tags


Labels bieten Entwicklern eine einfache Möglichkeit, Kubernetes-Ressourcen zu organisieren. Es handelt sich um Schlüssel-Wert-Paare, die Sie beliebigen Ressourcen zuweisen können. Ändern Sie die Herdbeschreibungsdateien der Frontend-Anwendung und bringen Sie sie in die in der vorherigen Abbildung gezeigte Ansicht. Speichern Sie danach diese Dateien und führen Sie die folgenden Befehle aus:

 kubectl apply -f sa-frontend-pod.yaml Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply pod "sa-frontend" configured kubectl apply -f sa-frontend-pod2.yaml Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply pod "sa-frontend2" configured 

Wenn diese Befehle ausgeführt werden, gibt das System Warnungen aus (es passt nicht zu uns, dass wir apply anstelle von create , wir verstehen dies), aber nach einer Warnung meldet es, dass die entsprechenden Pods konfiguriert sind. Wir können überprüfen, ob Etiketten Etiketten zugewiesen wurden, indem wir die Protokolle filtern, für die Informationen angezeigt werden sollen:

 kubectl get pod -l app=sa-frontend NAME           READY STATUS    RESTARTS AGE sa-frontend    1/1 Running   0 2h sa-frontend2   1/1 Running   0 2h 

Eine andere Möglichkeit, um zu überprüfen, ob Beschriftungen tatsächlich Beschriftungen zugewiesen wurden, besteht darin, den Schlüssel --show-labels an den vorherigen Befehl anzuhängen. Aus diesem Grund enthalten Informationen zu ihren Pods auch Daten zu ihren Marken.

Jetzt wurden Tags zugewiesen und wir können den Dienst so konfigurieren, dass er mit ihnen funktioniert. Daher werden wir die Beschreibung eines Dienstes wie LoadBalancer .


Lastausgleich mit einem Dienst wie LoadBalancer

▍ Servicebeschreibung


Hier ist eine YAML-Beschreibung eines Dienstes wie LoadBalancer :

 apiVersion: v1 kind: Service              # 1 metadata: name: sa-frontend-lb spec: type: LoadBalancer       # 2 ports: - port: 80               # 3   protocol: TCP          # 4   targetPort: 80         # 5 selector:                # 6   app: sa-frontend       # 7 

Erklären Sie diesen Text:

  1. Kind : Wir erstellen einen Service, eine Service Ressource.
  2. Type : Der in der Spezifikation angegebene Ressourcentyp. Wir haben den Typ LoadBalancer , weil wir mit diesem Service das Problem des Lastausgleichs zwischen den Herden lösen wollen.
  3. Port : Port, an dem der Dienst Anforderungen akzeptiert.
  4. Protocol : Das vom Dienst verwendete Protokoll.
  5. TargetPort : Port, an den eingehende Anforderungen umgeleitet werden.
  6. Selector : Ein Objekt, das Informationen darüber enthält, mit welchen Pods der Dienst arbeiten soll.
  7. app: sa-frontend : Diese Eigenschaft gibt an, mit welchen Pods der Dienst arbeiten wird. Dies sind nämlich die Pods, denen das Label app: sa-frontend zugewiesen ist.

Um einen Dienst zu erstellen, müssen Sie den folgenden Befehl ausführen:

 kubectl create -f service-sa-frontend-lb.yaml service "sa-frontend-lb" created 

Sie können den Status des Dienstes wie folgt überprüfen:

 kubectl get svc NAME             TYPE CLUSTER-IP      EXTERNAL-IP PORT(S) AGE sa-frontend-lb   LoadBalancer 10.101.244.40   <pending> 80:30708/TCP 7m 

Hier können Sie sehen, dass sich die EXTERNAL-IP Eigenschaft im Status <pending> , aber Sie können nicht warten, bis sie sich ändert. Dies liegt an der Tatsache, dass wir Minikube verwenden. Wenn wir bei der Arbeit mit einem bestimmten Cloud-Dienstanbieter wie Azure oder der Google Cloud Platform einen ähnlichen Dienst erstellen würden, hätte der Dienst eine öffentliche IP-Adresse, die den Zugriff über das Internet ermöglicht.

Trotzdem erlaubt uns Minikube nicht, herumzuspielen, was uns einen nützlichen Befehl für das lokale Debuggen des Systems gibt:

 minikube service sa-frontend-lb Opening kubernetes service default/sa-frontend-lb in default browser... 

Dank dieses Befehls wird ein Browser gestartet, der auf den Dienst zugreift. Nachdem der Dienst die Anforderung erhalten hat, leitet er sie an einen der Herde weiter (es spielt keine Rolle, unter welchem ​​er sich befindet). Diese Abstraktion ermöglicht es uns, eine Gruppe von Herden als eine Einheit zu betrachten und mit ihnen zu arbeiten, wobei der Dienst als ein einziger Zugangspunkt zu ihnen verwendet wird.

In diesem Abschnitt haben wir darüber gesprochen, wie Ressourcen Beschriftungen zugewiesen werden und wie sie beim Konfigurieren von Diensten als Selektoren verwendet werden. Hier haben wir einen Service wie LoadBalancer beschrieben und erstellt. Dank dessen haben wir das Problem der Skalierung der Anwendung (Skalierung besteht aus dem Hinzufügen neuer Herde mit den entsprechenden Beschriftungen zum Cluster) und der Organisation des Lastausgleichs zwischen den Herden unter Verwendung des Dienstes als Einstiegspunkt gelöst.

Kubernetes-Praxis: Bereitstellungen


Die Bereitstellung ist eine Abstraktion von Kubernetes, mit der wir steuern können, was im Anwendungslebenszyklus immer vorhanden ist. Es geht darum, Anwendungsänderungen zu verwalten. Anwendungen, die sich nicht ändern, sind sozusagen „tote“ Anwendungen. Wenn die Anwendung "lebt", kann es vorkommen, dass sich ihre Anforderungen regelmäßig ändern, ihr Code erweitert wird, dieser Code gepackt und bereitgestellt wird. Darüber hinaus können bei jedem Schritt des Prozesses Fehler gemacht werden.

Mit einer Ressource vom Typ Bereitstellung können Sie den Übergang von einer Version einer Anwendung zu einer anderen automatisieren. Dies geschieht ohne Unterbrechung des Systems. Wenn während dieses Vorgangs ein Fehler auftritt, haben wir die Möglichkeit, schnell zur vorherigen funktionierenden Version der Anwendung zurückzukehren.

▍Verwendung von Bereitstellungen


Jetzt verfügt der Cluster über zwei Herde und einen Dienst, der den Zugriff von außen ermöglicht und die Last auf sie ausgleicht.


Aktueller Status des Clusters

Wir haben darüber gesprochen, dass es keine gute Idee ist, zwei verschiedene Herde mit derselben Funktionalität zu betreiben. Wenn wir ein solches Schema verwenden, müssen wir mit jedem Herd einzeln arbeiten, jeden bestimmten Herd erstellen, aktualisieren, löschen und seinen Zustand beobachten. Bei diesem Ansatz ist es nicht erforderlich, über ein schnelles Update des Systems oder das schnelle Rollback eines nicht erfolgreichen Updates zu sprechen. Wir sind mit diesem Sachverhalt nicht zufrieden, daher werden wir auf die Möglichkeit der Bereitstellung von Ressourcen zurückgreifen, die auf die Lösung der oben genannten Probleme abzielen.

Bevor wir mit der Arbeit fortfahren, formulieren wir die Ziele, die uns Richtlinien geben, die beim Parsen der Bereitstellungsmanifestdatei hilfreich sind. Also hier ist was wir brauchen:

  1. Wir möchten in der Lage sein, zwei Herde basierend auf einem Container- rinormaloku/sentiment-analysis-frontend zu erstellen.
  2. Wir benötigen ein Anwendungsbereitstellungssystem, mit dem es bei der Aktualisierung ohne Unterbrechungen funktioniert.
  3. Wir möchten, dass das app: sa-frontend Label zugewiesen wird app: sa-frontend , wodurch der sa-frontend-lb Dienst diese Pods erkennen kann.

Wir werden diese Anforderungen nun als Beschreibung der Bereitstellungsressource ausdrücken.

▍ Bereitstellungsbeschreibung


Hier ist eine YAML-Beschreibung einer Ressource vom Typ Bereitstellung, die unter Berücksichtigung der oben genannten Systemanforderungen erstellt wurde:

 apiVersion: extensions/v1beta1 kind: Deployment                                          # 1 metadata: name: sa-frontend spec: replicas: 2                                             # 2 minReadySeconds: 15 strategy:   type: RollingUpdate                                   # 3   rollingUpdate:     maxUnavailable: 1                                   # 4     maxSurge: 1                                         # 5 template:                                               # 6   metadata:     labels:       app: sa-frontend                                  # 7   spec:     containers:       - image: rinormaloku/sentiment-analysis-frontend         imagePullPolicy: Always                         # 8         name: sa-frontend         ports:           - containerPort: 80 

Lassen Sie uns diese Beschreibung analysieren:

  1. Kind : Hier steht, dass wir eine Ressource der Deployment .
  2. Replicas : Eine Eigenschaft des Bereitstellungsspezifikationsobjekts, die definiert, wie viele Instanzen (Replikate) von Herden ausgeführt werden sollen.
  3. Type : beschreibt die Strategie, die in dieser Bereitstellung beim Wechsel von der aktuellen zu einer neuen Version verwendet wird. RollingUpdate Strategie von RollingUpdate bietet keine Systemausfälle während Upgrades.
  4. MaxUnavailable : Dies ist eine Eigenschaft des RollingUpdate Objekts, mit der die maximale Anzahl nicht verfügbarer Herde (im Vergleich zur gewünschten Anzahl von Herden) festgelegt wird, wenn eine sequentielle Systemaktualisierung durchgeführt wird. In unserer Bereitstellung, die das Vorhandensein von 2 Replikaten impliziert, gibt der Wert dieser Eigenschaft an, dass nach Abschluss eines Pods ein weiterer ausgeführt wird, wodurch die Anwendung während des Updates verfügbar wird.
  5. MaxSurge : Dies ist eine Eigenschaft des RollingUpdate Objekts, die die maximale Anzahl von Herden beschreibt, die einer Bereitstellung hinzugefügt werden können (im Vergleich zu einer bestimmten Anzahl von Herden). In unserem Fall bedeutet der Wert 1, dass wir beim Wechsel zu einer neuen Version des Programms dem Cluster ein weiteres Sub hinzufügen können, was dazu führt, dass bis zu drei Herde gleichzeitig gestartet werden können.
  6. Template : Dieses Objekt definiert die Herdvorlage, mit der die beschriebene Deployment neue Herde erstellt. Diese Einstellung ist Ihnen wahrscheinlich bekannt.
  7. app: sa-frontend : Bezeichnung für Herde, die nach einem bestimmten Muster erstellt wurden.
  8. ImagePullPolicy : ImagePullPolicy die Reihenfolge der Arbeit mit Bildern. In unserem Fall ist diese Eigenschaft auf Always festgelegt, Always während jeder Bereitstellung wird das entsprechende Image aus dem Repository heruntergeladen.

Nachdem wir das alles untersucht haben, wollen wir weiter üben. Führen Sie die Bereitstellung aus:

 kubectl apply -f sa-frontend-deployment.yaml deployment "sa-frontend" created 

Überprüfen Sie den Status des Systems:

 kubectl get pods NAME                           READY STATUS RESTARTS AGE sa-frontend                    1/1 Running 0 2d sa-frontend-5d5987746c-ml6m4   1/1 Running 0 1m sa-frontend-5d5987746c-mzsgg   1/1 Running 0 1m sa-frontend2                   1/1 Running 0 2d 

Wie Sie sehen können, haben wir jetzt 4 Pods. Zwei davon wurden mithilfe der Bereitstellungsressource erstellt, zwei weitere haben wir selbst erstellt. Jetzt können Sie die Pods, die wir selbst erstellt haben, mit Befehlen des folgenden Typs entfernen:

 kubectl delete pod <pod-name> 

Hier ist übrigens ein Auftrag für selbständiges Arbeiten. Löschen Sie einen der mit der Bereitstellungsressource erstellten Herde und überwachen Sie das System. Denken Sie über die Gründe nach, bevor Sie weiterlesen.

Beim Löschen eines Herdes erfährt die Bereitstellungsressource, dass sich der aktuelle Status des Systems (1 Sub) vom gewünschten unterscheidet (2 Sub), sodass ein anderes Sub gestartet wird.

Was ist die Verwendung von Bereitstellungsressourcen, abgesehen von der Tatsache, dass das System bei Verwendung im richtigen Zustand gehalten wird? Berücksichtigen Sie die Stärken dieser Ressourcen.

▍ Bereitstellen ohne Systemausfallzeit


Angenommen, ein Produktmanager kommt zu uns und meldet, dass der Client, für den wir dieses Produkt erstellt haben, eine grüne Schaltfläche in der Clientanwendung wünscht. Die Entwickler implementieren diese Anforderung und geben uns das einzige, was wir von ihnen benötigen - einen rinormaloku/sentiment-analysis-frontend:green namens rinormaloku/sentiment-analysis-frontend:green . Jetzt kommt unsere Zeit. Wir, das DevOps-Team, müssen das aktualisierte System bereitstellen und sicherstellen, dass keine Ausfallzeiten auftreten. Lassen Sie uns nun sehen, ob die Bemühungen zur Entwicklung und Konfiguration der Bereitstellungsressource gerechtfertigt sind.

Bearbeiten Sie die Datei sa-frontend-deployment-green.yaml und ersetzen Sie den Namen des rinormaloku/sentiment-analysis-frontend:green durch einen neuen mit rinormaloku/sentiment-analysis-frontend:green . Speichern Sie diese Datei dann als sa-frontend-deployment-green.yaml und führen Sie den folgenden Befehl aus:

 kubectl apply -f sa-frontend-deployment-green.yaml --record deployment "sa-frontend" configured 

Überprüfen Sie den Systemstatus mit dem folgenden Befehl:

 kubectl rollout status deployment sa-frontend Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 of 2 updated replicas are available... deployment "sa-frontend" successfully rolled out 

In Übereinstimmung mit den Daten, die als Antwort auf diesen Befehl angezeigt werden, können wir den Schluss ziehen, dass die Updatebereitstellung erfolgreich war. Während des Upgrades wurden die alten Replikate einzeln durch neue ersetzt. , , , . , , .


, , :

 minikube service sa-frontend-lb 

, .




, , — .

RollingUpdate


, kubectl apply -f sa-frontend-deployment-green.yaml --record , Kubernetes , , . , , rinormaloku/sentiment-analysis-frontend:green . , , .




RollingUpdate , , maxUnavailable: 1 maxSurge: 1 . , Deployment , , , . , , , .

Deployment. , . .


, , . «! ! !», — . . , , :

 kubectl rollout history deployment sa-frontend deployments "sa-frontend" REVISION  CHANGE-CAUSE 1         <none>    2         kubectl.exe apply --filename=sa-frontend-deployment-green.yaml --record=true 

: «, , ?».

«. , ?», — .

, , :

 kubectl rollout undo deployment sa-frontend --to-revision=1 deployment "sa-frontend" rolled back 

. , .

.

.

!

, . Kubernetes , , . , !

. , . CHANGE-CAUSE <none> , — kubectl.exe apply –filename=sa-frontend-deployment-green.yaml –record=true ?

, -- record , .

, , , .

Kubernetes:


Kubernetes, , . , .




.

▍ sa-logic


resource-manifests :

 kubectl apply -f sa-logic-deployment.yaml --record deployment "sa-logic" created 

sa-logic . Python-. app: sa-logic . sa-logic , . sa-logic-deployment.yaml .

-, , — sa-logic .

▍ sa-logic


, Service. , Java-, sa-webapp , , Python-. , , , Python-, . , , , .

, , , , . , sa-logic , sa-logic .

:

 kubectl apply -f service-sa-logic.yaml service "sa-logic" created 

, .




sa-logic , sa-webapp , , .

sa-webapp .

▍ sa-webapp


, Deployment - . , sa-web-app-deployment.yaml , :

 - image: rinormaloku/sentiment-analysis-web-app imagePullPolicy: Always name: sa-web-app env:   - name: SA_LOGIC_API_URL     value: "http://sa-logic" ports:   - containerPort: 8080 

env ? , , , SA_LOGIC_API_URL http://sa-logic . , , . ?

kube-dns.

▍DNS- Kubernetes


Kubernetes , kube-dns . DNS-. kube-dns , DNS- .

, sa-logic , IP-. kube-dns IP- . http://sa-logic IP-.

Deployment sa-webapp .

▍ sa-webapp


:

 kubectl apply -f sa-web-app-deployment.yaml --record deployment "sa-web-app" created 

sa-webapp , . React- , sa-webapp .

▍ sa-webapp


service-sa-web-app-lb.yaml , , , , . , , :

 kubectl apply -f service-sa-web-app-lb.yaml service "sa-web-app-lb" created 

. , , . , sa-frontend , Java- sa-webapp , http://localhost:8080/sentiment . , , sa-webapp , React- , Java-.

, . , — , , .

, :

  1. IP- sa-webapp , :

    minikube service list
    |-------------|----------------------|-----------------------------|
    | NAMESPACE | NAME | URL |
    |-------------|----------------------|-----------------------------|
    | default | kubernetes | No node port |
    | default | sa-frontend-lb | http://192.168.99.100:30708 |
    | default | sa-logic | No node port |
    | default | sa-web-app-lb | http://192.168.99.100:31691 |
    | kube-system | kube-dns | No node port |
    | kube-system | kubernetes-dashboard | http://192.168.99.100:30000 |
    |-------------|----------------------|-----------------------------|
  2. IP- sa-frontend/src/App.js . , :

     analyzeSentence() {       fetch('http://192.168.99.100:31691/sentiment', { /*    */})           .then(response => response.json())           .then(data => this.setState(data));   } 
  3. React-, sa-frontend npm run build .
  4. :

     docker build -f Dockerfile -t $DOCKER_USER_ID/sentiment-analysis-frontend:minikube. 
  5. Docker Hub:

     docker push $DOCKER_USER_ID/sentiment-analysis-frontend:minikube 
  6. sa-frontend-deployment.yaml , .
  7. :

     kubectl apply -f sa-frontend-deployment.yaml 

, , , , minikube service sa-frontend-lb . , - .




Zusammenfassung


Kubernetes , , , , . Kubernetes , , . Kubernetes Supernetes.

, :

  • , , React, Java Python.
  • Docker, , Dockerfile .
  • , , Docker Hub.

, Kubernetes:

  • Dienstleistungen

, , Kubernetes.

Liebe Leser! Kubernetes?

Source: https://habr.com/ru/post/de438984/


All Articles