Speichern von Daten in einem Kubernetes-Cluster

Es gibt mehrere Möglichkeiten, die Datenspeicherung für Anwendungen zu konfigurieren, die auf einem Kubernetes-Cluster ausgeführt werden. Einige davon sind bereits veraltet, andere sind erst vor kurzem erschienen. In diesem Artikel betrachten wir das Konzept von drei Möglichkeiten zur Anbindung von Speichersystemen, darunter die jüngste – die Anbindung über das Container Storage Interface.

Speichern von Daten in einem Kubernetes-Cluster

Methode 1: Geben Sie PV im Pod-Manifest an

Ein typisches Manifest, das einen Pod in einem Kubernetes-Cluster beschreibt:

Speichern von Daten in einem Kubernetes-Cluster

Die Teile des Manifests, die beschreiben, welches Volume verbunden ist und wo, werden farblich hervorgehoben.

Im Abschnitt volumeMounts Geben Sie die Mount-Punkte (mountPath) an – in welches Verzeichnis innerhalb des Containers das permanente Volume gemountet wird, sowie den Namen des Volumes.

Im Abschnitt x listet alle Volumes auf, die im Pod verwendet werden. Geben Sie den Namen jedes Volumes sowie den Typ (in unserem Fall: awsElasticBlockStore) und die Verbindungsparameter an. Welche Parameter im Manifest aufgeführt sind, hängt vom Volume-Typ ab.

Das gleiche Volumen kann gleichzeitig in mehreren Pod-Containern montiert werden. Auf diese Weise können unterschiedliche Anwendungsprozesse auf dieselben Daten zugreifen.

Diese Verbindungsmethode wurde ganz am Anfang erfunden, als Kubernetes noch in den Kinderschuhen steckte, und heute ist die Methode veraltet.

Bei der Verwendung treten mehrere Probleme auf:

  1. alle Volumes müssen manuell erstellt werden; Kubernetes kann nichts für uns erstellen;
  2. Zugriffsparameter für jedes Volume sind eindeutig und müssen in den Manifesten aller Pods angegeben werden, die das Volume verwenden.
  3. Um das Speichersystem zu ändern (z. B. von AWS zu Google Cloud zu wechseln), müssen Sie die Einstellungen und den Typ der bereitgestellten Volumes in allen Manifesten ändern.

All dies ist sehr umständlich, daher wird diese Methode in Wirklichkeit nur zum Verbinden einiger spezieller Volume-Typen verwendet: configMap, Secret, emptyDir, hostPath:

  • configMap und Secret sind Service-Volumes, mit denen Sie ein Volume mit Dateien aus Kubernetes-Manifesten im Container erstellen können.

  • emptyDir ist ein temporäres Volume, das nur für die Lebensdauer des Pods erstellt wird. Praktisch zum Testen oder Speichern temporärer Daten. Wenn ein Pod gelöscht wird, wird auch das emptyDir-Volume gelöscht und alle Daten gehen verloren.

  • hostPath – ermöglicht Ihnen das Mounten eines beliebigen Verzeichnisses auf der lokalen Festplatte des Servers, auf dem die Anwendung innerhalb des Containers mit der Anwendung ausgeführt wird, einschließlich /etc/kubernetes. Da es sich hierbei um eine unsichere Funktion handelt, verbieten Sicherheitsrichtlinien in der Regel die Verwendung von Volumes dieses Typs. Andernfalls kann die Anwendung eines Angreifers das HTC Kubernetes-Verzeichnis in seinem Container bereitstellen und alle Cluster-Zertifikate stehlen. Normalerweise dürfen hostPath-Volumes nur von Systemanwendungen verwendet werden, die im kube-system-Namespace ausgeführt werden.

Speichersysteme, mit denen Kubernetes sofort funktioniert sind in der Dokumentation angegeben.

Methode 2. Anschluss an SC/PVC/PV-Feuerstellen

Eine alternative Verbindungsmethode ist das Konzept der Storage-Klasse, PersistentVolumeClaim, PersistentVolume.

Lagerklasse speichert Verbindungsparameter zum Datenspeichersystem.

PersistentVolumeClaim beschreibt die Anforderungen für das, was die Anwendung benötigt.
PersistentVolume Speichert Zugriffsparameter und Volume-Status.

Der Kern der Idee: Im Pod-Manifest geben sie ein Volume vom Typ PersistentVolumeClaim an und geben den Namen dieser Entität im Parameter ClaimName an.

Speichern von Daten in einem Kubernetes-Cluster

Das PersistentVolumeClaim-Manifest beschreibt die Anforderungen an das Datenvolumen, das die Anwendung benötigt. Einschließlich:

  • Festplattengröße;
  • Zugriffsmethode: ReadWriteOnce oder ReadWriteMany;
  • Link zur Speicherklasse – in welchem ​​Datenspeichersystem wir das Volume erstellen möchten.

Das Speicherklassenmanifest speichert den Typ und die Parameter der Verbindung zum Speichersystem. Das Cubelet benötigt sie, um das Volume auf seinem Knoten bereitzustellen.

PersistentVolume-Manifeste geben die Speicherklasse und Zugriffsparameter für ein bestimmtes Volume an (Volume-ID, Pfad usw.).

Beim Erstellen eines PVC prüft Kubernetes, welche Volume-Größe und welche Speicherklasse erforderlich sind, und wählt ein kostenloses PersistentVolume aus.

Wenn solche PVs nicht verfügbar sind, kann Kubernetes ein spezielles Programm starten – Provisioner (sein Name ist in der Storage-Klasse angegeben). Dieses Programm stellt eine Verbindung zum Speichersystem her, erstellt ein Volume mit der erforderlichen Größe, empfängt eine Kennung und erstellt ein PersistentVolume-Manifest im Kubernetes-Cluster, das dem PersistentVolumeClaim zugeordnet ist.

Mit all diesen Abstraktionen können Sie Informationen darüber, mit welchem ​​Speichersystem die Anwendung arbeitet, von der Anwendungsmanifestebene auf die Verwaltungsebene entfernen.

Alle Parameter für die Verbindung zum Datenspeichersystem befinden sich in der Storage-Klasse, für die Cluster-Administratoren verantwortlich sind. Beim Wechsel von AWS zu Google Cloud müssen Sie lediglich den Namen der Storage-Klasse in den Anwendungsmanifesten in PVC ändern. Persistenzvolume für die Datenspeicherung werden im Cluster mithilfe des Provisioner-Programms automatisch erstellt.

Methode 3: Containerspeicherschnittstelle

Der gesamte Code, der mit verschiedenen Speichersystemen interagiert, ist Teil des Kubernetes-Kerns. Die Veröffentlichung von Fehlerbehebungen oder neuen Funktionen ist an neue Releases gebunden; der Code muss für alle unterstützten Versionen von Kubernetes geändert werden. All dies ist schwierig zu warten und neue Funktionen hinzuzufügen.

Um das Problem zu lösen, haben Entwickler von Cloud Foundry, Kubernetes, Mesos und Docker das Container Storage Interface (CSI) erstellt – eine einfache einheitliche Schnittstelle, die das Zusammenspiel des Container-Management-Systems und eines speziellen Treibers (CSI Driver) beschreibt, der mit einem bestimmten Speichersystem. Der gesamte Code für die Interaktion mit Speichersystemen wurde vom Kubernetes-Kern auf ein separates System verschoben.

Dokumentation zur Containerspeicherschnittstelle.

Normalerweise besteht der CSI-Treiber aus zwei Komponenten: dem Node-Plugin und dem Controller-Plugin.

Das Node Plugin wird auf jedem Knoten ausgeführt und ist für das Mounten von Volumes und das Durchführen von Vorgängen auf ihnen verantwortlich. Das Controller-Plugin interagiert mit dem Speichersystem: erstellt oder löscht Volumes, weist Zugriffsrechte zu usw.

Die alten Treiber verbleiben vorerst im Kubernetes-Kernel, es wird jedoch nicht mehr empfohlen, sie zu verwenden, und es wird jedem empfohlen, den CSI-Treiber speziell für das System zu installieren, mit dem sie funktionieren.

Die Innovation mag diejenigen abschrecken, die es bereits gewohnt sind, die Datenspeicherung über die Storage-Klasse einzurichten, aber tatsächlich ist nichts Schlimmes passiert. Für Programmierer ändert sich eigentlich nichts – sie haben nur mit dem Namen Storage-Klasse gearbeitet und werden dies auch weiterhin tun. Für Administratoren wurde die Helmkarteninstallation hinzugefügt und die Struktur der Einstellungen geändert. Wurden die Einstellungen bisher direkt in der Storage-Klasse eingegeben, müssen sie jetzt zunächst im Helm-Chart und dann in der Storage-Klasse festgelegt werden. Wenn man sich das ansieht, ist nichts Schlimmes passiert.

Sehen wir uns anhand eines Beispiels an, welche Vorteile Sie durch die Umstellung auf die Anbindung von Ceph-Speichersystemen über den CSI-Treiber erzielen können.

Bei der Arbeit mit Ceph bietet das CSI-Plugin mehr Optionen für die Arbeit mit Speichersystemen als integrierte Treiber.

  1. Dynamische Festplattenerstellung. Normalerweise werden RBD-Festplatten nur im RWO-Modus verwendet, aber CSI für Ceph ermöglicht die Verwendung im RWX-Modus. Mehrere Pods auf verschiedenen Knoten können dieselbe RDB-Festplatte auf ihren Knoten bereitstellen und parallel mit ihnen arbeiten. Fairerweise muss man sagen, dass nicht alles so hell ist – diese Festplatte kann nur als Blockgerät angeschlossen werden, was bedeutet, dass Sie die Anwendung anpassen müssen, um damit im Mehrfachzugriffsmodus zu arbeiten.
  2. Schnappschüsse erstellen. In einem Kubernetes-Cluster können Sie ein Manifest mit der Anforderung erstellen, einen Snapshot zu erstellen. Das CSI-Plugin erkennt es und erstellt einen Schnappschuss von der Festplatte. Darauf basierend können Sie entweder ein Backup oder eine Kopie von PersistentVolume erstellen.
  3. Erhöhen der Festplattengröße auf Speicher und PersistentVolume in einem Kubernetes-Cluster.
  4. Quoten. Die in Kubernetes integrierten CephFS-Treiber unterstützen keine Kontingente, aber neue CSI-Plugins mit dem neuesten Ceph Nautilus können Kontingente auf CephFS-Partitionen aktivieren.
  5. Metriken. Das CSI-Plugin kann Prometheus verschiedene Messwerte darüber liefern, welche Volumes verbunden sind, welche Kommunikation stattfindet usw.
  6. Topologiebewusst. Ermöglicht Ihnen, in Manifesten anzugeben, wie der Cluster geografisch verteilt ist, und zu vermeiden, dass ein Speichersystem in Amsterdam mit Pods verbunden wird, die in London ausgeführt werden.

Informationen zum Verbinden von Ceph mit einem Kubernetes-Cluster über CSI finden Sie unter im praktischen Teil der Slurm-Abendvorlesung. Sie können es auch abonnieren Ceph-Videokurs, das am 15. Oktober startet.

Autor des Artikels: Sergey Bondarev, praktizierender Architekt bei Southbridge, zertifizierter Kubernetes-Administrator, einer der Entwickler von Kubespray.

Ein kleines Post Scriptum, nicht zur Werbung, sondern zum Nutzen...

PS Sergey Bondarev leitet zwei Intensivkurse: aktualisiert Kubernetes-Basis 28.–30. September und Fortgeschrittene Kubernetes Mega 14.–16. Oktober.

Speichern von Daten in einem Kubernetes-Cluster

Source: habr.com

Kommentar hinzufügen