Stocker les données de votre cluster K8s avec Longhorn
Découvrons ensemble Longhorn, la solution de stockage distribuée de Rancher Labs
Au sommaire :
- 1-Qu'est-ce que Longhorn ?
- 2-Déploiement
- 3-Exposer l'interface
- 4-Déploiement d'une application
1-Qu'est-ce que Longhorn ?
Longhorn est une solution de stockage persistante et hautement disponible conçue par la société Rancher Labs (rachetée par Suse en 2020).
C'est un projet hébergé par la CNCF (Cloud Native Computing Foundation) depuis octobre 2019 et qui est actuellement au stade du bac à sable (sandbox). Cela signifie que si tout se passe bien, il passera par la suite en incubation (incubate) puis par être certifié (graduated) mais même dans son état actuel, Longhorn est prêt à être utilisé en production (72.000 nœuds actifs selon SUSE).
Il se présente sous le forme d'un plugin CSI (Container Storage Interface), supporte les PV (PersistentVolume) et PVC (PersistentVolumeClaim) ainsi que les sauvegardes et les snapshot.
Si Kubernetes réplique les applications sur l'ensemble du cluster, Longhorn va quant à lui répliquer la configuration des applications à travers les PV et PVC.
2-Déploiement
Vous pouvez constater avec la commande suivante que pour le moment, votre cluster ne dispose d'aucun espace de stockage (storageClass).
kubectl get sc
Pour déployer Longhorn, rien de plus simple. Si vous avez suivi le tutoriel sur K3s, déployez la dernière version en date de Longhorn (1.4.0) avec la commande suivante.
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.5.0/deploy/longhorn.yaml
Vous pouvez vérifier en temps réel la création des pods dans le namespace "longhorn-system".
kubectl get pods \
--namespace longhorn-system \
--watch
Si vous avez ce message qui s'affiche, c'est que vous n'avez pas assez d'espace disque ajouter quelques Go à votre machine virtuelle dans PVE.
Si vous avez un namespace en statut "terminated", suivez ce tutoriel pour le supprimer proprement.
Pour l'instant, rien de complexe hein ? Continuons donc.....
3-Exposer l'interface
Pour accéder à l'interface, vous pouvez sois l'exposer temporairement à travers le port 80 en HTTP, sois de manière permanente avec "NodePort".
Je ne traiterai pas du cas des contrôleurs Ingress pour exposer l'interface à travers un reverse proxy comme Traefik et NGINX.
Port-forward
Tapez la commande suivante
kubectl port-forward svc/longhorn-frontend -n longhorn-system 8080:80
Puis tapez l'adresse IP du serveur sur votre navigateur web et vous devriez y accéder.
NodePort/LoadBalancer
Pour l'exposer de manière permanente, éditez le service "longhorn-frontend" avec l'éditeur nano.
KUBE_EDITOR="nano" kubectl edit svc longhorn-frontend -n longhorn-system
Remplacez "ClusterIP" par "NodePort" ou "LoadBalancer" puis enregistrez.
Vérifiez les services et récupérez le numéro de port.
kubectl get svc longhorn-frontend -n longhorn-system
Puis tapez l'adresse IP du serveur suivi du numéro de port du service.
Mabrouk!!!! Vous avez réussis à installer Longhorn et à y accéder.
Le cluster est composé de 3 nœuds. Chacun des nœuds ont un disque de 12 Go dans ma maquette Proxmox VE.
4-Déploiement d'une application
Après le déploiement de Longhorn, vous pouvez constater qu'il va créer un espace de stockage de type "storageClass". Tapez la commande suivante.
kubectl get sc
Maintenant on va voir comment Longhorn réplique la configuration des applications et pour cela, il nous faudra déployer une application.
Ça tombe bien, on avais pas encore vu ça ensemble donc c'est le moment de mettre le pied à l'étrier.
N'ayez pas peur en lisant la suite, je vais tout vous expliquer.
Vous allez créer 3 fichiers pour l'application jellyfin :
- Un fichier "jellyfin-PersistentVolumeClaim"
- Un fichier "jellyfin-deployement"
- Un fichier "jellyfin-service"
Commençons par "jellyfin-service".
- apiVersion: le type d'API (v1)
- kind : le type d'objet (pod, deployment, service, ingress). Indiquez "Service".
- metadata : indiquez le nom de l'application (app_name)
- spec : ce sont les spécifications du "Service". Indiquez le nom de l'application dans "selector" qui sera utilisé par le "app_name-deployment". Enfin, indiquez le numéro de port interne du pod dans "port" et targetPort" ainsi que le numéro de port externe dans "nodePort"
apiVersion: v1
kind: Service
metadata:
name: jellyfin
spec:
selector:
app: jellyfin
type: NodePort
ports:
- port: 8096
targetPort: 8096
nodePort: 31600
Déployez le fichier.
kubectl apply -f jellyfin-svc.yml
Passons au "jellyfin-PersistentVolumeClaim".
- apiVersion: le type d'API (v1)
- kind : le type d'objet (pod, deployment, service, ingress). Indiquez "PersistentVolumeClaim".
- metadata : donnez un nom à votre PVC (app_name-pvc)
- spec : ce sont les spécifications du "PVC". Indiquez
apiVersion: v1
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: jellyfin-pvc
spec:
storageClassName: longhorn
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Déployez le fichier.
kubectl apply -f jellyfin-pvc.yml
Dans Longhorn, vous pouvez voir qu'un volume vient d'être créer mais qu'il n'est pas encore rattaché.
Enfin, passons au "jellyfin-deployment"
- apiVersion: le type d'API (apps/v1)
- kind : le type d'objet (pod, deployment, service, ingress). Indiquez "Deployment".
- metadata : indiquez le nom de l'application (app_name)
- spec : ce sont les spécifications du "Deployment". Indiquez par exemple que vous souhaitez 3 replicas du pod.
- selector: pour que Kubernetes puisse créer les replicas, indiquez dans matchLabels le nom de l'application.
- template: définissez l'objet à répliquer. Indiquez dans les métadonnées le nom de l'application indiqué dans "selector/matchlabels" (app_name).
- spec: ce sont les spécifications mais cette fois-ci du pod. Indiquez le nom de l'application, le registry et son numéro de port interne. Vous allez également indiquer le nom du volume à monter ainsi que le chemin du dossier puis enfin, vous allez indiquer le nom du PVC.
apiVersion: apps/v1
kind: Deployment
metadata:
name: jellyfin
spec:
replicas: 3
selector:
matchLabels:
app: jellyfin
template:
metadata:
labels:
app: jellyfin
spec:
containers:
- name: jellyfin
image: linuxserver/jellyfin
ports:
- containerPort: 8096
volumeMounts:
- name: jellyfin-data
mountPath: /config
volumes:
- name: jellyfin-data
persistentVolumeClaim:
claimName: jellyfin-pvc
Déployez le fichier.
kubectl apply -f jellyfin-deployment.yml
Récupérez chaque IP du cluster et vérifiez si l'application fonctionne.
kubectl get nodes -o wide
Vous pouvez voir sur les captures d'écran que l’application est bien fonctionnelle.
Retournez sur Longhorn et vous verrez que le PVC n'est plus en statut "Detached" mais en statut "Healty".
Allez dans "Volume" et cliquez sur le nom du PVC.
On vois bien que la configuration du pod est répliquée sur l'ensemble des nœuds du cluster.
Je pense que c'est pas mal.
Si une suite à ce tutoriel, j'borderai le cas des sauvegardes et des instantanées. Ça parlera entre autres de NFS, Amazon S3 et MinIO
Sources :