Kubernetes im Geiste der Piraterie: unser Weg zu Microservices und eine vorgefertigte Vorlage für die Implementierung



Hallo, ich bin Yuri Buylov, ich entwickle bei CarPrice und implementiere auch DevOps-Praktiken, Microservices und Kubernetes. Ich möchte über Kubernetes im Geiste der Piraterie sprechen - nicht nur über die Verwaltung eines großen, schönen Schiffs auf Segeln, sondern über eine Flotte kleiner, unansehnlicher Fischerboote, manchmal rostig, aber sehr schnell, flink und gefährlich.

Es wird für diejenigen interessant sein, die die Infrastruktur entwickeln oder auf Microservices übertragen, DevOps auf Kubernetes implementieren und in jeder Hinsicht auf Cloud Native umsteigen. Ich werde Ihnen über unseren Weg berichten. Am Ende des Artikels werde ich unsere Grundlagen für die Microservices-Umgebung erläutern. Ich werde einen Link zu einer Vorlage geben, die für Entwickler und Tester praktisch ist.

Dieser Artikel basiert auf einer Videopräsentation auf der @ Kubernetes-Konferenz von Mail.ru Cloud SolutionsWenn Sie nicht lesen möchten, können Sie sehen .

Wie wir vor Kubernetes gelebt haben: Dev Server, Bare Metal und Ansible


Wir lebten und leben in einer Art ständiger Veränderungen und Experimente: AV-Tests, Testen verschiedener Hypothesen. Wir starten neue Dienste, und wenn etwas nicht funktioniert, schneiden wir es aus.

Einmal hatten wir einen Monolithen im PHP, der viel Schmerz und Leid brachte. Um eine akzeptable Markteinführungszeit zu gewährleisten, gingen wir den typischen Weg - wir begannen, diesen Monolithen für Microservices zu sehen. Als Ergebnis stellte sich heraus, dass aus einem großen Monolithen viele kleine Monolithen wurden. Dies ist normal, dies gilt für alle, die vor einer ähnlichen Aufgabe standen.

Dann haben wir angefangen, andere Technologien auszuprobieren, insbesondere Golang erschien in unserem Unternehmen, es wurde später die Hauptentwicklungssprache. Es gab Fragen: Wie kann man das alles entwickeln, testen und bereitstellen? Die Antwort lag auf der Hand - Sie benötigen einen Entwickler-Server. Jeder Entwickler muss über einen Entwicklungsserver verfügen, auf dem er eine Verbindung herstellen kann, um dort hochwertigen und leistungsstarken Code zu schreiben.

Infolgedessen haben die Jungs einen Entwickler-Server geschrieben. Das Ergebnis war eine Webschnittstelle, die das Docker-Compose auf den Servern kontrollierte. Es gab auch einen Container mit Quellcode, der in Docker-Compose gemountet war. Der Entwickler konnte eine Verbindung über SSH und Programm herstellen. Dort arbeiteten auch Tester, alles funktionierte perfekt.



Mit der Zunahme der Anzahl der Dienste wurde es jedoch unmöglich zu arbeiten. Der Moment kam, als es notwendig war, etwas einzusetzen, nicht die Container auszupacken. Wir haben Bare Metal genommen und Docker dort gerollt. Dann nahmen sie Ansible, schrieben mehrere Rollen. Jede Rolle ist ein Dienst, bei dem Docker-Compose lag, der zu einem der Autos „kam“.



Also lebten wir: In Nginx registrierten wir uns stromaufwärts mit unseren Händen und sagten, zu welchem ​​Hafen wir gehen sollten, wo dieser Dienst lebt. Es gab sogar eine Yaml-Datei, in der alle Ports aufgelistet waren, damit Anwendungen nicht um sie konkurrieren konnten.

Wie wir zu Kubernetes kamen und die Infrastruktur darauf aufbauten


Offensichtlich kann man nicht so leben, Orchestrierung ist erforderlich. Wir haben das in den Jahren 2017-2018 verstanden, dann war nicht klar, wo wir dieses Orchester bekommen sollten. Kubernetes hatte gerade erst angefangen, es gab HashiCorp Nomad, Rancher, OpenShift. Wir haben Nomad ausprobiert, es war nicht schlecht, aber wir wollten Docker-Compose nicht in Nomad-Konfigurationen umschreiben.

Bei Kubernetes wurde uns sofort klar, dass ausländische Kollegen es versuchten, es gelang ihnen nicht immer. Und wir hatten keine bärtigen Admins, die uns zu einem Cluster machen könnten. Sie begannen zu überlegen, wie sie dies umsetzen sollten. Schon damals war Kubernetes zum Beispiel bei Amazon, aber wir erinnern uns an die Schlösser, nach denen sie sich dringend bewegten. Daher wurde diese Option sofort verworfen, umso teurer der Verkehr dort.

Und dann erschien Kubernetes auf der Mail.ru Cloud Solutions-Plattform als Service Mail.ru Cloud Containers. Wir haben unseren S3-Speicher bereits von Amazon dorthin verlegt und beschlossen, auch K8s zu testen. Wir haben einen Cluster in der Cloud bereitgestellt, alles hat funktioniert.

Zum Testen haben wir uns entschlossen, dort einen zustandslosen Dienst bereitzustellen. Hat eine API für mobile Anwendungen bereitgestellt, bereitgestellt - es funktioniert. Dort 50% des Verkehrs gesendet - es funktioniert. Ja, etwas fiel in regelmäßigen Abständen, aber die Jungs haben es repariert, alles war in Ordnung. Infolgedessen wurde die gesamte Infrastruktur übertragen, jetzt basiert sie auf Kubernetes, hauptsächlich Entwicklungs- und Bühnenservern.



Jeder Entwickler hat seinen eigenen Minikube in VMware, mit dem er arbeitet. Wir starten neue Projekte in Kubernetes in der MCS-Cloud und stellen auch Managed MySQL bereit, das sofort mit allen Slaves, Replikationen und Backups in S3 ankommt.

Wir haben immer noch Vermächtnis auf Bare Metal, einschließlich eines Docker-Clusters, auf dem Ansible ausgeführt wird, aber eines Tages werden wir es herausfinden.

Wie man mit einem Technologiezoo lebt und nicht leidet


Der Technologiezoo ist jetzt nicht mehr so ​​beängstigend wie beispielsweise 2011. Es ist sogar normal, wenn Sie spezielle Tools und Technologien von verschiedenen Orten aus verwenden und nach Belieben verwenden können. Zum Beispiel verwenden wir Golang für einige Dinge, aber Data Scientist arbeitet in Python. Sie können sie nicht zwingen, in GO oder PHP zu schreiben.

Im Allgemeinen haben wir zwei Regeln:

  • Dockerize: Es müssen Container vorhanden sein.
  • Beobachtbarkeit: Diese Behälter müssen beobachtbar sein.

Um die Analogie zum Zoo fortzusetzen: Es gibt Zellen, und es ist nicht so wichtig, wer in diesen Zellen sitzt. Die Hauptsache ist, dass Wasser und Lebensmittel regelmäßig, automatisch und gleichmäßig ankommen und die "lebenswichtigen Produkte" von Dienstleistungen, dh Protokolle, irgendwo zentral versandt werden.

Zur Beobachtung haben wir einen Standardstapel: Jede Anwendung schreibt Protokolle in stdout, von wo aus alles zentral an EFK übertragen wird. Das heißt, der Entwickler kann die Protokolle in Kibana anzeigen. App-Metriken werden in Prometheus, Dashboards und Warnungen standardmäßig in Grafana abgelegt. Jaeger ist eine Opentracing-Geschichte, die zeigt, wer auf welchen Dienst zugreift, wenn wir es nicht wissen oder nicht auf andere Weise damit umgehen wollen.



Wie man mit all dem entwickelt und testet


Nehmen wir an, ein neuer Entwickler kommt zu uns und sieht 100 Services und 100 Repositorys. Er hat sofort Fragen. Wie werden diese 100 Dienste bereitgestellt und wie werden sie konfiguriert? Wo sind die Datenbanken? Welche Konten gibt es? Und es gibt viele solche Fragen. Aus diesem Grund dauerte die Veröffentlichung des neuen Entwicklers unanständig, er konnte eine Woche lang sitzen und alles einrichten.

Aus diesem Grund haben wir eine 1-Klick-Entwicklungsumgebung entwickelt. Jeder Entwickler verfügt über einen eigenen Minikube mit bedingt unendlichen Kernen und Speicher, der in der VMware-Cloud bereitgestellt wird. Plus eine Datenbank - sie kommt täglich aus der Produktion, wird verschleiert, komprimiert und auf ZFS gestellt. Dies ist eine persönliche Entwicklung unseres Administrators. Wir sind seit langer Zeit mit Kostensenkungen beschäftigt. Wir mussten allen Entwicklern eine Basis geben und nicht pleite gehen.

In ZFS gibt es Snapshots. Ein API-Entwickler kann die Datenbank in zwei Sekunden direkt aus der Produktion rollen. Bei Autotests die gleiche Geschichte: Wir beginnen mit der API und alles funktioniert.



So sieht der Entwicklungsablauf heute aus:



Entwickler sind glücklich, DevOps und Administratoren sind glücklich, weil alle Prozesse einheitlich, wiederholbar und einheitlich sind. Aber es gibt eine Sache.

Schichtschichtsystem


Wie Linus Torvalds sagte: „Reden ist billig. Zeig mir den Code. " Wir verwenden also ein mehrstufiges Schichtsystem. Es gibt triviale Ebenen: dev, stage, prod, die jedem einfallen, der CI / CD machen wird.

Aber es gibt immer noch Entwickler, sie brauchen einige ihrer Domains, einige benutzerspezifische Storys, also haben wir eine Ebene mit Benutzerwerten. Dies reicht jedoch nicht aus - Sie müssen noch testen. Angenommen, wir haben eine Verzweigung erstellt, möglicherweise mehrere Dienste, und wir müssen diese an den Tester weitergeben, damit sie wiederholt wird. Dazu haben wir eine Ebene mit Werten für Aufgaben, d. H. Aufgabenwerten.

Ein weiterer, etwas heiliger Moment - wir verwenden Tiller nicht, der sich für Helm entschieden hat, aber wir verwenden ihn tatsächlich als Template-Engine. Das heißt, wir verwenden nur die Helmvorlage, sie gibt eine Yaml-Datei an der Ausgabe aus, die Minikube oder einem Cluster zugeordnet werden kann, und nichts anderes wird benötigt.



Wie das K8s-Helm-Repository funktioniert


Wie gesagt, wir haben offensichtliche Ebenen von Dev, Prod und Stage. Es gibt eine Yaml-Datei von jedem Dienst. Wenn wir einen neuen Dienst gesehen haben, fügen Sie die Datei hinzu.

Zusätzlich gibt es einen Papa dev.server mit dem interessantesten. Es gibt Bash-Skripte, mit denen Sie beispielsweise einen neuen Benutzer erstellen können: Erstellen Sie nicht 100 Dienste mit Ihren Händen und füllen Sie keine Yaml-Dateien aus, sondern führen Sie sie einfach mit einem Befehl aus. Hier werden all diese Yaml-Dateien generiert.



Im selben Ordner befinden sich Aufgaben eines Unterordners. Wenn wir bestimmte Werte für unsere Bereitstellung festlegen müssen, erstellen wir einfach einen Ordner mit darin enthaltenen Aufgabennummern und schreiben den Zweig fest. Dann sagen wir dem Tester: "Ein solcher Zweig liegt im Repository, nehmen Sie ihn und führen Sie ihn aus." Er startet, zieht den Befehl, der im Papierkorb liegt, und alles funktioniert - keine manuelle Konfiguration erforderlich. Das Wunder von DevOps ist eine Infrastruktur als Code.

Infolgedessen läuft der Prozess auf drei Teams hinaus:



Wenn ein neuer Entwickler eintrifft, gibt er ihm Minikube, einen Archivordner mit Zertifikaten und einer Domain. Im Allgemeinen braucht er nur Kubectl und Helm. Er klont das Repository für sich selbst, zeigt kubectl den Pfad zu seiner Konfiguration und führt den Befehl make_user mit seinem Namen aus. Und für alle Dienste werden Kopien für ihn erstellt. Darüber hinaus werden sie nicht nur erstellt - es gibt eine Datenbank, die ihm übergeben wurde, der Entwickler hat Anmeldeinformationen dafür vorgeschrieben, und alle diese Anmeldeinformationen gehen an andere Dienste.

Der Benutzer wurde erstellt. Wie kann ich ihn jetzt bereitstellen? Auch hier ist nichts kompliziert - wir führen deploy.sh mit seinem Namen aus und alles kommt dem Entwickler im Standard-Namespace in seinem Minikube, alles ist sofort auf seiner Domain verfügbar.

Wenn der Entwickler etwas programmiert hat, nimmt er die Problem-ID und gibt sie dem Tester. Der Tester kopiert diesen Zweig, startet eine Bereitstellung, und in seinem Cluster wird eine Umgebung mit einer neuen Funktion angezeigt.

K8s-Steuerbaugruppe


Das Repository selbst wird zusätzlich kompiliert und in CI / CD-Prozesse integriert. Hier gibt es nichts Besonderes - nur Kubectl mit Zertifikaten und Helm.



Im Projekt sieht es folgendermaßen aus:



Angenommen, Sie sind bereitgestellt, und es gibt eine Phase, in der Sie zuerst die Phase durchführen und dann die Tests dort mit Jenkins ausführen müssen. Aus dem Repository haben Sie ein mit Helm kompiliertes Bild. Wir führen den Befehl deploy Namespace service_stage run aus und alles hebt ab.

Dann kommt CI, hier .drone.yml, aber ungefähr das Gleiche wird in GitLab oder anderswo passieren.

Als nächstes startet Jenkins, der die Tests auf der Bühne durchführt. Wenn alles in Ordnung ist, wird fast dieselbe Bereitstellung gestartet, jedoch bereits auf dem Produkt. Das heißt, dieser Mechanismus erleichtert Entwicklern und Testern nicht nur das Leben, sondern wird auch verwendet, um Funktionen für Produkte bereitzustellen.

Wir lieben Open Source, wir möchten in die Entwicklung von DevOps investieren, deshalb haben wir eine Vorlage erstellt, die Sie verwenden können, und sie auf den Github hochgeladen . Es gibt alles, worüber ich gesprochen habe: Sie können nehmen, beobachten, testen und anwenden. Dies ist für alle nützlich, die Microservices implementieren oder unter der Tatsache leiden, dass das Team Microservices implementiert oder DevOps-Prozesse darauf aufbauen möchte.

Unsere anderen verwandten Artikel:

  1. 25 nützliche Kubernetes-Tools: Bereitstellung und Verwaltung .
  2. Abrechnung, Marktplatz und Sandboxen für Big Data zum zweiten Mal: ​​Was Testumgebungen in der Cloud leisten können .
  3. Dank Kubernetes und Automatisierung in zwei Stunden in die Cloud migrieren

Dieser Vortrag wurde erstmals auf der @ Kubernetes-Konferenz von Mail.ru Cloud Solutions gehalten. Sehen Sie sich ein Video mit anderen Aufführungen an und melden Sie sich für Ankündigungen von Telegrammveranstaltungen rund um Kubernetes bei der Mail.ru Group an .

All Articles