Mise en place d’un cluster glusterfs sur raspberry pi pour kubernetes

Jusqu’à maintenant lorsque j’avais besoin d’un volume persistent sur mon cluster k3s j’utilisais un montage nfs depuis un des noeuds du cluster. Je me suis donc mis en quête d’un système de fichier réseau synchronisé et j’ai fait le choix de tester dans un premier temps glusterfs.

Installation de glusterfs sur les 3 noeuds de mon cluster de raspberry pi

J’ai pris 3 rpi 3B+ avec hypriot comme os sur lequel j’ai monté 3 clés USB de 64Gb. Commençons par identifier le nom du device sur lequel est installé la clé USB.

sudo lsblk
*NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    1 57.3G  0 disk
└─sda1        8:1    1 57.3G  0 part
mmcblk0     179:0    0 14.4G  0 disk
├─mmcblk0p1 179:1    0   64M  0 part /boot
└─mmcblk0p2 179:2    0 14.4G  0 part /

Lés clés sont montées sur les 3 rpi sur le device /dev/sda. Créons le filesystem qui accueillera les données :

sudo fdisk -w auto /dev/sda
g
n
(Valider les valeurs par défaut pour les 3 questions)
w

Formatons la partition et montons-la:

sudo mkfs.xfs -f -L myvol-brick1 /dev/sda1
sudo mkdir -p /data/glusterfs/myvol1/brick1/
printf $(sudo blkid -o export /dev/sda1|grep PARTUUID)" /data/glusterfs/myvol1/brick1 xfs defaults,noatime 1 2\n" | sudo tee -a /etc/fstab
sudo mount /data/glusterfs/myvol1/brick1

Installons le service glusters et démarrons le sur les 3 noeuds :

apt install glusterfs-server glusterfs-client -y
sudo systemctl enable glusterd
sudo systemctl start glusterd

Ajoutons les 2 autres noeuds sur lesquels vous aurez exécuté toutes les commandes ci-dessus également au préalable.

sudo gluster peer probe rpi2
sudo gluster peer probe rpi3
sudo gluster peer status
Number of Peers: 2

Hostname: rpi2
Uuid: f8e6bab0-ffed-4d89-86cc-af6d702a8eca
State: Peer in Cluster (Connected)

Hostname: rpi3
Uuid: f31ad7b1-78f5-4d95-811f-bb9d765a1953
State: Peer in Cluster (Connected)

Créons le volume avec les 3 noeuds :

sudo gluster volume create myvol1 replica 3 rpi1:/data/glusterfs/myvol1/brick1/brick rpi2:/data/glusterfs/myvol1/brick1/brick rpi3:/data/glusterfs/myvol1/brick1/brick

Démarrons le volume:

sudo gluster volume start myvol1sudo gluster volume start myvol1
volume start: myvol1: success

Faisons un test depuis notre noeud rpi1 :

sudo mkdir -p /mnt/myvol1
sudo mount -t glusterfs localhost:/myvol1 /mnt/myvol1
sudo touch /mnt/myvol1/toto
sudo umount /mnt/myvol1

Vérifions que le fichier toto est bien présent sur les 3 rpi:

ls -al /data/glusterfs/myvol1/brick1/brick

Montage du glusterfs sur notre cluster kubernetes k3s

Normalement glusterfs est pris en charge par kubernetes mais donc mon cas impossible de le faire fonctionner. Pour le moment je vais simplement le monter en nfs sur le noeud master de mon cluster et créer une storageClass pour mes futurs volumes persistants.

Dans un premier temps installons la partie client de glusterfs

sudo apt install glusterfs-client

Maintenant ajoutons cette ligne à fstab :

sudo mkdir -p /mnt/myvol1
sudo vi /etc/fstab
rpi1:/myvol1 /mnt/myvol1 glusterfs defaults,_netdev 0 0
````
Montons le et vérifions que notre fichier toto est présent:

```bash
sudo mount /mnt/myvol1
cd /mnt/myvol1
ls

il l’est super effaçons le :

sudo rm toto

Normalement en vous rendant sur dans le répertoire /data/glusterfs/myvol1/brick1/brick sur vos raspberry le fichier toto devrait avoir disparu :)

Finissons par installer la partie nfs-server:

sudo apt install nfs-server
sudo vi /etc/exports

Ajouter cette ligne en fin de fichier

/mnt/myvol1 *(rw,fsid=1,sync,no_root_squash,no_all_squash)

sudo systemctl enable nfs-server
sudo systemctl restart nfs-server

Vérifions que le répertoire est bien partagé :

sudo exportfs

/mnt/myvol1     <world>

Création de la storage class

Attention il faut installer le package nfs-client sur tous les noeuds de votre cluster kubernetes !

Editez le fichier storage-class.yaml et ajoutez le contenu suivant en modifiant l’ip avec celle de votre node master:

kind: ServiceAccount
apiVersion: v1
metadata:
  name: nfs-client-provisioner-gfs
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-gfs-runner
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner-gfs
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner-gfs
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-gfs-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner-gfs
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner-gfs
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner-gfs
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner-gfs
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage-gfs
  namespace: default
provisioner: fuseim.pri/nfs
parameters:
  archiveOnDelete: "true"
reclaimPolicy: Retain
volumeBindingMode: Immediate
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-client-provisioner-gfs
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner-gfs
    spec:
      serviceAccountName: nfs-client-provisioner-gfs
      containers:
        - name: nfs-client-provisioner-gfs
          image: quay.io/external_storage/nfs-client-provisioner:v3.1.0-k8s1.11
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/nfs
            - name: NFS_SERVER
              value: 192.168.1.43
            - name: NFS_PATH
              value: /mnt/myvol1
          resources:
            requests:
              cpu: 400m
              memory: 512M
            limits:
              cpu: 800m
              memory: 1024M
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.1.43
            path: /mnt/myvol1

Appliquons et vérifions que le montage est présent dans le pod :

kubectl apply -f storage-class.yaml
kubectl exec -it nfs-client-provisioner-gfs-774cc8f97c-qvqcx /bin/sh
touch toto

Allez sur vos raspberry et vérfiez que le fichier toto est apparu dans le répertoire /data/glusterfs/myvol1/brick1/brick

A vous les volumes persistants répliqués sur plusieurs nodes !!!


Alimenter un blog comme celui-ci est aussi passionnant que chronophage. En passant votre prochaine commande (n'importe quel autre article) au travers des liens produits ci-contre, je touche une petite commission sans que cela ne vous coûte plus cher. Cela ne me permet pas de gagner ma vie, mais de couvrir les frais inhérents au fonctionnement du site. Merci donc à vous!

comments powered by Disqus