Kubernetes Daten auf einer NFS-Freigabe speichern

In diesem Artikel geht es kurz darum, wie wir Daten aus unserem Kubernetes-Cluster auf einer NFS-Freigabe speichern können.

Wichtig: Stelle bitte sicher, dass auf jedem Node das Paket nfs-common installiert ist.

Durchführung

Helm Installation

Im ersten Schritt muss auf dem Master Node der Helm Paketmanager installiert werden. Dazu müssen wir den folgenden Befehl ausführen:

curl -L https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

Wir können dann im Anschluss mit dem folgenden Befehl überprüfen ob die Installation erfolgreich durchgeführt wurde:

helm version

Installation vom NFS-Provisioner

In diesem Schritt installieren wir den nfs-subdir-external-provisioner. Dies ist eine Speicherklasse, um den NFS-Speicher in das Kubernetes-Cluster einzubinden. Kubernetes bietet von Haus aus keine Möglichkeit an NFS-Speicher anzubinden. Um die Installation durchzuführen und einen dedizierten Namespace zu erstellen, müssen die folgenden Befehle ausgeführt werden:

helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
kubectl create namespace nfs-provisioner

Starten des NFS-Provisioner Pods

In diesem Schritt starten wir den Pod für den NFS-Provisioner. Dazu passen wir noch die Serveradresse und den Pfad unserer NFS-Freigabe an.

helm install nfs-client nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --set nfs.server=<server-adresse> --set nfs.path=<freigabe-pfad> --namespaces <namespace-name>

Anlegen der Manifest-Dateien für den Storage

Im nächsten Schritt erstellen wir eine YAML-Datei für das „PersistentVolume“. Diese enthält den folgenden Inhalt:

apiVersion: v1
kind: PersistentVolume
metadata: 
  name: nfs-pv
  namespace: nfs-storage
spec:
  capacity:
    storage: <größe> (z.B. 450Gi)
  accessModes:
    - ReadWriteMany
  nfs:
    server: <server-adresse>
    path: <freigabe-pfad>

Und im Anschluss legen wir die Manifest-Datei für den „PersistentVolumeClaim“ an. Diese enthält die Größe unserer Webanwendung.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
  namespace: nfs-storage
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: <größe>

Info zu PV und PVC: Ein PV wird vom Administrator definiert und präsentiert das Speichermedium (Speicher Backend) und das PVC stellt die Anfrage vom Pod an den PV, um die entsprechende Größe für die App vom Volume zu erhalten. In der Regel erstellt man einen PV pro Speichermedium und ein PVC pro Applikation / Pod.

Jetzt müssen beide Dateien einfach wieder mit kubectl apply aktiviert werden.

Pod Konfiguration anpassen

Um jetzt den Speicher in dem Pod verfügbar zu machen, müssen wir in der Deployment-Datei unseres Pods im spec Segment die Volumes definieren.

volumes:
  - name: nfs-volum-app
    nfs:
      server: <server-adresse>
      path: <freigabe-pfad>

Dann können wir im Container Segment die volumeMounts definieren:

volumeMounts:
  - mountPath: <container pfad>
    name: <name-des-volumes>

Beispiel Pod-Konfiguration

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextcloud
  namespace: nextcloud
  annotations:
    author: Phillip
  labels:
    app: nextcloud
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nextcloud
  template:
    metadata:
      labels:
        app: nextcloud
    spec:
      containers:
        - name: nextcloud-app
          image: lscr.io/linuxserver/nextcloud:latest
          env:
            - name: PUID
              value: "1000"
            - name: GUID
              value: "1000"
          ports:
            - name: http
              containerPort: 80
          resources:
            requests:
              cpu: "250m"
              memory: "256Mi"
            limits:
              cpu: "2000m"
              memory: "4096Mi"
          volumeMounts:
            - mountPath: /config
              name: nfs-volume-nextcloud-config
            - mountPath: /data
              name: nfs-volume-nextcloud-data
      volumes:
        - name: nfs-volume-nextcloud-config
          nfs:
            server: 192.168.5.4
            path: /mnt/Kubernetes/Daten/nextcloud-config
        - name: nfs-volume-nextcloud-data
          nfs:
            server: 192.168.5.4
            path: /mnt/Kubernetes/Daten/nextcloud-data

---
apiVersion: v1
kind: Service
metadata:
  name: nextcloud-service
  namespace: nextcloud
spec:
  selector:
    app: nextcloud
  ports:
    - port: 80

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nextcloud
  namespace: nextcloud
spec:
  ingressClassName: nginx
  rules:
  - host: nextcloud.k8s.domain.de
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: nextcloud-service
            port:
              number: 80