Tutorial

So richten Sie ReadWriteMany (RWX) Persistent Volumes mit NFS unter DigitalOcean Kubernetes ein

Block StorageKubernetesDigitalOcean Managed Kubernetes

Einführung

Aufgrund der verteilten und dynamischen Natur von Containern ist die statische Verwaltung und Konfiguration von Speicher in Kubernetes zu einem schwierigen Problem geworden, da Arbeitslasten jetzt in der Lage sind, innerhalb von Sekunden von einer virtuellen Maschine (VM) auf eine andere zu wechseln. Um dieses Problem zu lösen, verwaltet Kubernetes Volumes mit einem System aus Persistent Volumes (PV), API-Objekten, die eine Speicherkonfiguration/ein Volume darstellen, und PersistentVolumeClaims (PVC), einer Speicheranforderung, die von einem Persistent Volume erfüllt werden soll. Darüber hinaus können Container Storage Interface (CSI)-Treiber dazu beitragen, die Handhabung und Bereitstellung von Speicher für containerisierte Workloads zu automatisieren und zu verwalten. Diese Treiber sind für die Bereitstellung, das Einbinden, das Aufheben der Einbindung, das Entfernen und das Erstellen von Snapshots von Volumes verantwortlich.

Das digitalocean-csi integriert einen Kubernetes-Cluster mit dem Produkt DigitalOcean Block Storage. Damit kann ein Entwickler Blockspeicher-Volumes für containerisierte Anwendungen in Kubernetes dynamisch bereitstellen. Anwendungen können jedoch manchmal erfordern, dass Daten über mehrere Droplets hinweg persistent gespeichert und gemeinsam genutzt werden. Die Blockspeicher-CSI-Standardlösung von DigitalOcean ist nicht in der Lage, das gleichzeitige Einbinden eines Blockspeicher-Volumes in mehrere Droplets zu unterstützen. Dies bedeutet, dass es sich um eine ReadWriteOnce (RWO)-Lösung handelt, da das Volume auf einen Knoten beschränkt ist. Das Protokoll Network File System (NFS) hingegen unterstützt das Exportieren derselben Freigabe an viele Consumer. Dies wird ReadWriteMany (RWX) genannt, da viele Knoten das Volume als Read-Write einbinden können. Wir können daher einen NFS-Server innerhalb unseres Clusters verwenden, um Speicher bereitzustellen, der die zuverlässige Unterstützung von DigitalOcean Block Storage mit der Flexibilität von NFS-Freigaben nutzen kann.

In diesem Tutorial werden Sie die dynamische Bereitstellung für NFS-Volumes innerhalb eines DigitalOcean Kubernetes (DOKS)-Clusters, in dem die Exporte auf DigitalOcean Block-Speichervolumes gespeichert werden, konfigurieren. Anschließend werden Sie mehrere Instanzen einer Nginx-Demoanwendung bereitstellen und die gemeinsame Nutzung von Daten zwischen den einzelnen Instanzen testen.

Voraussetzungen

Bevor Sie mit diesem Leitfaden beginnen, benötigen Sie Folgendes:

  • Die auf Ihrem lokalen Rechner installierte Befehlszeilenschnittstelle kubectl. Mehr über die Installation und Konfiguration von kubectl können Sie der offiziellen Dokumentation entnehmen.

  • Einen DigitalOcean Kubernetes-Cluster, bei dem Ihre Verbindung standardmäßig als kubectl konfiguriert ist. Um einen Kubernetes-Cluster auf DigitalOcean zu erstellen, lesen Sie unseren Kubernetes-Schnellstart. Eine Anleitung zur Konfiguration von kubectl finden Sie unter dem Schritt Verbinden mit Ihrem Cluster, wenn Sie Ihren Cluster erstellen.

  • Den auf Ihrem lokalen Rechner installierten Helm-Paketmanager und das auf Ihrem Cluster installierte Tiller. Führen Sie dazu die Schritte 1 und 2 des Tutorials So installieren Sie Software auf Kubernetes Clustern mit dem Helm-Paketmanager aus.

Hinweis: Ab Helm Version 3.0 muss Tiller nicht mehr installiert werden, damit Helm funktioniert. Wenn Sie die neueste Version von Helm verwenden, finden Sie die Anweisungen in der Helm-Installationsdokumentation.

Schritt 1 – Bereitstellen des NFS-Servers mit Helm

Für die Bereitstellung des NFS-Servers verwenden Sie ein Helm Chart. Die Bereitstellung eines Helm Charts ist eine automatisierte Lösung, die schneller und weniger fehleranfällig ist als die manuelle Erstellung der NFS-Serverbereitstellung.

Stellen Sie zuerst sicher, dass das standardmäßige Chart-Repository stable verfügbar ist, indem Sie das Repo hinzufügen:

  • helm repo add stable https://kubernetes-charts.storage.googleapis.com/

Als Nächstes rufen Sie die Metadaten für das Repository ab, das Sie gerade hinzugefügt haben. Dadurch wird sichergestellt, dass der Helm-Client aktualisiert wird:

  • helm repo update

Um den Zugriff auf das Repo stable zu verifizieren, führen Sie eine Suche in den Charts aus:

  • helm search repo stable

Dadurch erhalten Sie eine Liste der verfügbaren Charts, ähnlich der folgenden:

Output
NAME CHART VERSION APP VERSION DESCRIPTION stable/acs-engine-autoscaler 2.2.2 2.1.1 DEPRECATED Scales worker nodes within agent pools stable/aerospike 0.3.2 v4.5.0.5 A Helm chart for Aerospike in Kubernetes stable/airflow 5.2.4 1.10.4 Airflow is a platform to programmatically autho... stable/ambassador 5.3.0 0.86.1 A Helm chart for Datawire Ambassador ...

Das Ergebnis bedeutet, dass Ihr Helm-Client ausgeführt wird und auf dem neuesten Stand ist.

Nachdem Helm nun eingerichtet ist, installieren Sie das Helm Chart nfs-server-provisioner, um den NFS-Server einzurichten. Wenn Sie den Inhalt des Charts untersuchen möchten, werfen Sie einen Blick in seine Dokumentation auf GitHub.

Wenn Sie das Helm-Chart bereitstellen, legen Sie einige Variablen für Ihren NFS-Server fest, um die Konfiguration für Ihre Anwendung weiter zu spezifizieren. Sie können auch andere Konfigurationsoptionen untersuchen und sie an die Bedürfnisse der Anwendung anpassen.

Verwenden Sie den folgenden Befehl, um das Helm-Chart zu installieren:

  • helm install nfs-server stable/nfs-server-provisioner --set persistence.enabled=true,persistence.storageClass=do-block-storage,persistence.size=200Gi

Dieser Befehl stellt einen NFS-Server mit den folgenden Konfigurationsoptionen bereit:

  • Fügt ein Persistent Volume für den NFS-Server mit dem Flag --set hinzu. Dadurch wird sichergestellt, dass alle gemeinsam genutzten NFS-Daten auch bei Pod-Neustarts persistent gespeichert sind.
  • Für die persistente Speicherung wird die Speicherklasse do-block-storage verwendet.
  • Stellt insgesamt 200Gi für den NFS-Server bereit, die in Exporte aufgeteilt werden können.

Hinweis: Die Option persistence.size bestimmt die Gesamtkapazität aller NFS-Volumes, die Sie bereitstellen können. Zum Zeitpunkt dieser Veröffentlichung unterstützen nur die DOKS Version 1.16.2-do.3 und spätere Versionen die Erweiterung von Volumes, sodass die Größenänderung dieses Volumes eine manuelle Aufgabe ist, wenn Sie eine frühere Version verwenden. Stellen Sie in diesem Fall sicher, dass Sie diese Größe im Hinblick auf Ihre zukünftigen Bedürfnisse einstellen.

Nachdem dieser Befehl abgeschlossen ist, erhalten Sie eine Ausgabe, die der folgenden ähnelt:

Output
NAME: nfs-server LAST DEPLOYED: Thu Feb 13 19:30:07 2020 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: The NFS Provisioner service has now been installed. A storage class named 'nfs' has now been created and is available to provision dynamic volumes. You can use this storageclass by creating a PersistentVolumeClaim with the correct storageClassName attribute. For example: --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: test-dynamic-volume-claim spec: storageClassName: "nfs" accessModes: - ReadWriteOnce resources: requests: storage: 100Mi

Um den von Ihnen bereitgestellten NFS-Server zu sehen, führen Sie den folgenden Befehl aus:

  • kubectl get pods

Dadurch wird Folgendes angezeigt:

Output
NAME READY STATUS RESTARTS AGE nfs-server-nfs-server-provisioner-0 1/1 Running 0 11m

Prüfen Sie als Nächstes die von Ihnen erstellte storageclass:

  • kubectl get storageclass

Sie erhalten eine Ausgabe, die der folgenden ähnelt:

Output
NAME PROVISIONER AGE do-block-storage (default) dobs.csi.digitalocean.com 90m nfs cluster.local/nfs-server-nfs-server-provisioner 3m

Sie haben nun einen NFS-Server sowie einen storageclass, die Sie für die dynamische Bereitstellung von Volumes verwenden können. Als Nächstes können Sie eine Bereitstellung erstellen, die diesen Speicher verwendet, und ihn über mehrere Instanzen hinweg gemeinsam nutzen.

Schritt 2 – Bereitstellen einer Anwendung unter Verwendung eines gemeinsam genutzten PersistentVolumeClaim

In diesem Schritt erstellen Sie eine beispielhafte Bereitstellung auf Ihrem DOKS-Cluster, um Ihre Speichereinrichtung zu testen. Dies wird eine Nginx Webserver-Anwendung namens web sein.

Um diese Anwendung bereitzustellen, schreiben Sie zunächst die YAML-Datei, um die Bereitstellung zu spezifizieren. Öffnen Sie eine Datei nginx-test.yaml mit Ihrem Texteditor; dieses Tutorial verwendet nano:

  • nano nginx-test.yaml

Fügen Sie in diese Datei die folgenden Zeilen ein, um die Bereitstellung mit einem PersistentVolumeClaim namens nfs-data zu definieren:

nginx-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        resources: {}
        volumeMounts:
        - mountPath: /data
          name: data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: nfs-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-data
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
  storageClassName: nfs

Speichern Sie die Datei und beenden Sie den Texteditor.

Diese Bereitstellung ist so konfiguriert, dass sie die zugehörigen PersistentVolumeClaim nfs-data verwendet und sie unter /data einbindet.

In der PVC-Definition werden Sie feststellen, dass der storageClassName auf nfs gesetzt ist. Damit wird dem Cluster mitgeteilt, dass er diese Speicherung nach den Regeln der nfs storageClass, die Sie im vorherigen Schritt erstellt haben, erfüllen muss. Der neue PersistentVolumeClaim wird verarbeitet und dann wird eine NFS-Freigabe bereitgestellt, um den Anspruch in Form eines Persistent Volumes zu erfüllen. Der Pod wird versuchen, dieses PVC einzubinden, sobald es bereitgestellt wurde. Nach dem Einbinden verifizieren Sie die Funktionalität ReadWriteMany (RWX).

Führen Sie die Bereitstellung mit dem folgenden Befehl aus:

  • kubectl apply -f nginx-test.yaml

Dadurch erhalten Sie folgende Ausgabe:

Output
deployment.apps/web created persistentvolumeclaim/nfs-data created

Als Nächstes prüfen Sie, ob der Pod web anläuft:

  • kubectl get pods

Dadurch wird Folgendes ausgegeben:

Output
NAME READY STATUS RESTARTS AGE nfs-server-nfs-server-provisioner-0 1/1 Running 0 23m web-64965fc79f-b5v7w 1/1 Running 0 4m

Nachdem nun die Beispielbereitstellung läuft, können Sie sie mit dem Befehl kubectl scale auf drei Instanzen skalieren:

  • kubectl scale deployment web --replicas=3

Dadurch erhalten Sie folgende Ausgabe:

Output
deployment.extensions/web scaled

Führen Sie nun den Befehl kubectl get erneut aus:

  • kubectl get pods

Sie finden die skalierten Instanzen der Bereitstellung:

Output
NAME READY STATUS RESTARTS AGE nfs-server-nfs-server-provisioner-0 1/1 Running 0 24m web-64965fc79f-q9626 1/1 Running 0 5m web-64965fc79f-qgd2w 1/1 Running 0 17s web-64965fc79f-wcjxv 1/1 Running 0 17s

Sie haben nun drei Instanzen Ihrer Nginx-Bereitstellung, die mit demselben Persistent Volume verbunden sind. Im nächsten Schritt stellen Sie sicher, dass sie Daten untereinander gemeinsam nutzen können.

Schritt 3 – Validieren der gemeinsamen Nutzung von NFS-Daten

Im letzten Schritt überprüfen Sie, ob die Daten von allen Instanzen, die in die NFS-Freigabe eingebunden sind, gemeinsam genutzt werden. Dazu erstellen Sie eine Datei im Verzeichnis /data in einem der Pods und verifizieren dann, ob die Datei in dem Verzeichnis /data eines anderen Pods vorhanden ist.

Um dies zu validieren, verwenden Sie den Befehl kubectl exec. Mit diesem Befehl können Sie einen Pod angeben und einen Befehl innerhalb dieses Pods ausführen. Um mehr über die Überprüfung von Ressourcen unter Verwendung von kubectl zu erfahren, werfen Sie einen Blick auf unseren kubectl-Spickzettel.

Um innerhalb eines Ihrer Pods web eine Datei namens hello_world zu erstellen, verwenden Sie den Befehl kubectl exec, um den Befehl touch weiterzugeben. Beachten Sie, dass die Zahl nach web im Pod-Namen für Sie unterschiedlich sein wird. Achten Sie also darauf, den hervorgehobenen Pod-Namen durch einen Ihrer eigenen Pods zu ersetzen, die Sie im letzten Schritt als Ausgabe von kubectl get pods gefunden haben.

  • kubectl exec web-64965fc79f-q9626 -- touch /data/hello_world

Ändern Sie dann den Namen des Pod und verwenden Sie den Befehl ls, um die Dateien im Verzeichnis /data eines anderen Pods aufzulisten:

  • kubectl exec web-64965fc79f-qgd2w -- ls /data

Ihre Ausgabe zeigt die Datei an, die Sie im ersten Pod erstellt haben:

Output
hello_world

Dies zeigt, dass alle Pods Daten über NFS gemeinsam nutzen und dass Ihre Einrichtung korrekt funktioniert.

Zusammenfassung

In diesem Tutorial haben Sie einen NFS-Server erstellt, der durch DigitalOcean Block Storage unterstützt wurde. Der NFS-Server verwendete dann diesen Blockspeicher zur Bereitstellung und zum Export von NFS-Freigaben für Workloads in einem RWX-kompatiblen Protokoll. Auf diese Weise konnten Sie eine technische Beschränkung der Blockspeicherung von DigitalOcean umgehen und dieselben PVC-Daten über viele Pods hinweg gemeinsam nutzen. Durch dieses Tutorial ist Ihr DOKS-Cluster nun so eingerichtet, dass er eine wesentlich größere Anzahl von Anwendungsfällen für die Bereitstellung unterstützt.

Wenn Sie mehr über Kubernetes erfahren möchten, sehen Sie sich unser Curriculum für Full-Stack-Entwickler oder die Produktdokumentation für DigitalOcean Kubernetes an.

Creative Commons License