Volumes éphémères avec suivi de la capacité de stockage : EmptyDir sur stéroïdes

Volumes éphémères avec suivi de la capacité de stockage : EmptyDir sur stéroïdes

Certain applications also need to store data, but they are quite indifferent to the fact that the data will not be saved after a restart.

For example, caching services are limited by RAM, but can also move rarely used data to slower storage with little impact on overall performance. Other applications need to know that some files may contain read-only input, such as configuration settings or secret keys.

Kubernetes already has several types of ephemeral volumes, but their functionality is limited to what is implemented in K8s.

Ephemeral CSI volumes allow Kubernetes to be extended with CSI drivers to support lightweight local volumes. This way, it is possible to use arbitrary structures: configurations, secrets, identity data, variables, and so on. CSI drivers need to be enhanced to support this functionality in Kubernetes, as it is expected that standard drivers will not work — but these volumes are expected to be usable on any node selected for the pod.

This can be problematic for volumes with significant resource consumption on the node or for storage available only on certain nodes. Therefore, in Kubernetes 1.19, two new volume functions have been introduced for alpha testing, conceptually similar to EmptyDir volumes:

  • general-purpose ephemeral volumes;

  • CSI storage capacity tracking.

Advantages of the new approach:

  • storage can be local or network-attached;

  • volumes can have a specified size that cannot be exceeded by the application;

  • works with any CSI drivers that support persistent volume provision and (for capacity tracking support) implement the call GetCapacity;

  • volumes can have some initial data depending on the driver and parameters;

  • all standard volume operations (snapshotting, resizing, etc.) are supported;

  • volumes can be used with any application controller that accepts a module or volume specification;

  • Le planificateur Kubernetes choisit lui-même les nœuds appropriés, il n'est donc plus nécessaire de gérer et configurer les extensions du planificateur ni de modifier les webhooks.

Applications

Ainsi, les volumes éphémères à usage général conviennent aux applications suivantes :

Mémoire permanente en remplacement de la mémoire vive pour memcached

Dernières versions de memcached ont ajouté le support de l'utilisation de la mémoire permanente (Intel Optane, etc., note du traducteur) au lieu de la mémoire vive classique. Lors du déploiement de memcached via le contrôleur d'applications, des demandes peuvent être faites pour allouer un volume de taille spécifiée à partir de PMEM à l'aide du pilote CSI, par exemple PMEM-CSI.

Stockage local LVM en tant qu'espace de travail

Les applications traitant des données dont la taille dépasse la mémoire vive peuvent demander un stockage local avec taille ou métriques de performance qui ne peuvent être fournies par des volumes EmptyDir classiques de Kubernetes. Par exemple, pour cette fin, TopoLVM.

Accès en lecture seule aux volumes de données

L'allocation d'un volume peut entraîner la création d'un volume rempli dans les cas suivants :

Ces volumes peuvent être montés en mode lecture seule.

Comment cela fonctionne

Volumes éphémères à usage général

La caractéristique clé des volumes éphémères à usage général est la nouvelle source de volume, EphemeralVolumeSource, contenant tous les champs nécessaires pour créer une demande de volume (historically this is called persistent volume request, PVC). Un nouveau contrôleur dans kube-controller-manager vérifie les pods créant une telle source de volume, puis crée un PVC pour ces pods. Pour le pilote CSI, cette demande ressemble à toutes les autres, il n'est donc pas nécessaire d'un support particulier ici.

Tant que ces PVC existent - ils peuvent être utilisés comme toute autre demande de volume. En particulier, ils peuvent être référencés comme source de données lors de la copie d'un volume ou de la création d'un instantané à partir d'un volume. L'objet PVC contient également l'état actuel du volume.

Les noms des PVC créés automatiquement sont prédéfinis : il s'agit d'une combinaison du nom du pod et du nom du volume, séparés par un tiret. La prédéfinition des noms facilite l'interaction avec les PVC, car il n'est pas nécessaire de les rechercher si le nom du pod et le nom du volume sont connus. Le inconvénient est que le nom peut déjà être utilisé, ce qui est détecté par Kubernetes, et par conséquent le démarrage du pod est bloqué.

Pour s'assurer que le volume est supprimé avec le pod, le contrôleur fait du pod le propriétaire de la demande de volume. Lorsque le pod est supprimé, un mécanisme de nettoyage standard s'active, qui supprime à la fois la demande et le volume.

Les requêtes sont associées à un pilote de stockage via un mécanisme de classe de stockage classique. Bien que les classes d'association immédiate et différée (c'est-à-dire WaitForFirstConsumer) soient prises en charge, il est judicieux d'utiliser WaitForFirstConsumer, car alors le planificateur peut tenir compte à la fois de l'utilisation du nœud et de la disponibilité du stockage lors du choix du nœud. Une nouvelle fonctionnalité apparaît ici.

Suivi de la capacité de stockage

Le planificateur n’a généralement pas de données sur l’endroit où le pilote CSI créera le volume. Le planificateur ne peut pas non plus contacter le pilote directement pour demander cette information. Par conséquent, le planificateur interroge les nœuds jusqu'à ce qu'il en trouve un où les volumes peuvent être disponibles (association différée), ou laisse complètement le choix de l'emplacement au pilote (association immédiate).

Nouveau API CSIStorageCapacity, qui est en phase alpha, permet de stocker les informations nécessaires dans etcd, afin qu'elles soient accessibles au planificateur. Contrairement au support des volumes éphémères à usage général, lors du déploiement du pilote, le suivi de la capacité de stockage doit être activé : external-provisioner doit publier les informations sur la capacité reçues du pilote via un GetCapacity.

Si le planificateur doit choisir un nœud pour un pod avec un volume non lié utilisant l'association différée, et que le pilote a activé cette fonctionnalité lors du déploiement en définissant le drapeau CSIDriver.storageCapacity, alors les nœuds qui n'ont pas une capacité de stockage suffisante seront automatiquement rejetés. Cela fonctionne à la fois pour les volumes éphémères à usage général et pour les volumes persistants, mais pas pour les volumes éphémères CSI, car leurs paramètres ne peuvent pas être lus par Kubernetes.

Comme d'habitude, les volumes avec liaison immédiate sont créés avant la planification des pods, et leur emplacement est choisi par le pilote de stockage, donc lors de la configuration external-provisioner par défaut, les classes de stockage avec liaison immédiate sont omises, car ces données ne seront de toute façon pas utilisées.

Étant donné que le planificateur Kubernetes est contraint de travailler avec des informations potentiellement obsolètes, il n'y a aucune garantie que la capacité sera disponible au moment de la création du volume, mais néanmoins, les chances qu'il soit créé sans réessais sont accrues.

N.B. Vous pourrez obtenir plus d'informations, ainsi que vous entraîner en toute sécurité sur un environnement de test, et en cas de situations vraiment incompréhensibles, obtenir une aide qualifiée du support technique lors des ateliers — Base Kubernetes qui se déroulera du 28 au 30 septembre, et pour les spécialistes plus avancés. Méga Kubernetes du 14 au 16 octobre.

Sécurité

CSIStorageCapacity

Les objets CSIStorageCapacity se trouvent dans les espaces de noms, lors du déploiement de chaque pilote CSI, il est recommandé de restreindre les droits RBAC pour CSIStorageCapacity dans cet espace, car il est évident d'où proviennent les données. Dans tous les cas, Kubernetes ne vérifie pas cela, et généralement, les pilotes sont installés dans un seul espace de noms, donc on s'attend à ce que les pilotes fonctionnent et ne publient pas de données incorrectes (et ici, la carte m'a vraiment aidé, note du traducteur inspirée d'une vieille plaisanterie.)

Volumes éphémères à usage général

Si les utilisateurs ont des droits pour créer un pod (directement ou indirectement), ils pourront également créer des volumes éphémères de usage général même s'ils n'ont pas les droits pour créer une demande de volume. C'est parce que les contrôles des droits RBAC s'appliquent au contrôleur qui crée le PVC, et non à l'utilisateur. C'est le changement majeur à ajouter au compte, avant d'activer cette fonction dans les clusters, si des utilisateurs non fiables ne doivent pas avoir le droit de créer des volumes.

Exemple

Séparée discussion correspondante dans PMEM-CSI contient toutes les modifications nécessaires pour exécuter un cluster Kubernetes 1.19 à l'intérieur de machines virtuelles QEMU avec toutes les fonctionnalités en phase alpha. Le code du pilote n'a pas été modifié, seule le déploiement a changé.

Sur une machine adaptée (Linux, un utilisateur normal peut utiliser Docker, voir ici les détails), ces commandes lanceront le cluster et installeront le pilote PMEM-CSI :

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

Une fois que tout fonctionne, la sortie contiendra des instructions pour l'utilisation :

Le cluster de test est prêt. Connectez-vous avec [...] /pmem-csi/_work/pmem-govm/ssh.0, exécutez
kubectl une fois connecté. Alternativement, utilisez kubectl directement avec la
variable d'environnement suivante :
   KUBECONFIG=[...] /pmem-csi/_work/pmem-govm/kube.config

secret/pmem-csi-registry-secrets créé
secret/pmem-csi-node-secrets créé
serviceaccount/pmem-csi-controller créé
...
Pour essayer le modèle de volumes éphémères du pilote pmem-csi :
   cat deploy/kubernetes-1.19/pmem-app-ephemeral.yaml |
   [...] /pmem-csi/_work/pmem-govm/ssh.0 kubectl create -f -

Les objets CSIStorageCapacity ne sont pas destinés à être lus par des humains, donc un traitement est nécessaire. À l'aide de filtres de modèle en Golang, les classes de stockage seront affichées; dans cet exemple, le nom, la topologie et la capacité seront affichés :

$ 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

Un objet distinct a ce contenu :

$ kubectl describe csistoragecapacities/csisc-6cw8j
Nom :         csisc-sqdnt
Namespace :    default
Étiquettes :       
Annotations :  
Version API :  storage.k8s.io/v1alpha1
Capacité :     30716Mi
Type :         CSIStorageCapacity
Métadonnées :
  Horodatage de création :  2020-08-11T15:41:03Z
  Nom généré :       csisc-
  Champs gérés :
    ...
  Références du propriétaire :
    Version API :     apps/v1
    Contrôleur :      true
    Type :            StatefulSet
    Nom :            pmem-csi-controller
    UID :             590237f9-1eb4-4208-b37b-5f7eab4597d1
  Version de la ressource :  2994
  Lien auto :         /apis/storage.k8s.io/v1alpha1/namespaces/default/csistoragecapacities/csisc-sqdnt
  UID :               da36215b-3b9d-404a-a4c7-3f1c3502ab13
Topologie de nœud :
  Étiquettes correspondantes :
    pmem-csi.intel.com/node :  pmem-csi-pmem-govm-worker1
Nom de classe de stockage :           pmem-csi-sc-late-binding
Événements :

Essayons de créer une application démonstration avec un seul volume éphémère de type général. Le contenu du fichier 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

Après la création, comme indiqué dans les instructions ci-dessus, nous avons obtenu un pod supplémentaire et un PVC :

$ kubectl get pods/my-csi-app-inline-volume -o wide
NOM                       PRÊT   ÉTAT    REDÉMARRAGES   ÂGE     IP          NŒUD                         NŒUD NOMMÉ   PORTAIL DE PRÉPARATION
my-csi-app-inline-volume   1/1     En cours d'exécution   0          6m58s   10.36.0.2   pmem-csi-pmem-govm-worker1              
$ kubectl get pvc/my-csi-app-inline-volume-my-csi-volume
NOM                                     ÉTAT   VOLUME                                     CAPACITÉ   MODES D'ACCÈS   STOCKAGE               ÂGE
my-csi-app-inline-volume-my-csi-volume   Lié    pvc-c11eb7ab-a4fa-46fe-b515-b366be908823   4Gi        RWO            pmem-csi-sc-late-binding   9m21s

Le propriétaire du PVC est le pod :

$ 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
...

Les informations ont été mises à jour comme prévu pour 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

Si une autre application a besoin de plus de 26620Mi, le planificateur ne le prendra pas en compte pmem-csi-pmem-govm-worker1 dans tous les cas.

Et après ?

Les deux fonctions sont toujours en cours de développement. Plusieurs demandes ont été ouvertes lors des tests alpha. Les liens avec les suggestions d'améliorations sont en cours de documentation du travail nécessaire pour passer à l'étape bêta, ainsi que des alternatives qui ont déjà été examinées et rejetées :

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster