Speicherkapazität verfolgt kurzlebige Volumina: EmptyDir auf Steroiden

Speicherkapazität verfolgt kurzlebige Volumina: EmptyDir auf Steroiden

Einige Anwendungen müssen auch Daten speichern, sind jedoch damit einverstanden, dass die Daten nach einem Neustart nicht gespeichert werden.

Caching-Dienste sind beispielsweise durch den Arbeitsspeicher begrenzt, können aber auch Daten, die selten verwendet werden, in einen Speicher verschieben, der langsamer als der Arbeitsspeicher ist, ohne dass dies Auswirkungen auf die Gesamtleistung hat. Andere Anwendungen müssen sich darüber im Klaren sein, dass die Dateien möglicherweise schreibgeschützte Eingaben enthalten, z. B. Einstellungen oder geheime Schlüssel.

Kubernetes hat bereits mehrere Typen vergängliche Bände, aber ihre Funktionalität ist auf das beschränkt, was in den K8s implementiert ist.

Flüchtig CSI-Volumes ermöglichte die Erweiterung von Kubernetes mit CSI-Treibern, um Unterstützung für leichtgewichtige lokale Volumes bereitzustellen. Auf diese Weise ist eine Nutzung möglich beliebige Strukturen: Einstellungen, Geheimnisse, Identifikationsdaten, Variablen usw. CSI-Treiber müssen geändert werden, um diese Kubernetes-Funktion zu unterstützen, da davon ausgegangen wird, dass reguläre standardisierte Treiber nicht funktionieren. Es wird jedoch davon ausgegangen, dass solche Volumes auf jedem für den Pod ausgewählten Knoten verwendet werden können.

Dies kann ein Problem für Volumes sein, die erhebliche Hostressourcen verbrauchen, oder für Speicher, der nur auf einigen Hosts verfügbar ist. Aus diesem Grund führt Kubernetes 1.19 zwei neue Alpha-Test-Volume-Funktionen ein, die konzeptionell den EmptyDir-Volumes ähneln:

  • kurzlebige Bände für allgemeine Zwecke;

  • CSI-Speicherkapazitätsverfolgung.

Vorteile des neuen Ansatzes:

  • Der Speicher kann lokal oder über ein Netzwerk verbunden sein.

  • Volumes können eine bestimmte Größe haben, die von der Anwendung nicht überschritten werden kann;

  • Funktioniert mit allen CSI-Treibern, die die Bereitstellung persistenter Volumes unterstützen und (zur Unterstützung der Kapazitätsverfolgung) den Aufruf implementieren GetCapacity;

  • Abhängig vom Treiber und den Einstellungen können die Volumes einige Anfangsdaten enthalten.

  • alle Standardvorgänge mit einem Volume (Erstellen eines Snapshots, Größenänderung usw.) werden unterstützt;

  • Volumes können mit jedem Anwendungscontroller verwendet werden, der eine Modul- oder Volume-Spezifikation akzeptiert.

  • Der Kubernetes-Scheduler wählt selbst geeignete Knoten aus, sodass keine Notwendigkeit mehr besteht, Scheduler-Erweiterungen bereitzustellen und zu konfigurieren oder Webhooks zu ändern.

Anwendungen

Daher eignen sich kurzlebige Allzweck-Volumes für die folgenden Anwendungsfälle:

Persistenter Speicher als Ersatz für RAM für Memcached

Neueste Versionen von memcached Unterstützung hinzugefügt Verwendung von persistentem Speicher (Intel Optane usw.), ca. Übersetzer) anstelle von regulärem RAM. Wenn Sie Memcached über einen Anwendungscontroller bereitstellen, können Sie flüchtige Allzweck-Volumes verwenden, um beispielsweise mithilfe des CSI-Treibers die Zuweisung eines Volumes einer bestimmten Größe von PMEM anzufordern PMEM-CSI.

Lokaler LVM-Speicher als Arbeitsbereich

Anwendungen, die mit Daten arbeiten, die größer als RAM sind, erfordern möglicherweise lokalen Speicher mit einer Größe oder Leistungsmetriken, die normale EmptyDir-Volumes von Kubernetes nicht bieten können. Zu diesem Zweck wurde es beispielsweise geschrieben TopoLVM.

Nur lesender Zugriff auf Datenvolumes

Die Zuweisung eines Volumes kann zur Erstellung eines vollständigen Volumes führen, wenn:

Diese Volumes können im schreibgeschützten Modus gemountet werden.

Wie funktioniert das

Universelle, kurzlebige Bände

Ein wesentliches Merkmal kurzlebiger Allzweck-Volumes ist die neue Volume-Quelle. EphemeralVolumeSource, enthält alle Felder zum Erstellen einer Volume-Anfrage (historisch als persistente Volume-Anfrage, PVC bezeichnet). Neuer Controller drin kube-controller-manager untersucht die Pods, die eine solche Volume-Quelle erstellen, und erstellt dann einen PVC für diese Pods. Für den CSI-Treiber sieht diese Anfrage genauso aus wie die anderen, sodass hier keine besondere Unterstützung erforderlich ist.

Solange solche PVCs vorhanden sind, können sie wie alle anderen Anforderungen auf dem Volume verwendet werden. Sie können insbesondere beim Kopieren eines Volumes oder beim Erstellen eines Snapshots von einem Volume als Datenquelle referenziert werden. Das PVC-Objekt enthält auch den aktuellen Status des Volumes.

Die Namen automatisch erstellter PVCs sind vordefiniert: Sie sind eine Kombination aus dem Pod-Namen und dem Volume-Namen, getrennt durch einen Bindestrich. Vordefinierte Namen erleichtern die Interaktion mit dem PVC, da Sie nicht danach suchen müssen, wenn Sie den Pod-Namen und den Volume-Namen kennen. Der Nachteil besteht darin, dass der Name möglicherweise bereits verwendet wird, was von Kubernetes erkannt wird und infolgedessen der Start des Pods blockiert wird.

Um sicherzustellen, dass das Volume zusammen mit dem Pod gelöscht wird, stellt der Controller eine Anfrage an das Volume unter dem Besitzer. Wenn der Pod gelöscht wird, wird der standardmäßige Garbage-Collection-Mechanismus ausgeführt, der sowohl die Anfrage als auch das Volume löscht.

Anforderungen werden vom Speichertreiber über den normalen Mechanismus der Speicherklasse abgeglichen. Obwohl Klassen mit sofortiger und später Bindung (aka WaitForFirstConsumer) werden unterstützt, für kurzlebige Volumes ist die Verwendung sinnvoll WaitForFirstConsumer, dann kann der Planer bei der Auswahl eines Knotens sowohl die Knotennutzung als auch die Speicherverfügbarkeit berücksichtigen. Hier erscheint eine neue Funktion.

Verfolgung der Speicherkapazität

Normalerweise weiß der Planer nicht, wo der CSI-Treiber das Volume erstellen wird. Es besteht auch keine Möglichkeit für den Disponenten, den Fahrer direkt zu kontaktieren, um diese Informationen anzufordern. Daher fragt der Scheduler Knoten ab, bis er einen Knoten findet, auf dem auf Volumes zugegriffen werden kann (späte Bindung), oder überlässt die Wahl des Speicherorts vollständig dem Treiber (sofortige Bindung).

neu API CSIStorageCapacity, das sich im Alpha-Stadium befindet, ermöglicht die Speicherung der notwendigen Daten in etcd, damit sie dem Planer zur Verfügung stehen. Im Gegensatz zur Unterstützung für kurzlebige Allzweck-Volumes müssen Sie bei der Bereitstellung des Treibers die Speicherkapazitätsverfolgung aktivieren: external-provisioner sollte die vom Treiber erhaltenen Kapazitätsinformationen normal veröffentlichen GetCapacity.

Wenn der Scheduler einen Knoten für einen Pod mit einem ungebundenen Volume auswählen muss, der die späte Bindung verwendet, und der Treiber diese Funktion während der Bereitstellung durch Setzen des Flags aktiviert hat CSIDriver.storageCapacity, dann werden Knoten, die nicht über genügend Speicherkapazität verfügen, automatisch verworfen. Dies funktioniert sowohl für allgemeine, kurzlebige als auch für persistente Volumes, jedoch nicht für kurzlebige CSI-Volumes, da deren Parameter von Kubernetes nicht gelesen werden können.

Wie üblich werden sofort verknüpfte Volumes erstellt, bevor Pods geplant werden, und ihre Platzierung wird vom Speichertreiber, also bei der Konfiguration, ausgewählt external-provisioner Standardmäßig werden Speicherklassen mit sofortiger Bindung übersprungen, da diese Daten ohnehin nicht verwendet werden.

Da der Kubernetes-Scheduler gezwungen ist, mit möglicherweise veralteten Informationen zu arbeiten, gibt es keine Garantie dafür, dass bei der Erstellung des Volumes in jedem Fall Kapazität verfügbar ist, aber die Chancen, dass es ohne Wiederholungsversuche erstellt wird, sind dennoch erhöht.

NB In Intensivkursen können Sie sich ausführlicher informieren, sicher „am Katzenstand üben“ und im Falle einer völlig unverständlichen Situation qualifizierte technische Unterstützung erhalten – Kubernetes-Basis findet vom 28. bis 30. September statt und richtet sich an fortgeschrittenere Spezialisten Kubernetes Mega 14.–16. Oktober.

Sicherheit

CSIStorageCapacity

CSIStorageCapacity-Objekte befinden sich in Namespaces. Wenn jeder CSI-Treiber in seinem eigenen Namespace bereitgestellt wird, wird empfohlen, die RBAC-Rechte auf CSIStorageCapacity in diesem Bereich zu beschränken, da offensichtlich ist, woher die Daten kommen. Kubernetes prüft dies ohnehin nicht, und normalerweise werden Treiber im selben Namensraum abgelegt, sodass letztlich von den Treibern erwartet wird, dass sie funktionieren und keine falschen Daten veröffentlichen (und hier ist meine Karte ausgefallen, ca. Übersetzer basierend auf einem bärtigen Witz)

Universelle, kurzlebige Bände

Wenn Benutzer Rechte zum Erstellen eines Pods haben (direkt oder indirekt), können sie auch kurzlebige Allzweck-Volumes erstellen, selbst wenn sie keine Rechte zum Erstellen einer Anfrage auf dem Volume haben. Dies liegt daran, dass RBAC-Berechtigungsprüfungen auf den Controller angewendet werden, der das PVC erstellt, und nicht auf den Benutzer. Dies ist die wichtigste hinzuzufügende Änderung zu deinem Konto, bevor Sie diese Funktion auf Clustern aktivieren, in denen nicht vertrauenswürdige Benutzer keine Rechte zum Erstellen von Volumes haben sollten.

Beispiel

Trennen Zweig PMEM-CSI enthält alle notwendigen Änderungen, um einen Kubernetes 1.19-Cluster in virtuellen QEMU-Maschinen mit allen Funktionen in der Alpha-Phase auszuführen. Der Treibercode hat sich nicht geändert, nur die Bereitstellung hat sich geändert.

Auf einer geeigneten Maschine (Linux) kann ein normaler Benutzer verwenden Docker, sehen hier Details) Diese Befehle rufen den Cluster auf und installieren den PMEM-CSI-Treiber:

git clone --branch=kubernetes-1-19-blog-post https://github.com/intel/pmem-csi.git
cd pmem-csi
export TEST_KUBERNETES_VERSION=1.19 TEST_FEATURE_GATES=CSIStorageCapacity=true,GenericEphemeralVolume=true TEST_PMEM_REGISTRY=intel
make start && echo && test/setup-deployment.sh

Nachdem alles funktioniert hat, enthält die Ausgabe eine Gebrauchsanweisung:

The test cluster is ready. Log in with [...]/pmem-csi/_work/pmem-govm/ssh.0, run
kubectl once logged in.  Alternatively, use kubectl directly with the
following env variable:
   KUBECONFIG=[...]/pmem-csi/_work/pmem-govm/kube.config

secret/pmem-csi-registry-secrets created
secret/pmem-csi-node-secrets created
serviceaccount/pmem-csi-controller created
...
To try out the pmem-csi driver ephemeral volumes:
   cat deploy/kubernetes-1.19/pmem-app-ephemeral.yaml |
   [...]/pmem-csi/_work/pmem-govm/ssh.0 kubectl create -f -

CSIStorageCapacity-Objekte sind nicht dafür gedacht, von Menschen gelesen zu werden, daher ist eine gewisse Verarbeitung erforderlich. Golang-Vorlagenfilter zeigen die Speicherklassen an. In diesem Beispiel werden der Name, die Topologie und die Kapazität angezeigt:

$ kubectl get 
        -o go-template='{{range .items}}{{if eq .storageClassName "pmem-csi-sc-late-binding"}}{{.metadata.name}} {{.nodeTopology.matchLabels}} {{.capacity}}
{{end}}{{end}}' 
        csistoragecapacities
csisc-2js6n map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker2] 30716Mi
csisc-sqdnt map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker1] 30716Mi
csisc-ws4bv map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker3] 30716Mi

Ein einzelnes Objekt hat folgenden Inhalt:

$ kubectl describe csistoragecapacities/csisc-6cw8j
Name:         csisc-sqdnt
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  storage.k8s.io/v1alpha1
Capacity:     30716Mi
Kind:         CSIStorageCapacity
Metadata:
  Creation Timestamp:  2020-08-11T15:41:03Z
  Generate Name:       csisc-
  Managed Fields:
    ...
  Owner References:
    API Version:     apps/v1
    Controller:      true
    Kind:            StatefulSet
    Name:            pmem-csi-controller
    UID:             590237f9-1eb4-4208-b37b-5f7eab4597d1
  Resource Version:  2994
  Self Link:         /apis/storage.k8s.io/v1alpha1/namespaces/default/csistoragecapacities/csisc-sqdnt
  UID:               da36215b-3b9d-404a-a4c7-3f1c3502ab13
Node Topology:
  Match Labels:
    pmem-csi.intel.com/node:  pmem-csi-pmem-govm-worker1
Storage Class Name:           pmem-csi-sc-late-binding
Events:                       <none>

Versuchen wir, eine Demoanwendung mit einem einzigen kurzlebigen Allzweck-Volume zu erstellen. Dateiinhalte pmem-app-ephemeral.yaml:

# This example Pod definition demonstrates
# how to use generic ephemeral inline volumes
# with a PMEM-CSI storage class.
kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app-inline-volume
spec:
  containers:
    - name: my-frontend
      image: intel/pmem-csi-driver-test:v0.7.14
      command: [ "sleep", "100000" ]
      volumeMounts:
      - mountPath: "/data"
        name: my-csi-volume
  volumes:
  - name: my-csi-volume
    ephemeral:
      volumeClaimTemplate:
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 4Gi
          storageClassName: pmem-csi-sc-late-binding

Nach der Erstellung, wie in der obigen Anleitung gezeigt, haben wir nun einen zusätzlichen Pod und PVC:

$ kubectl get pods/my-csi-app-inline-volume -o wide
NAME                       READY   STATUS    RESTARTS   AGE     IP          NODE                         NOMINATED NODE   READINESS GATES
my-csi-app-inline-volume   1/1     Running   0          6m58s   10.36.0.2   pmem-csi-pmem-govm-worker1   <none>           <none>
$ kubectl get pvc/my-csi-app-inline-volume-my-csi-volume
NAME                                     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS               AGE
my-csi-app-inline-volume-my-csi-volume   Bound    pvc-c11eb7ab-a4fa-46fe-b515-b366be908823   4Gi        RWO            pmem-csi-sc-late-binding   9m21s

PVC-Inhaber – unter:

$ kubectl get -o yaml pvc/my-csi-app-inline-volume-my-csi-volume
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    pv.kubernetes.io/bind-completed: "yes"
    pv.kubernetes.io/bound-by-controller: "yes"
    volume.beta.kubernetes.io/storage-provisioner: pmem-csi.intel.com
    volume.kubernetes.io/selected-node: pmem-csi-pmem-govm-worker1
  creationTimestamp: "2020-08-11T15:44:57Z"
  finalizers:
  - kubernetes.io/pvc-protection
  managedFields:
    ...
  name: my-csi-app-inline-volume-my-csi-volume
  namespace: default
  ownerReferences:
  - apiVersion: v1
    blockOwnerDeletion: true
    controller: true
    kind: Pod
    name: my-csi-app-inline-volume
    uid: 75c925bf-ca8e-441a-ac67-f190b7a2265f
...

Voraussichtlich aktualisierte Informationen für pmem-csi-pmem-govm-worker1:

csisc-2js6n map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker2] 30716Mi
csisc-sqdnt map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker1] 26620Mi
csisc-ws4bv map[pmem-csi.intel.com/node:pmem-csi-pmem-govm-worker3] 30716Mi

Wenn eine andere Anwendung mehr als 26620Mi benötigt, wird der Scheduler dies nicht berücksichtigen pmem-csi-pmem-govm-worker1 in jedem Fall.

Was kommt als nächstes?

Beide Funktionen befinden sich noch in der Entwicklung. Während des Alphatests wurden mehrere Anwendungen geöffnet. Die Links zu Verbesserungsvorschlägen dokumentieren die Arbeit, die geleistet werden muss, um in die Beta-Phase zu gelangen, sowie welche Alternativen bereits in Betracht gezogen und abgelehnt wurden:

Source: habr.com

Kommentar hinzufügen