---
categories: cloud storage haute-disponibilite
title: Howto GlusterFS
...

* Documentation : <https://docs.gluster.org/en/latest/>

**GlusterFS** est un système de fichier distribué permettant d'utiliser le stockage de plusieurs serveurs pour un seul système de fichier. On peut l'utiliser en mode réplication, où chaque fichier est répliqué sur plusieurs serveurs afin d'augmenter sa disponibilité en cas de coupures (un peu comme du RAID1), ou en mode distribué, où les fichiers ne sont pas tous sur un même serveur (un peu comme du RAID0), ou un mixe des deux.

## Vocabulaire de GlusterFS

<dl>
  <dt>Cluster</dt>
  <dd>Un groupe de serveurs partageant une configuration GlusterFS commune.</dd>

  <dt>Peer</dt>
  <dd>Un serveur qui est membre du cluster.</dd>

  <dt>Brick</dt>
  <dd>L'emplacement physique utilisé pour le stockage des données d'un volume.</dd>

  <dt>Volume</dt>
  <dd>Un stockage logique exporté par GlusterFS.</dd>
</dl>

## Configuration d'un nouveau cluster

### Installation

~~~
# apt install glusterfs-server
~~~

Il est ensuite possible de vérifier que GlusterFS est installé avec :

~~~
# glusterd --version
glusterfs 9.2
Repository revision: git://git.gluster.org/glusterfs.git
[...]
~~~

### Création du cluster

Après avoir installé `glusterfs-server` sur l'ensemble des serveurs du futur cluster, il faut ajouter les serveurs à leur liste de serveurs de confiance. `glusterd` s'occupe de communiquer la liste entre chaque serveur déjà présent dans la liste, et l'ajout est symétrique, il suffit donc de faire la commande suivante sur une seule machine du cluster (1 fois par serveur à ajouter) :

~~~
srv1# gluster peer probe <adresse IP srv2>
peer probe: success. 
~~~

> Note : Les serveurs doivent pouvoir communiquer entre eux sans restriction au niveau réseau (techniquement ils ont besoin d'accès à : 24007/TCP, 24008/TCP, */UDP et `base-port`-`max-port`/TCP (à priori 49152-60999/TCP)). Le port 24007 étant particulièrement important, étant celui utilisé pour ajouter des serveurs dans la liste des serveurs de confiances.

Pour vérifier que les serveurs ont bien été ajoutés, faire la commande suivante sur un des serveurs du cluster :

~~~
# gluster peer status
Number of Peers: 1

Hostname: xxx
Uuid: xxxxx
State: Peer in Cluster (Connected)
~~~

### Création d'un volume

Ici `/srv/gluster/` est un montage d'un volume dédié pour GlusterFS et le volume à créer se nomme `foovol`.

Créer le répertoire sur chaque serveur :

~~~
# mkdir /srv/gluster/foovol
~~~

Puis sur un des serveurs, créer le volume GlusterFS

~~~
# gluster volume create foovol replica 2 <IP srv1>:/srv/gluster/foovol <IP srv2>:/srv/gluster/foovol
volume create: foovol: success: please start the volume to access data
# gluster volume start foovol
volume start: foovol: success
~~~

> Note: Un volume en mode replica avec seulement 2 réplications comme ci-dessus est fortement sensible aux split-brain, il est donc recommandé d'utiliser au moins 3 serveurs et `replica 3`. En général, le mode réplica devrait être utilisé avec `2n+1` replica, où `n` est le nombre de serveurs de stockage pouvant tomber sans coupures de service.

Vérification :

~~~
# gluster volume info
gluster volume info
 
Volume Name: foovol
Type: Replicate
Volume ID: [...]
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: <addresse IP srv1>:/srv/gluster/foovol
Brick2: <addresse IP srv2>:/srv/gluster/foovol
[...]
~~~

Sur la machine cliente, on peut maintenant monter le volume :

~~~
# echo "srv1:/foovol /mnt/foovol glusterfs defaults  0   0" >>/etc/fstab
# mkdir /mnt/foovol
# mount /mnt/foovol
~~~

## Administration

Vérifier l'état global des volumes GlusterFS :

~~~
# gluster volume status <volume|all>
~~~

Obtenir la liste des clients glusterfs et leur utilisation des différentes bricks :

~~~
# gluster volume status <volume|all> clients
~~~

Autres informations :

~~~
# gluster volume status <volume|all> (mem|fd|inode|callpool)
~~~

### Lister les peers

~~~
# gluster peer status
~~~

### Lister les volumes

~~~
# gluster volume list
~~~

#### Voir la santé du volume "foo"

~~~
# gluster volume heal foo info
~~~

#### Forcer un 'heal' pour le volume "bar"

~~~
#  gluster volume heal bar
~~~

### Cas pratiques 

#### Récupération d'un split-brain - Forcer l'utilisation d'un réplicas comme source de résolution

Dans une situation de split-brain, on peut avoir :

~~~
# gluster volume heal foo info
Brick tic.example.net:/srv/gluster/foovol
<gfid:1b82dc4fd-3d3f-4dc1-89a9-0783b2c10bc> - Is in split-brain

Status: Connected
Number of entries: 1

Brick tac.example.net:/srv/gluster/foovol
<gfid:1b82dc4fd-3d3f-4dc1-89a9-0783b2c10bc> - Is in split-brain

Status: Connected
Number of entries: 1
~~~

Dans ce cas, on peut définir que c'est le réplica "tic" qui va être utilisé pour rétablir le reste du cluster avec la commande : 

~~~
# gluster volume heal foo split-brain source-brick tic.example.net:/srv/gluster/foovol gfid:1b82dc4fd-3d3f-4dc1-89a9-0783b2c10bc
Healed gfid:1b82dc4fd-3d3f-4dc1-89a9-0783b2c10bc
~~~

[Plus de documentation](https://docs.gluster.org/en/v3/Troubleshooting/resolving-splitbrain/)

#### Volume éteint sur l'un des serveurs glusterfs

Dans le cas où un volume est éteint sur l'un des serveurs, la solution la plus simple pour revenir dans un état nominal est de redémarré le service `glusterd` sur ce serveur :

```
# systemctl restart glusterd
```

## Monitoring

### Nagios (coté serveur)

> Ce plugin, sans modification, provoque des faux-positifs dans le cas où glusterfs n'utilise pas les FQDN des serveurs.

Le monitoring de GlusterFS au niveau des serveurs du cluster peut se faire avec le plugin [atlantos/nagios-check-gluster](https://github.com/atlantos/nagios-check-gluster).

Celui-ci surveille :

* que `glusterd` soit bien démarré sur le serveur,
* que les peer sont bien connectés,
* que les volumes sont bien démarrés,
* que les services servant à l'export des données des volumes soient bien démarrés,
* (si voulu, et par défaut) que les services de correction automatique de la synchronisation soient bien démarrés,
* (si voulu, et par défaut) que les services de détection du "Bitrot" soient bien démarrés,
* (si voulu, et par défaut) que les services (interne) d'export par NFS soient bien démarrés (ils ne sont pas utilisés lors de l'export par Ganesha),
* (si voulu, et par défaut) qu'il n'y a pas de problèmes de synchronisation,
* (si voulu, et par défaut) que le check de "Bitrot" ne retourne aucune erreur.

Ce plugin a besoin de tourner en tant que `root`.

## Export de volumes par NFS

> `glusterd` peut techniquement exporter nativement un volume par NFS mais cette fonctionnalité n'est pas compilée dans le paquet dans les dépôts Debian.

> L'export par Ganesha est aussi nécessaire pour faire de la Haute Disponibilité avec NFS.

L'export d'un volume GlusterFS par NFS peut se faire par [Ganesha](https://nfs-ganesha.github.io/). Pour ce faire, il faut installer les paquets `nfs-ganesha` et `nfs-ganesha-gluster` :

~~~
apt install nfs-ganesha nfs-ganesha-gluster
~~~

Il faut ensuite définir un export tel que :

~~~
EXPORT {
    Export_Id = <nombre>; # Identifiant interne à Ganesha pour cet export, doit être un nombre entre 1 et 65535

    Path = "<volume_path>"; # Chemin du volume à être exporté, peut être '/<volume_name>' par exemple
    Pseudo = "<pseudo_path>"; # pseudo chemin pour NFSv4

    Access_Type = <None|RW|RO|MDONLY|MDONLY_RO>;

    Disable_ACL = TRUE; # Obligatoire si les ACL ne sont pas activés au niveau du système de fichier sous-jacent

    FSAL {
        Name = "GLUSTER";
        Hostname = "<nom_de_domaine|adresse_ip>"; # Adresse du serveur glusterfs à contacter, probablement localhost
        Volume = "<nom_du_volume_glusterfs>";
    }
}
~~~

et configurer Ganesha pour glusterfs (fichier: `/etc/ganesha/ganesha.conf`):

~~~
NFS_Core_Param {
    NSM_Use_Caller_Name = true;
}

%include "</chemin/vers/fichier/configurant/l'export>"
~~~

Puis redémarrer Ganesha :

~~~
systemctl restart nfs-ganesha.service
~~~

L'export devrait maintenant être en place.

### Haute-disponibilité

La gestion de la haute disponibilité avec NFS se fait avec [Pacemaker](/HowtoPacemaker).
