Kubernetes : comment déployer des containers persistants ?

Les containers persistants stockent leurs données de manière durable, ce qui est largement préférable pour exécuter des applications traditionnelles. Cet article détaille les possibilités pour y parvenir.

De par leur conception, les containers sont légers, éphémères et « sans état », c’est-à-dire que toutes les données qu’ils ont pu créer localement se volatilisent une fois qu’ils sont éteints. Un container peut stocker des données vers un service de stockage objet S3, mais ce n’est pas la manière dont travaillent les applications traditionnelles qui stockent plutôt des fichiers sur le disque du serveur qui les exécute.

On parle d’application « sans état » ou « stateless » lorsqu’elle est conçue pour se volatiliser avec ses données à l’extinction. Et d’une application « avec état », ou « stateful », lorsqu’elle est conçue pour enregistrer des données sur disque.

Une application ou un composant sans état n’enregistre aucune donnée client générée dans la session en cours et ne peut donc pas non plus en réutiliser dans les sessions suivantes. Chaque opération dans une application sans état s’exécute comme si c’était la première fois. Les applications sans état sont couramment utilisées dans les réseaux de diffusion de contenu et les services d’impression qui effectuent des travaux ponctuels.

Une application avec état, en revanche, récupère des données spécifiques provenant de sessions précédentes et les enregistre pour les suivantes. Les applications avec état sont souvent utilisées lorsque les préférences et les actions de l’utilisateur doivent être mémorisées d’une session à l’autre. C’est par exemple le cas pour le stockage d’articles dans un panier d’achats en ligne, l’historique des conversations dans une application de messagerie ou les données dans une application d’analyse qui traite les mêmes informations de manière répétée.

Il est pratiquement impossible d’exécuter une application traditionnelle sans maintenir un certain historique. Cependant, la containerisation d’applications et de composants d’application avec état peut entraîner des problèmes de gestion des données pour les équipes informatiques. Typiquement, un container est censé pouvoir s’exécuter sur un serveur différent. Dans ce cas, il faut que cet autre serveur ait accès au stockage utilisé par le précédent.

Les principales approches pour exécuter des applications avec état sont les volumes persistants, gérés comme des ressources « PersistentVolumes » par Kubernetes, et les jeux d’états persistants, alias « StatefulSets ».

Les volumes persistants

Dans une application stateful containerisée, les données doivent être persistantes, conservées et faciles d’accès en dehors de l’application. C’est là que les PersistentVolumes entrent en jeu.

Les PersistentVolumes sont des ressources de cluster Kubernetes : ce sont des modules de stockage dans un cluster qui référencent un emplacement de données physique. Les PersistentVolumes mettent le stockage à la disposition des applications exécutées dans les pods Kubernetes en dehors du cycle de vie de ces pods, ce qui signifie que les données ne sont pas perdues lorsque Kubernetes détruit ou recrée un pod.

En pratique, des pilotes de solutions de stockage définissent une ressource StorageClass au niveau du nœud maître d’un cluster Kubernetes. Les pods qui ont besoin qu’un volume soit monté pour eux envoient une requête PersistentVolumeClaims (PVC) au nœud maître. En réponse, le nœud maître relie une ressource PersistentVolume au PVC.

Au moment de l’écriture de cet article, Kubernetes prend en charge les plugins PersistentVolume suivants :

  • AWS Elastic Block Store
  • Microsoft Azure Disks
  • Microsoft Azure Files
  • CephFS volumes
  • Container Storage Interface
  • Fibre Channel storage
  • Google Compute Engine Persistent Disk
  • GlusterFS volumes
  • hostPath volumes
  • iSCSI storage
  • Network File System storage
  • Portworx volumes
  • RADOS Block Device volumes
  • VMware vSphere virtual machine disk volumes

Les StatefulSets

Les StatefulSets sont des objets Kubernetes qui permettent aux administrateurs de déployer des pods avec des caractéristiques persistantes : leur identifiant réseau et leur stockage personnel seront conservés à chaque redéploiement. Dans le détail, les StatefulSets ont ces caractéristiques :

  • Des identifiants réseau uniques,
  • Des volumes de stockage persistants, basés sur les classes de stockage définies au niveau utilisateur,
  • Des déploiements, des mises à l’échelle et des mises à jour qui se font toujours dans un ordre précis.

Par exemple, alors que les pods sont d’ordinaire déployés avec un nom réseau aléatoire, ceux d’un StatefulSets s’appelleront, dans l’ordre de mise en route, web-01, web-02, web-03, etc. Par défaut, ils seront éteints dans l’ordre inverse.

Une fois créés, les StatefulSets garantissent que le nombre souhaité de pods fonctionne. Si l’un d’eux défaille, les StatefulSets le remplacent avec une nouvelle copie qui sera automatiquement associée au stockage persistant du précédent. Le code suivant est un exemple de fichier manifeste pour le déploiement à l’aide de StatefulSets d’un service applicatif web persistant.

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web-statefulset
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx-svc"
  replicas: 2
  minReadySeconds: 10
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: pvdata
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

Les logiciels les plus courants pour le stockage persistant

Les outils de stockage pour containers facilitent l’exécution d’applications persistantes dans Kubernetes. Les deux plus célèbres sont OpenEBS et Portworx.

OpenEBS est un projet Open source qui propose de gérer le stockage persistant comme n’importe quel autre container. Les caractéristiques d’OpenEBS sont les suivantes :

  • Architecture CAS (Container Attached Storage), dans laquelle un volume de stockage est déployé sous la forme d’un pod dédié,
  • Haute disponibilité en répliquant les volumes de données de manière synchrone,
  • Couche d’abstraction au-dessus des infrastructures de stockage du marché, qu’elles soient matérielles (tiroir de disque), logicielles (SDS) ou en cloud,
  • Possibilité de suivre les métriques des pods au travers d’outils standards comme Kubernetes Dashboard, Prometheus ou Grafana, du fait de l’architecture CAS.

De son côté, Portworx de Pure Storage se concentre sur la haute disponibilité du stockage, en le distribuant sur plusieurs serveurs, qu’ils soient sur site ou en cloud. Ses fonctions avancées comprennent la reprise après sinistre et la sécurité. Les caractéristiques de Portworx sont les suivantes :

  • Chiffrement des données et gestion de leur sécurité,
  • Autoscaling, c’est-à-dire que le système redimensionne automatiquement les containers et les volumes de stockage,
  • Faculté de programmer les ressources de stockage,
  • Sauvegardes et snapshots.

Bien que les containers soient conçus pour être jetables, de nombreuses applications ont aujourd’hui besoin de rappeler des informations entre les sessions. Grâce aux outils de stockage pour les containers et aux options de Kubernetes pour le maintien de l’état entre sessions, les équipes informatiques et DevOps peuvent à la fois répondre au besoin de déployer des applications traditionnelles et bénéficier de l’efficacité de Kubernetes afin de redéployer automatiquement des containers au moindre incident.

Pour approfondir sur Stockage de conteneurs