Kubernetes Reservierung: Es besteht

Mein Name ist Sergey, ich komme von ITSumma und ich möchte Ihnen sagen, wie wir mit der Reservierung in Kubernetes umgehen. In letzter Zeit habe ich viele Beratungsarbeiten zur Implementierung einer Vielzahl von Devops-Lösungen für verschiedene Teams durchgeführt, und insbesondere arbeite ich eng an Projekten mit K8s. Auf der Uptime Day 4-Konferenz, die sich der Redundanz in komplexen Architekturen widmete, hielt ich eine Präsentation über redundante Würfel, und hier ist seine kostenlose Nacherzählung. Ich werde nur im Voraus warnen, dass er kein direkter Leitfaden zum Handeln ist, sondern eine Verallgemeinerung der Gedanken zu diesem Thema.



Im Prinzip sind Überwachung und Redundanz die beiden Hauptinstrumente, um die Ausfallsicherheit eines Projekts zu erhöhen. Aber in der Cuber ist alles von selbst ausgeglichen, Sie sagen, alles ist von selbst skaliert, und wenn etwas passiert, wird es von selbst aufsteigen ... Das heißt, während der ersten oberflächlichen Untersuchung des Themas hat mir das Internet die Frage beantwortet: "Wie funktioniert K8s Backup?" ? " Viele Leute denken, dass ein Cuber so eine magische Sache ist, die alle Infrastrukturprobleme beseitigt und das Projekt niemals zum Erliegen bringt. Aber ... die Welt ist nicht so, wie es scheint.

Wie sind wir zuvor mit dem Sicherungsprozess umgegangen? Wir hatten identische Plattformen für die Platzierung - entweder waren es virtuelle Maschinen oder es waren Eisenserver, auf die wir drei grundlegende Praktiken angewendet haben:

  1. Codesynchronisation und Statik
  2. Konfigurationssynchronisation
  3. Datenbankreplikation

Und voila: In jedem Moment wechseln wir zur Reserveseite, alle sind glücklich, wir stehen auf, wir sind anderer Meinung.



Und was bieten sie uns, um die ständige Verfügbarkeit unserer Kubernetes-Anwendung zu erhöhen? Das erste, was in der inoffiziellen Dokumentation steht, ist, viele Maschinen zu platzieren, viele Master zu erstellen - ihre Anzahl muss die Bedingungen für das Erreichen eines Quorums innerhalb des Clusters erfüllen, und so wird etcd, api, MC, Scheduler auf jedem der Master ausgelöst ... Und anscheinend ist alles in Ordnung : Wenn mehrere Arbeitsknoten oder Master ausfallen, wird unser Cluster neu ausgeglichen und die Anwendung funktioniert weiterhin. Sieht wieder nach Magie aus! Oft befindet sich unser Cluster jedoch im selben Rechenzentrum, was zu bestimmten Fragen führen kann. Was ist, wenn ein Bagger ankam und ein Kabel ausgrub, blitzschnell, gab es eine universelle Flut? Alles ist abgedeckt, unser Cluster ist nicht mehr. Wie kann man sich der Reservierung unter Berücksichtigung dieser Seite des Problems nähern?

Zunächst sollten Sie einen anderen Cluster in der Hot Reserve haben, dh einen Cluster, zu dem Sie jederzeit wechseln können. In diesem Fall sollten die Infrastrukturen aus Sicht des Cuber völlig identisch sein. Das heißt, wenn es nicht standardmäßige Plugins für die Arbeit mit dem Dateisystem gibt, benutzerdefinierte Lösungen für Ingress, sollten diese auf Ihren zwei (oder drei oder zehn, es gibt genug Geld und Administratoren) Clustern vollständig identisch sein. Es müssen zwei Arten von Anwendungen klar definiert werden (Deployment'ov, Statefulset'ov, Daemonset'ov, Cronjob'ov usw.): Welche von ihnen können ständig an einer Reserve arbeiten und welche sollten besser nicht vor dem direkten Wechsel gestartet werden.

Sollte unser Backup-Cluster also vollständig mit unserem Kampf-Cluster identisch sein? Nein. Früher haben wir im Rahmen der Arbeit mit monolithischen Projekten mit Eiseninfrastruktur eine fast völlig identische Umgebung beibehalten, aber im Rahmen des Cuber denke ich, dass dies nicht sein sollte. Schauen wir uns an, warum.

Beginnen wir zum Beispiel mit den grundlegenden Entitäten von Kubernetes - Bereitstellungen - sie müssen identisch sein. Es sollten Anwendungen gestartet werden, die die Verkehrsverarbeitung jederzeit abfangen und es unserem Projekt ermöglichen, weiter zu leben. Wenn es sich um Konfigurationsdateien handelt, müssen wir hier prüfen, ob sie identisch sein sollten oder nicht. Das heißt, wenn wir, kluge Leute, keine verbotenen Substanzen verwenden und die Basis nicht in K8s behalten, müssen wir Zugriffseinstellungen in den Konfigurationskarten für die Kampfbasis haben (deren Sicherungsprozess separat erstellt wird). Um den Zugriff auf die Sicherungsdatenbankinstanz sicherzustellen, benötigen wir daher eine separate Konfigurationsdatei (configmap). Genau so arbeiten wir mit Geheimnissen: Passwörter für den Zugriff auf die Datenbank, API-Schlüssel; Zu jeder Zeit kann entweder ein Kampfgeheimnis oder eine Reserve mit uns zusammenarbeiten. Insgesamt haben wir bereits zwei Kubernetes-Entitäten, deren Backup-Versionen nicht mit den Kampfversionen identisch sein sollten. Die nächste Entität, die es wert ist, darüber nachzudenken, ist Cronjob. Cronjobs in Reserve sollten keinesfalls mit den Cronjob-Produktionsclustern identisch sein! Wenn wir den Sicherungscluster erhöhen und ihn vollständig aktivieren, während alle Cronjobs aktiviert sind, erhalten beispielsweise zwei Briefe gleichzeitig von Ihnen anstelle von einem. Oder eine Art Synchronisation von Daten mit externen Quellen findet zweimal statt, wir beginnen zu verletzen, zu weinen, zu schreien und zu schwören.



Aber wie bieten uns Leute aus dem Internet an, einen Backup-Cluster zu organisieren? Die zweitbeliebteste Antwort nach "Warum?" - Nutzung der Kubernetes Federation.

Was ist das? Dies ist beispielsweise ein großer Meta-Cluster. Wenn wir uns die Architektur des Cuber vorstellen - wo wir einen Master, mehrere Knoten haben - dann haben wir aus Sicht der Föderation auch einen Master und mehrere Knoten, nur jeder Knoten ist ein separater Cluster. Das heißt, wir arbeiten mit denselben Entitäten, mit denselben Grundelementen wie mit einem einzelnen Cuber, aber wir drehen und drehen nicht unsere physischen Maschinen, sondern ganze Cluster. Im Rahmen des Bundes sind wir in der vollständigen Synchronisation der Bundesressourcen von den Eltern zu den Nachkommen. Wenn wir beispielsweise eine Bereitstellung über den Verbund gestartet haben, wird diese in jedem unserer Tochtercluster bereitgestellt. Wenn wir eine Konfigurationskarte verwenden, besteht das Geheimnis darin, sie an den Verband weiterzuleiten - sie wird sich auf alle unsere untergeordneten Cluster ausbreiten. Gleichzeitig ermöglicht uns der Verband, unsere Ressourcen für Kinder anzupassen. Das heißt, wir haben eine Konfigurationskarte erstellt, diese über den Verbund bereitgestellt. Wenn wir dann etwas an bestimmten Clustern beheben müssen, bearbeiten wir sie in einem separaten Cluster, und diese Änderung wird nirgendwo synchronisiert.

Kubernetes Federation ist noch nicht so lange ein vorhandenes Tool und unterstützt nicht alle Ressourcen, die K8s selbst bereitstellt: Zum Zeitpunkt der Veröffentlichung einer der ersten Versionen der Dokumentation ging es darum, nur Konfigurationszuordnungen, Bereitstellung für Replikatsätze und Ingress zu unterstützen. Geheimnisse wurden nicht unterstützt, die Arbeit mit Volumen wurde ebenfalls nicht unterstützt. Zu begrenzter Satz. Insbesondere wenn wir Spaß haben möchten, beispielsweise durch die benutzerdefinierte Ressourcendefinition, um unsere eigenen Ressourcen auf die Kubernetes zu übertragen, werden wir sie nicht in den Verbund übertragen. Das heißt, sozusagen ... eine Entscheidung, die der Wahrheit sehr ähnlich ist, aber sie lässt uns regelmäßig in den Fuß schießen. Auf der anderen Seite können Sie mit dem Verband unser Replikatset flexibel verwalten. Beispielsweise möchten wir, dass 10 Replikate unserer Anwendung gestartet werden. Standardmäßig teilt der Verbund diese Anzahl proportional auf die Anzahl der Cluster auf. Und das alles kann auch konfiguriert werden! Das heißt, Sie können angeben, dass Sie 6 Replikate unserer Anwendung in einem Kampfcluster und nur 4 Replikate unserer Anwendung in einem Sicherungscluster aufbewahren müssen, um Ressourcen zu sparen oder zu Ihrer eigenen Unterhaltung. Welches ist auch sehr praktisch. Aber mit dem Verband müssen wir einige neue Lösungen verwenden, etwas unterwegs erledigen und uns zwingen, ein bisschen mehr nachzudenken ...

Ist es möglich, den Prozess der Buchung eines Cubers irgendwie einfacher anzugehen? Welche Werkzeuge haben wir überhaupt?

Erstens haben wir immer eine Art CD / CD-System, das heißt, wir gehen nicht manuell herum, schreiben nicht erstellen / anwenden auf den Servern. Das System erzeugt Yaml'ics für unsere Container.

Zweitens gibt es mehrere Cluster, wir haben entweder eine oder mehrere (wenn wir klug sind) Registrierungen, die wir auch genommen und reserviert haben. Und es gibt ein wunderbares kubectl-Dienstprogramm, das mit mehreren Clustern gleichzeitig arbeiten kann.



Also: Meiner Meinung nach ist die einfachste und korrekteste Lösung zum Erstellen eines Sicherungsclusters eine primitive parallele Bereitstellung. Es gibt eine Art Pipeline im ci / cd-System; Zuerst bauen wir unsere Container, testen und rollen Anwendungen über kubectl in mehreren unabhängigen Clustern aus. Wir können simultane Berechnungen für mehrere Cluster erstellen. Dementsprechend beschließen wir auch, in dieser Phase Konfigurationen zu liefern. Sie können die Konfigurationen für unseren Kampfcluster, die Konfigurationen für den Sicherungscluster vordefinieren und auf ci / cd-Ebene des Systems die Pro-Umgebung in den Pro-Cluster und die Sicherungsumgebung in den Sicherungscluster übertragen. Im Vergleich zum Verband müssen Sie nicht für jeden untergeordneten Cluster eine Bundesressource definieren und etwas neu definieren. Wir haben das im Voraus gemacht. Was für gute Leute wir sind.

Aber ... da ist ... ich schrieb, da ist die "Wurzel allen Übels", aber es gibt tatsächlich zwei davon. Das erste ist das Dateisystem. Es gibt eine Art PV, oder wir verwenden externen Speicher. Wenn wir Dateien im Cluster speichern, müssen wir die alten Praktiken befolgen, die aus der Zeit der Eiseninfrastrukturen übrig geblieben sind: Synchronisieren Sie beispielsweise mit lsync. Nun, oder jede andere Krücke, die Sie persönlich bevorzugen. Wir rollen alles zu anderen Autos und leben.

Zweitens und in der Tat ist die Datenbank ein noch wichtigerer Stolperstein. Wenn wir kluge Leute sind und die Datenbank nicht im Cube behalten, ist das Sichern von Daten nach demselben alten Schema die Master-Slave-Replikation und das Umschalten. Wir werden das Replikat einholen und gut leben. Wenn wir jedoch unsere Datenbank im Cluster behalten, gibt es im Prinzip viele vorgefertigte Lösungen zum Organisieren derselben Master-Slave-Replik, viele Lösungen zum Erhöhen der Datenbank im Cube.
Es wurden bereits eine Milliarde Berichte über Datenbanksicherungen gelesen, eine Milliarde Artikel wurden geschrieben, hier wird tatsächlich nichts Neues benötigt. Folgen Sie im Allgemeinen Ihrem Traum, leben Sie, wie Sie möchten, erfinden Sie auch einige komplizierte Krücken, aber denken Sie darüber nach, wie Sie all dies reservieren werden.

Und nun darüber, wie wir im Prinzip im Brandfall zum Backup-Standort wechseln müssen. Zunächst stellen wir zustandslose Anwendungen parallel bereit. Sie haben keinen Einfluss auf die Geschäftslogik unserer Anwendungen, unseres Projekts. Wir können ständig zwei Sätze laufender Anwendungen behalten und sie können anfangen, Datenverkehr zu empfangen. Beim Wechsel zur Sicherungssite ist es sehr wichtig zu prüfen, ob die Konfigurationen neu definiert werden müssen Zum Beispiel haben wir einen Kubernetes-Verkaufscluster, es gibt einen Backup-Kubernetes-Cluster, es gibt eine externe Master-Datenbank und es gibt eine Backup-Master-Datenbank. Wir haben vier Möglichkeiten, wie diese Anwendungen im Produkt miteinander interagieren können. Unsere Basis kann wechseln, und es stellt sich heraus, dass wir den Datenverkehr auf die neue Basis im Prod-Cluster umschalten müssen, oder wir können den Cluster abrufen und sind in die Reserve umgezogen, aber wir arbeiten weiterhin mit der Pro-Base, also der dritten Option, wenn wir sie erhalten haben Dann wird es vermasselt, und wir wechseln beide Anwendungen. Definieren Sie unsere Konfiguration neu, damit neue Anwendungen bereits mit der neuen Datenbank funktionieren.

Welche Schlussfolgerungen können aus all dem gezogen werden?



Die erste Schlussfolgerung: Mit einer Reserve gut leben. Aber teuer. Aber im Idealfall mit mehr als einer Reserve leben. Idealerweise müssen Sie in der Regel mit mehreren Reserven leben. Erstens sollte sich die Reserve mindestens nicht in einem DC befinden, und zweitens zumindest in einem anderen Hoster. Es ist oft passiert - und in meiner Praxis war es das auch. Leider kann ich die Projekte nicht benennen, gerade als es im Rechenzentrum einen Brand gab ... Ich bin so: Wir wechseln in die Reserve! Und Backup-Server im selben Rack standen ...

Oder stellen Sie sich vor, Amazon sei in Russland verboten worden (und das war es auch). Und alles: das Gefühl der Tatsache, dass in einem anderen Amazonas unsere Reserve liegt? Es ist auch nicht verfügbar. Also wiederhole ich: Wir behalten die Reserve zumindest in einem anderen DC und vorzugsweise bei einem anderen Host.

Die zweite Schlussfolgerung: Wenn Ihre Anwendung mit einigen externen Quellen kommuniziert (es kann sich entweder um eine Datenbank oder eine externe API handeln), müssen Sie sie als Dienst mit einem externen Endpunkt definieren, damit Sie sie zum Zeitpunkt des Wechsels nicht neu reparieren müssen 15 Ihrer Anwendungen, die auf derselben Basis klopfen. Definieren Sie die Datenbank als separaten Dienst, klopfen Sie darauf, als ob sie sich in Ihrem Cluster befindet: Wenn Sie eine Datenbank haben, ändern Sie die IP an einem Ort und leben weiterhin glücklich.

Und zum Schluss: Ich liebe den „Würfel“ und experimentiere damit. Ich teile auch gerne die Ergebnisse dieser Experimente und im Allgemeinen meine persönlichen Erfahrungen. Aus diesem Grund habe ich eine Reihe von Webinaren über K8s aufgezeichnet. Weitere Informationen finden Sie in unserem Youtube-Kanal .

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


All Articles