GlusterFS

GlusterFS offre un’alternativa flessibile e facilmente deployabile per la gestione dello storage distribuito. L’articolo illustra le sue principali caratteristiche, il confronto con CephFS e l’integrazione in ambienti Docker Swarm.

  ·   5 min read

GlusterFS è un file system di rete open source sviluppato da RedHat. A differenza di CephFS, è ideale per soluzioni semplici e rapide da deployare. Al contrario, Ceph offre funzionalità più avanzate e una migliore gestione dei carichi di lavoro intensi, a costo di una maggiore complessità di configurazione e manutenzione.

La situazione finale sarà quella di avere N nodi con un volume GlusterFS condiviso tra tutti. Su ciascun nodo verrà installato Docker e configurato un cluster Swarm. Per maggiori informazioni, si rimanda alla lettura dei precedenti articoli Docker Swarm e MicroCeph e anche Bilanciamento del carico con HAProxy.

Configurazione degli host #

Dal nostro nodo PVE, possiamo creare tre VM a partire da un template, avendo cura di aggiungere un secondo disco di storage dedicato a GlusterFS. Per ulteriori dettagli, leggere la guida dedicata alla creazione di una VM in PVE.

Nel nostro caso, abbiamo creato i seguenti 3 nodi basati su Debian:

  • swarm-master: 10.10.1.10
  • swarm-worker1: 10.10.1.11
  • swarm-worker2: 10.10.1.12

Su ciascun nodo, si deve partizionare il secondo disco e formattarlo in ext4, tramite i comandi fdisk e mkfs.

Per l’automount della partizione, una volta recuperato l’ID, creato la directory in cui questa sarà montata, si deve modificare il file /etc/fstab di conseguenza. Ad esempio:

root@master:~# ll /dev/disk/by-uuid/
lrwxrwxrwx 1 root root 10 May  2 14:37 99c6a00f-e14d-4791-90a5-291b121421bd -> ../../sdb1

root@master:~# mkdir -p /mnt/glusterfs

root@master:~# cat /etc/fstab
UUID=99c6a00f-e14d-4791-90a5-291b121421bd	/mnt/glusterfs	ext4	defaults 0	0

Su ciascun nodo, dare quindi il comando systemctl daemon-reload e successivamente mount -a in modo che il filesystem sia montato in automatico.

La situazione finale dovrebbe essere simile alla seguente:

root@master:~# lsblk -f
NAME    FSTYPE  FSVER LABEL  UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1  ext4    1.0          69b8ba3e-57a4-4ec6-abf8-cd5aff4935bc   13.7M    94% /
├─sda14
└─sda15 vfat    FAT16        4E07-7ABB                             112.1M     9% /boot/efi
sdb
└─sdb1  ext4    1.0          99c6a00f-e14d-4791-90a5-291b121421bd   29.7G     0% /mnt/glusterfs

Installazione di GlusterFS e Docker #

Per l’installazione di GlusterFS su Debian, seguire la documentazione ufficiale. Infine abilitare il seguente servizio: systemctl enable --now glusterfsd.service.

Anche per l’installazione di Docker su Debian, si consiglia di seguire la guida ufficiale.

Inizializzazione dello storage #

Dal nodo master, dare i seguenti comandi per la creazione del cluster storage:

gluster peer probe <ip-node>

gluster peer probe 10.10.1.11
gluster peer probe 10.10.1.12

Per verificarne lo stato di salute esiste il comando gluster peer status:

root@master:~# gluster peer status
Number of Peers: 2

Hostname: 10.10.1.12
Uuid: 4d03ab18-ef27-4d30-adfc-90c1359f6155
State: Peer in Cluster (Connected)

Hostname: 10.10.1.11
Uuid: fad285cd-23c9-43ff-aec7-c9e60e947e42
State: Peer in Cluster (Connected)

Per visualizzare i nodi attivi all’interno del cluster storage, esiste anche il comando gluster pool list, che fornisce un elenco dettagliato dei nodi che compongono il cluster, mostrando informazioni chiave come l’UUID, l’indirizzo IP e lo stato di connessione di ciascun nodo:

root@master:~# gluster pool list
UUID					Hostname  	State
4d03ab18-ef27-4d30-adfc-90c1359f6155	10.10.1.12	Connected
fad285cd-23c9-43ff-aec7-c9e60e947e42	10.10.1.11	Connected
0ed2edbd-908a-4430-b69b-a0498c7b6b97	localhost 	Connected

Creazione del volume GlusterFS #

Per creare e avviare il volume, dare i seguenti comandi:


gluster volume create <volume-name> replica <number-of-replicas> <node1>:<path> <node2>:<path> force

root@master:~# gluster volume create docker replica 3 10.10.1.10:/mnt/glusterfs/ 10.10.1.11:/mnt/glusterfs/ 10.10.1.12:/mnt/glusterfs/ force

root@master:~# gluster volume start docker

Per visualizzare tutte le informazioni in merito al volume appena creato:

root@master:~# gluster volume info

Volume Name: docker
Type: Replicate
Volume ID: faa0d6b7-be58-4064-a809-1be3b6f9107d
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: 10.10.1.10:/mnt/glusterfs
Brick2: 10.10.1.11:/mnt/glusterfs
Brick3: 10.10.1.12:/mnt/glusterfs
Options Reconfigured:
performance.client-io-threads: off
transport.address-family: inet
storage.fips-mode-rchecksum: on
cluster.granular-entry-heal: on

Montare il volume GlusterFS #

Su ciascun nodo, creare il punto di mount che verrà utilizzato per i volumi docker tramite il comando mkdir -p /opt/docker. Quindi, creare il file /etc/systemd/system/opt-docker.mount per gestire il mount del volume:

[Unit]
Description=GlusterFS Mount
After=glusterd.service
Requires=glusterd.service

[Mount]
What=localhost:/docker
Where=/opt/docker
Type=glusterfs
Options=defaults,_netdev,noatime

[Install]
WantedBy=multi-user.target

Avviare e abilitare il mount col comando systemctl enable --now opt-docker.mount

A questo punto si avrà a disposizione /opt/docker come storage ridondato e sincronizzato per i vari volumi Docker. Questo approccio garantisce che i dati siano distribuiti e replicati attraverso i nodi, migliorando la disponibilità e la resilienza.

In alternativa alla creazione di un file di mount systemd, si può configurare il mount di GlusterFS aggiungendo la seguente riga nel file /etc/fstab di ciascun nodo:

localhost:/docker /opt/docker glusterfs defaults,_netdev,noatime,x-systemd.automount 0 0

Dopo aver aggiornato il file /etc/fstab, eseguire il seguente comando per ricaricare la configurazione di systemd e montare tutte le voci specificate:

systemctl daemon-reload && mount -a

Docker Swarm #

Riferirsi alla seguente guida per creare il cluster e aggiungere i vari nodi.

Una volta completata la configurazione del cluster, creare la seguente directory e il file index.html:

mkrir -p /opt/docker/nginx/html && echo "NGINX SWARM" > /opt/docker/nginx/html/index.html

Infine, solo sul nodo master, creare il file docker-compose.yml di esempio, che configura un web server NGINX per servire la pagina index.html:

services:
  webapp:
    image: nginx:latest
    volumes:
      - /opt/docker/nginx/html:/usr/share/nginx/html
    ports:
      - "8080:80"
    deploy:
      replicas: 3

Infine, avviare lo stack con il seguente comando:

root@master:~# docker stack deploy -c docker-compose.yml website

Accedendo al browser web e collegandosi agli indirizzi http://10.10.1.10:8080/ (master), http://10.10.1.11:8080/ (nodo1) o http://10.10.1.12:8080/ (nodo2), sarà visibile la pagina web creata in precedenza.

HAProxy #

Per avere maggiori informazioni e dettagli, riferirsi all’articolo Bilanciamento del carico con HAProxy. In particolare, un esempio del file di configurazione /etc/haproxy/haproxy.cfg:

frontend webfrontend
    bind 10.10.1.5:80
    mode http
    option httpclose
    default_backend nodes_backend

backend nodes_backend
    mode http
    balance roundrobin
    option httpchk GET /
    server node1 10.10.1.10:8080 check
    server node2 10.10.1.11:8080 check
    server node3 10.10.1.12:8080 check

Collegandosi all’indirizzo 10.10.1.5 tramite un qualsiasi browser, la richiesta verrà instradata da HAProxy a uno dei tre nodi. Questo approccio garantisce che, in caso di malfunzionamento di uno dei nodi, il sito rimanga comunque accessibile.

nginx-swarm

Riferimenti #