19 Container Storage Interface (CSI) in Kubernetes

Container Storage Interface (CSI) ist eine standardisierte Schnittstelle für Container-Orchestrierungssysteme wie Kubernetes, die eine nahtlose Integration mit verschiedenen Speichersystemen ermöglicht. CSI abstrahiert die Komplexität der Speicherverwaltung und ermöglicht es Speicheranbietern, ihre Lösungen ohne Änderungen am Kubernetes-Kern zu integrieren, was die Flexibilität und Wartbarkeit des Kubernetes-Ökosystems erheblich verbessert.

19.1 Grundkonzepte von CSI

19.2 CSI-Komponenten in Kubernetes

Ein CSI-Plugin in Kubernetes besteht aus mehreren Komponenten:

  1. CSI-Controller: Verwaltet die Lebenszyklus-Operationen von Volumes (erstellen, löschen, snapshots, etc.).
  2. CSI-Node: Verantwortlich für die Montage und Demontage von Volumes auf den Knoten.
  3. CSI-Identity: Stellt Identitätsinformationen über das Plugin bereit.

Diese Komponenten werden typischerweise als Container in einem Kubernetes-Cluster bereitgestellt.

19.3 Vorteile von CSI

19.4 CSI im Kontext von Kubernetes Storage

CSI erweitert das bestehende Storage-System in Kubernetes:

19.5 Konfigurationsbeispiel für ein CSI-Plugin

19.5.1 StorageClass mit CSI-Provisioner

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-example-sc
provisioner: example.csi.k8s.io
parameters:
  type: ssd
  fsType: ext4
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

19.5.2 PersistentVolumeClaim mit CSI-StorageClass

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-pvc-example
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: csi-example-sc

19.5.3 Pod mit CSI-Volume

apiVersion: v1
kind: Pod
metadata:
  name: csi-demo-pod
spec:
  containers:
    - name: app
      image: nginx
      volumeMounts:
      - mountPath: /data
        name: csi-volume
  volumes:
    - name: csi-volume
      persistentVolumeClaim:
        claimName: csi-pvc-example

19.6 Gängige CSI-Plugins

Kubernetes unterstützt eine Vielzahl von CSI-Plugins, darunter:

19.7 Deployment eines CSI-Plugins

Ein CSI-Plugin wird typischerweise mit den folgenden Komponenten bereitgestellt:

  1. Controller-Deployment: Verwaltet Volumes zentral
  2. Node-DaemonSet: Läuft auf jedem Knoten und kümmert sich um die Montage
  3. RBAC-Rollen: Für die notwendigen Berechtigungen
  4. CSIDriver-Objekt: Registriert das Plugin im Cluster

Beispiel für ein einfaches CSIDriver-Objekt:

apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
  name: example.csi.k8s.io
spec:
  attachRequired: true
  podInfoOnMount: true
  volumeLifecycleModes:
    - Persistent
    - Ephemeral

19.8 Troubleshooting und Debugging

Bei Problemen mit CSI-Volumes sollten folgende Bereiche überprüft werden:

  1. CSI-Controller-Logs: Für Probleme bei der Volume-Erstellung oder -Löschung
  2. CSI-Node-Logs: Für Probleme beim Mounten von Volumes
  3. PV/PVC-Status: Überprüfen des Status und der Events von PV und PVC
  4. Pod-Events: Überprüfen der Events des Pods, der das Volume verwendet

19.9 Beispiel Storage class

In diesem Beispiel wird eine Kubernetes-Umgebung dargestellt, in der eine StorageClass für das dynamische Volumen-Provisioning definiert ist. Es wird gezeigt, wie ein PersistentVolume (PV) und ein PersistentVolumeClaim (PVC) erstellt werden, um Speicherressourcen zuzuweisen. Ein Pod verwendet diesen Claim, um einen Speicherbereich an einen Mount-Punkt innerhalb des Containers zu binden.

19.9.1 StorageClass Konfiguration

Die StorageClass my-local-storage definiert, wie ein PersistentVolume (PV) bereitgestellt wird. Es wird angegeben, dass kein automatischer Provisioner für die Bereitstellung des Volumes genutzt wird (provisioner: kubernetes.io/no-provisioner). Das Volume wird erst gebunden (volumeBindingMode: WaitForFirstConsumer), wenn ein Pod, der es anfordert, tatsächlich instanziiert wird. Die Möglichkeit zur Erweiterung des Volumes wird durch allowVolumeExpansion: true gegeben.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: my-local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

19.9.2 PersistentVolume Konfiguration

my-persistent-volume definiert ein PV mit 1 Gi Speicherplatz. Die Zugriffsmöglichkeit ist auf ReadWriteOnce gesetzt, was bedeutet, dass das Volume auf genau einem Node im Read-Write-Modus gemountet werden kann. Durch hostPath wird ein lokaler Pfad (/var/tmp/my-data) auf dem Node als Speicherort für das Volume festgelegt. Die persistentVolumeReclaimPolicy: Recycle besagt, dass Daten auf dem Volume beim Löschen des PV nicht dauerhaft gelöscht, sondern für neue Claims zur Verfügung stehen.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-persistent-volume
spec:
  storageClassName: my-local-storage
  persistentVolumeReclaimPolicy: Recycle
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /var/tmp/my-data

19.9.3 PersistentVolumeClaim Konfiguration

Das PVC my-pvc fordert Speicher von der my-local-storage StorageClass an, mit der Zugriffsmöglichkeit ReadWriteOnce und einer Größe von 100 Mi. Dieses PVC wird dann verwendet, um Speicheranforderungen für Pods zu erfüllen.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  storageClassName: my-local-storage
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Mi

19.9.4 Pod Konfiguration

Der Pod my-pv-pod startet einen Container mit dem Image busybox und führt einen Befehl aus, der eine Nachricht in eine Datei (/output/erfolg.txt) innerhalb des gemounteten Volumes schreibt. Der volumeMounts-Abschnitt verbindet das durch my-pvc definierte PVC mit dem Pfad /output im Container. Der Pod verwendet Never als restartPolicy, was bedeutet, dass der Container nicht automatisch neu gestartet wird, wenn er beendet wird.

apiVersion: v1
kind: Pod
metadata:
  name: my-pv-pod
spec:
  restartPolicy: Never
  containers:
    - name: my-busybox
      image: busybox
      command: ["sh", "-c", "echo Hallo, dies ist ein Persistent Volume Claim Test >> /output/erfolg.txt"]
      volumeMounts:
      - mountPath: /output
        name: my-volume-mount
  volumes:
    - name: my-volume-mount
      persistentVolumeClaim:
        claimName: my-pvc