Kubernetes Speichermuster


Hallo Habr!

Wir erinnern Sie daran, dass wir ein weiteres äußerst interessantes und nützliches Buch über Kubernetes-Muster veröffentlicht haben. Alles begann mit Brendan Burns ' Patterns “, und die Arbeit in diesem Segment ist übrigens in vollem Gange . Heute laden wir Sie ein, einen Artikel aus dem MinIO-Blog zu lesen, der die Trends und Besonderheiten der Datenspeichermuster in Kubernetes zusammenfasst.


Kubernetes hat die traditionellen Muster der Anwendungsentwicklung und -bereitstellung grundlegend geändert. Jetzt kann das Team Tage brauchen, um die Anwendung zu entwickeln, zu testen und bereitzustellen - in verschiedenen Umgebungen und all dies innerhalb der Kubernetes-Cluster. Solche Arbeiten mit Technologien früherer Generationen dauerten normalerweise Wochen, wenn nicht Monate.

Eine solche Beschleunigung wurde durch die von Kubernetes bereitgestellte Abstraktion ermöglicht - das heißt, dass Kubernetes selbst mit Details auf niedriger Ebene von physischen oder virtuellen Maschinen interagiert und es Benutzern ermöglicht, unter anderem den gewünschten Prozessor, den erforderlichen Speicher und die Anzahl der Containerinstanzen zu deklarieren. Da Kubernetes von einer riesigen Community unterstützt wird und der Umfang von Kubernetes ständig erweitert wird, führt es bei allen Container-Orchestrierungsplattformen mit großem Abstand.

Mit der zunehmenden Verwendung von Kubernetes wächst auch die Verwirrung über die darin verwendeten Speichermuster .

Bei der allgemeinen Konkurrenz um ein Stück Kubernetes-Kuchen (dh zur Datenspeicherung) ertrinkt das Signal in lautem Rauschen, wenn es um Datenspeicherung geht.
Kubernetes verkörpert ein modernes Modell für die Entwicklung, Bereitstellung und Verwaltung von Anwendungen. Ein solches modernes Modell trennt die Datenspeicherung von der Datenverarbeitung. Um diese Trennung im Kontext von Kubernetes vollständig zu verstehen, müssen Sie auch verstehen, was statusbehaftete und zustandslose Anwendungen sind und wie Datenspeicherung damit kombiniert wird. Hier hat der von S3 verwendete REST-API-Ansatz klare Vorteile gegenüber dem für andere Lösungen typischen POSIX / CSI-Ansatz.

In diesem Artikel werden wir über Speichermuster in Kubernetes sprechen und die Debatte über staatsichere und zustandslose Anwendungen separat diskutieren, damit wir den Unterschied zwischen ihnen und warum es wichtig ist, klar verstehen können. Im weiteren Verlauf des Textes werden Anwendungen und die darin verwendeten Datenspeichermuster im Lichte der Best Practices für die Arbeit mit Containern und Kubernetes betrachtet.

Staatenlose Container


Container sind von Natur aus leicht und kurzlebig. Sie können einfach gestoppt, gelöscht oder auf einem anderen Knoten bereitgestellt werden - dies dauert nur wenige Sekunden. In einem Orchestrierungssystem für große Container finden solche Vorgänge kontinuierlich statt, und Benutzer bemerken solche Änderungen nicht einmal. Bewegungen sind jedoch nur möglich, wenn der Container keine Abhängigkeiten von dem Knoten aufweist, auf dem er sich befindet. Diese Behälter sollen ohne staatliche Erhaltung funktionieren .

Stateful Container


Wenn der Container Daten auf lokal verbundenen Geräten (oder auf einem Blockgerät) speichert, muss das Data Warehouse, auf dem er sich befindet, zusammen mit dem Container selbst auf einen neuen Knoten verschoben werden - im Fehlerfall. Dies ist wichtig, da sonst die im Container ausgeführte Anwendung nicht ordnungsgemäß funktionieren kann, da sie auf Daten zugreifen muss, die auf lokalen Medien gespeichert sind. Diese Behälter sollen zustandsbehaftet sein .

Aus rein technischer Sicht können Stateful Container auch auf andere Knoten verschoben werden. In der Regel wird dies mithilfe verteilter Dateisysteme oder Blocknetzwerkspeichern erreicht, die an alle Knoten angeschlossen sind, auf denen Container ausgeführt werden. Auf diese Weise erhalten Container Zugriff auf Volumes zur dauerhaften Datenspeicherung, und Informationen werden auf Datenträgern im gesamten Netzwerk gespeichert. Ich werde eine solche Methode als " zustandserhaltenden Container-Ansatz " bezeichnen, und im Rest des Artikels werde ich sie aus Gründen der Einheitlichkeit nennen.



Bei einem typischen Stateful-Container-Ansatz werden alle Anwendungs-Pods an ein verteiltes Dateisystem angehängt. Es wird eine Art gemeinsamer Speicher erhalten, in dem alle Anwendungsdaten erfasst werden. Während einige Variationen möglich sind, ist dies ein Ansatz auf hoher Ebene.

Schauen wir uns nun an, warum der Stateful-Container-Ansatz in der Cloud-basierten Welt Antipattern ist.

Cloud-basiertes Anwendungsdesign


Traditionell verwendeten Anwendungen Datenbanken zur strukturierten Speicherung von Informationen und lokalen Datenträgern oder verteilten Dateisystemen, in denen alle unstrukturierten oder sogar halbstrukturierten Daten gespeichert wurden. Als das Volumen unstrukturierter Daten zunahm, stellten die Entwickler fest, dass POSIX zu gesprächig war, mit erheblichen Kosten verbunden war und letztendlich die Anwendung störte, wenn es zu einem wirklich großen Umfang überging.

Dies trug hauptsächlich zur Entstehung eines neuen Standards für die Datenspeicherung bei, dh Cloud-basierte Speicher, die hauptsächlich auf der Basis der REST-API arbeiten und die Anwendung von der aufwändigen Wartung des lokalen Data Warehouse befreien. In diesem Fall wechselt die Anwendung tatsächlich in den Betriebsmodus, ohne den Status zu speichern (da sich der Status im Remotespeicher befindet). Moderne Anwendungen werden bereits unter Berücksichtigung dieses Faktors von Grund auf neu erstellt. In der Regel basiert jede moderne Anwendung, die Daten der einen oder anderen Art (Protokolle, Metadaten, Blobs usw.) verarbeitet, auf einem Cloud-orientierten Paradigma, bei dem der Status an ein speziell für seine Speicherung zugewiesenes Softwaresystem übertragen wird.

Ein Stateful-Container-Ansatz lässt dieses ganze Paradigma genau dahin zurückrollen, wo es begonnen hat!

Bei Verwendung von POSIX-Schnittstellen zum Speichern von Daten funktionieren Anwendungen so, als ob sie den Status beibehalten würden, und weichen daher von den wichtigsten Postulaten des Cloud-basierten Designs ab, dh von der Möglichkeit, die Größe der Anwendungsworkflows je nach Eingang zu variieren Laden Sie, wechseln Sie zu einem neuen Knoten, sobald der aktuelle Knoten ausfällt, und so weiter.

Ein genauerer Blick auf diese Situation zeigt, dass wir bei der Auswahl eines Data Warehouse immer wieder vor dem Dilemma „POSIX versus REST API“ stehen, ABER mit einer zusätzlichen Verschärfung der POSIX-Probleme, die durch die verteilte Natur von Kubernetes-Umgebungen verursacht werden. Insbesondere,

  • POSIX : POSIX , . , . API , , S3 API, , , «» . , . .
  • : , , . , , ( ), , . - POSIX . , S3 API , , , .
  • : POSIX : . - . , API, , , ..
  • : , . , , , . , , , .


Während die Container Data Storage Interface (CSI) bei der Verteilung des Kubernetes-Volumens sehr hilfreich war und diese teilweise an Drittanbieter von Data Warehouse weitergab, trug sie versehentlich dazu bei, dass der Stateful Container-Ansatz die empfohlene Methode zur Datenspeicherung in Kubernetes war.

CSI wurde als Standard für die Bereitstellung beliebiger Block- und Dateispeichersysteme für Legacy-Anwendungen bei der Arbeit mit Kubernetes entwickelt. Und wie in diesem Artikel gezeigt wurde, ist die einzige Situation, in der ein Stateful-Container-Ansatz (und CSI in seiner aktuellen Form) angemessen ist, wenn die Anwendung selbst ein Legacy-System ist, in dem es unmöglich ist, Unterstützung für die Objektdatenspeicher-API hinzuzufügen.

Es ist wichtig zu verstehen, dass bei Verwendung von CSI in der aktuellen Form, dh beim Mounten von Volumes bei der Arbeit mit modernen Anwendungen, ungefähr dieselben Probleme auftreten wie bei Systemen, bei denen die Datenspeicherung im POSIX-Stil organisiert ist.

Besserer Ansatz


In diesem Fall ist es wichtig zu verstehen, dass die meisten Anwendungen von Natur aus nicht speziell für Arbeiten mit oder ohne Zustandserhaltung geschärft werden. Dieses Verhalten hängt von der Gesamtarchitektur des Systems und von den spezifischen Optionen ab, die während des Entwurfs ausgewählt wurden. Lassen Sie uns ein wenig über zustandsbehaftete Anwendungen sprechen.

Grundsätzlich können alle Anwendungsdaten in mehrere große Typen unterteilt werden:

  • Logdaten
  • Zeitstempeldaten
  • Transaktionsdaten
  • Metadaten
  • Containerbilder
  • Blob-Daten (Blobs)

Alle diese Datentypen werden auf modernen Datenspeicherplattformen sehr gut unterstützt, und es gibt mehrere Cloud-basierte Plattformen, die für die Bereitstellung von Daten in jedem dieser spezifischen Formate angepasst sind. Beispielsweise können sich Transaktionsdaten und Metadaten in einer modernen Cloud-basierten Datenbank wie CockroachDB, YugaByte usw. befinden. Container-Images oder Blob-Daten können in der Docker-Registrierung basierend auf MinIO gespeichert werden. Zeitstempeldaten können in einer Zeitreihendatenbank wie InfluxDB usw. gespeichert werden. Wir werden nicht auf Details der einzelnen Datentypen und verwandten Anwendungen eingehen, aber die allgemeine Idee besteht darin, eine dauerhafte Datenspeicherung auf der Grundlage der lokalen Festplattenmontage zu vermeiden.



Darüber hinaus ist es häufig effektiv, eine temporäre Caching-Schicht bereitzustellen, die als eine Art temporärer Dateispeicher für Anwendungen dient. Anwendungen sollten jedoch nicht von dieser Ebene als Quelle der Wahrheit abhängen.

Stateful Application Storage


Während es in den meisten Fällen nützlich ist, Anwendungen zustandslos zu halten, sollten Anwendungen, die zum Speichern von Daten bestimmt sind, z. B. Datenbanken, Objektspeicher, Schlüssel- und Wertspeicher, den Status beibehalten. Mal sehen, warum diese Anwendungen auf Kubernetes bereitgestellt werden. Nehmen Sie als Beispiel MinIO, aber ähnliche Prinzipien gelten auch für andere große Cloud-basierte Speichersysteme.

Cloud-zentrierte Anwendungen wurden entwickelt, um die Flexibilität der Container zu maximieren. Dies bedeutet, dass sie keine Annahmen über die Umgebung treffen, in der sie bereitgestellt werden. Beispielsweise verwendet MinIO einen internen Löschcodierungsmechanismus, der dem System eine ausreichende Stabilität bietet, sodass es auch dann betriebsbereit bleibt, wenn die Hälfte der Laufwerke ausfällt. MinIO verwaltet auch die Datenintegrität und -sicherheit mithilfe seines eigenen serverseitigen Hashings und seiner eigenen Verschlüsselung.

Für solche Cloud-basierten Anwendungen sind lokale persistente Volumes (PV) als Backup-Speicher am bequemsten. Lokale PV bietet die Möglichkeit, Rohdaten zu speichern, während Anwendungen, die auf diesen PVs ausgeführt werden, unabhängig voneinander Informationen sammeln, um Daten zu skalieren und wachsende Datenanforderungen zu verwalten.

Dieser Ansatz ist viel einfacher und wesentlich besser skalierbar als CSI-basierte PV, die dem System ein eigenes Maß an Datenverwaltung und Redundanz verleihen. Tatsache ist, dass diese Ebenen normalerweise im Widerspruch zu Anwendungen stehen, die nach dem Prinzip der staatlichen Bewahrung konzipiert sind.

Zuversichtlich, Daten aus dem Computing zu entfernen


In diesem Artikel haben wir darüber gesprochen, wie Anwendungen neu ausgerichtet werden, um zu funktionieren, ohne den Status zu speichern, oder mit anderen Worten, die Datenspeicherung wird von der Berechnung auf ihnen begrenzt. Betrachten Sie abschließend einige Beispiele aus der Praxis für einen solchen Trend.

Spark , die bekannte Datenanalyseplattform, wurde traditionell für die zustandsbehaftete Bereitstellung und Bereitstellung im HDFS-Dateisystem verwendet. Mit dem Übergang von Spark zu einer Cloud-basierten Welt wird diese Plattform jedoch zunehmend ohne Zustandserhaltung mit "s3a" verwendet. Spark verwendet s3a, um den Status auf andere Systeme zu übertragen, während Spark-Container selbst vollständig ohne Statuserhaltung arbeiten. Andere große Unternehmen im Bereich der Big-Data-Analyse, insbesondere Vertica , Teradata, Greenplum geht auch mit der Aufteilung der Datenspeicherung zu arbeiten und die Berechnung über sie.

Ähnliche Muster sind auch auf anderen großen Analyseplattformen zu sehen, einschließlich Presto, Tensorflow to R, Jupyter. Das Hochladen des Status auf Remote-Cloud-Speichersysteme erleichtert die Verwaltung und Skalierung Ihrer Anwendung erheblich. Darüber hinaus unterstützt es die Portabilität der Anwendung auf eine Vielzahl von Umgebungen.

All Articles