Установка и настройка GlusterFS на двух нодах с репликацией тома
Ноды, на которых устаналивается GlusterFS-сервер используют Debian9
1 2 |
proxmox6.mydomain.com - 192.168.100.1 proxmox7.mydomain.com - 192.168.100.2 |
В качестве GlusterFS-сервера используем Ubuntu16.04 LTS
Установка GlusterFS-сервера на обоих нодах
Создание и выполнение скрипта для добавления репозитария GlusterFS на Debian
1 |
# nano add_repo.sh |
1 2 3 4 5 6 |
# /bin/bash wget -O - https://download.gluster.org/pub/gluster/glusterfs/4.1/rsa.pub | apt-key add - DEBID=$(grep 'VERSION_ID=' /etc/os-release | cut -d '=' -f 2 | tr -d '"') DEBVER=$(grep 'VERSION=' /etc/os-release | grep -Eo '[a-z]+') DEBARCH=$(dpkg --print-architecture) echo deb https://download.gluster.org/pub/gluster/glusterfs/LATEST/Debian/${DEBID}/${DEBARCH}/apt ${DEBVER} main > /etc/apt/sources.list.d/gluster.list |
1 |
# chmod +x add_repo.sh |
1 |
# bash add_repo.sh |
Проверяем добавленный репозитарий
1 |
# cat /etc/apt/sources.list.d/gluster.list |
1 |
deb https://download.gluster.org/pub/gluster/glusterfs/LATEST/Debian/9/amd64/apt stretch main |
1 |
# apt-get update && apt-get install glusterfs-server |
1 |
# systemctl status glusterd |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
● glusterd.service - GlusterFS, a clustered file-system server Loaded: loaded (/lib/systemd/system/glusterd.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2018-05-17 22:05:44 BST; 34s ago Process: 12431 ExecStart=/usr/sbin/glusterd -p /var/run/glusterd.pid --log-level $LOG_LEVEL $GLUSTERD_OPTIONS (code=exited, status=0/SUCCESS) Main PID: 12438 (glusterd) Tasks: 8 (limit: 4915) Memory: 5.9M CPU: 657ms CGroup: /system.slice/glusterd.service └─12438 /usr/sbin/glusterd -p /var/run/glusterd.pid --log-level INFO May 17 22:05:43 proxmox6 systemd[1]: Starting GlusterFS, a clustered file-system server... May 17 22:05:44 proxmox6 systemd[1]: Started GlusterFS, a clustered file-system server. |
1 |
# systemctl status glustereventsd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
● glustereventsd.service - Gluster Events Notifier Loaded: loaded (/lib/systemd/system/glustereventsd.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2018-05-17 22:05:44 BST; 1min 0s ago Main PID: 12486 (python) Tasks: 2 (limit: 4915) Memory: 10.2M CPU: 69ms CGroup: /system.slice/glustereventsd.service ├─12486 python /usr/sbin/glustereventsd --pid-file /var/run/glustereventsd.pid └─12538 python /usr/sbin/glustereventsd --pid-file /var/run/glustereventsd.pid May 17 22:05:44 proxmox6 systemd[1]: Started Gluster Events Notifier. May 17 22:05:44 proxmox6 glustereventsd[12486]: Unable to get Port details from Config |
Создание trusted storage pool(TSP) из двух нод
Проверяем состояние кластера
1 |
proxmox6 ~ # gluster peer status |
1 |
Number of Peers: 0 |
Добавялем в кластер вторую ноду(proxmox7)
1 |
proxmox6 ~# gluster peer probe proxmox7 |
1 |
peer probe: success. |
Примечние: локальный хост,на котором выполняем команду, добавлять не нужно(т.е. не требуется выполнять gluster peer probe proxmox6)
Проверяем состояние кластера на первой ноде(proxmox6)
1 |
proxmox6 ~ # gluster peer status |
1 2 3 4 |
Number of Peers: 1 Hostname: proxmox7 Uuid: b2e90b28-6f83-452f-a18d-aa8d6f030d39 State: Peer in Cluster (Connected) |
Проверяем состояние кластера на второй ноде(proxmox7)
1 |
proxmox7 ~ # gluster peer status |
1 2 3 4 5 |
Number of Peers: 1 Hostname: proxmox6 Uuid: 8c6b91c0-b007-4990-be79-da43935760b5 State: Peer in Cluster (Connected) |
Настройка GlusterFS Volume
Создание реплицируемого тома с именем gvolume1
На обоих нодах создаем каталог, в котором будет размещаться том
1 |
# mkdir /gluster-storage |
Желательно под GlusterFS том выделать отдельный диск или раздел диска
В данном случае GlusterFS-том размещается на корневой файловой системе
Если том создается на корневом разделе ноды( а не на отдельном диски/разделе, как рекомендуют разработчики GlusterFS, то используем опцию force)
1 |
# gluster volume create gvolume1 replica 2 transport tcp proxmox6:/gluster-storage proxmox7:/gluster-storage force |
1 |
volume create: gvolume1: success: please start the volume to access data |
Запуск тома
1 |
# gluster volume start gvolume1 |
1 |
volume start: gvolume1: success |
Просмотр информации о томе
1 |
# gluster volume info |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Volume Name: gvolume1 Type: Replicate Volume ID: 4ee9c0bc-bdcc-4568-9ccc-c1b94e5f60ff Status: Started Snapshot Count: 0 Number of Bricks: 1 x 2 = 2 Transport-type: tcp Bricks: Brick1: proxmox6:/gluster-storage Brick2: proxmox7:/gluster-storage Options Reconfigured: transport.address-family: inet nfs.disable: on performance.client-io-threads: off |
Уменьшим время в течение котрого клиент ожидает ответ от сервера и в случае недоступности сервера автоматически переподключается к другому серверу в trusted storage pool(по умолчанию таймаут 42 секунды, что вынуждает клиента ожидать 42 секунды, чтобы переключитя на другую ноду,если текущая не отвечает)
1 |
# gluster volume set gvolume1 network.ping-timeout "5" |
1 |
volume set: success |
1 |
# gluster volume info | grep timeout |
1 |
network.ping-timeout: 5 |
1 |
# gluster volume get gvolume1 network.ping-timeout |
1 2 3 |
Option Value ------ ----- network.ping-timeout 5 |
Ограничение доступа к volume gvolume1(разрешаем монтировать только нашим клиентам)
1 2 3 |
# gluster volume set gvolume1 auth.allow 192.168.100.1,192.168.100.2,192.168.100.3,192.168.100.4 |
1 |
# gluster volume info gvolume1 | grep auth |
1 |
auth.allow: 192.168.100.1,192.168.100.2,192.168.100.3,192.168.100.4 |
Для того, чтобы убрать ограничение(тем самым разрешить доступ к тому со всех хостов/клиентов)
1 |
# gluster volume set volume1 auth.allow * |
Просмотр компонентов gluster
1 |
# gluster volume status |
1 2 3 4 5 6 7 8 9 10 11 |
Status of volume: gvolume1 Gluster process TCP Port RDMA Port Online Pid ------------------------------------------------------------------------------ Brick proxmox6:/gluster-storage 49152 0 Y 29895 Brick proxmox7:/gluster-storage 49152 0 Y 17244 Self-heal Daemon on localhost N/A N/A Y 498 Self-heal Daemon on proxmox7 N/A N/A Y 2992 Task Status of Volume gvolume1 ------------------------------------------------------------------------------ There are no active volume tasks |
1 |
# gluster volume list |
1 |
gvolume1 |
Просмотр всех ключей
1 |
# gluster volume get gvolume1 all |
Фильтрация нужных ключей
1 |
# gluster volume get gvolume1 all | grep -E 'performance.write-behind-window-size|performance.cache-refresh-timeout|performance.cache-size|cluster.stripe-block-size|performance.io-thread-count' |
1 2 3 4 5 6 |
cluster.stripe-block-size 128KB performance.cache-refresh-timeout 1 performance.cache-size 32MB performance.io-thread-count 16 performance.cache-size 128MB performance.write-behind-window-size 1MB |
Тюнинг
1 |
# gluster volume set gvolume1 performance.cache-size 2GB |
1 |
# gluster volume set gvolume1 performance.io-thread-count 32 |
1 |
# gluster volume set gvolume1 performance.client-io-threads on |
Список наиболее часто запрашиваемых файлов
1 |
# gluster volume top gvolume1 open list-cnt 10 |
Список файлов наиболее часто запрашиваемых для чтения
1 |
# gluster volume top gvolume1 read list-cnt 10 |
Список файлов наиболее часто запрашиваемых для записи
1 |
# gluster volume top gvolume1 write list-cnt 10 |
Список каталогов наиболее часто запрашиваемых для открытия
1 |
# gluster volume top gvolume1 opendir list-cnt 10 |
Измерение полосы пропускания чтения(скорости чтения)
1 |
# gluster volume top gvolume1 read-perf bs 4096 count 250000 list-cnt 10 |
Измерение полосы пропускания записи (скорости записи)
1 |
# gluster volume top gvolume1 write-perf bs 4096 count 250000 list-cnt 10 |
Просмотр ожидающих вызовов тома
1 |
# gluster volume status gvolume1 callpool |
Просмотр lдетальной информации о томе
1 |
# gluster volume status gvolume1 detail |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
Status of volume: gvolume1 ------------------------------------------------------------------------------ Brick : Brick proxmox6:/gluster-storage TCP Port : 49152 RDMA Port : 0 Online : Y Pid : 29895 File System : ext4 Device : /dev/md2 Mount Options : rw,relatime,data=ordered Inode Size : 256 Disk Space Free : 176.4GB Total Disk Space : 203.1GB Inode Count : 13533184 Free Inodes : 13241929 ------------------------------------------------------------------------------ Brick : Brick proxmox7:/gluster-storage TCP Port : 49152 RDMA Port : 0 Online : Y Pid : 6849 File System : ext4 Device : /dev/md2 Mount Options : rw,relatime,data=ordered Inode Size : 256 Disk Space Free : 171.9GB Total Disk Space : 203.1GB Inode Count : 13533184 Free Inodes : 13095280 |
1 |
root@proxmox6 ~ # gluster volume status gvolume1 clients |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Client connections for volume gvolume1 ---------------------------------------------- Brick : proxmox6:/gluster-storage Clients connected : 2 Hostname BytesRead BytesWritten OpVersion -------- --------- ------------ --------- 192.168.100.1:49148 3816928 4933400 40000 192.168.100.2:49133 1332 1356 40000 ---------------------------------------------- Brick : proxmox7:/gluster-storage Clients connected : 2 Hostname BytesRead BytesWritten OpVersion -------- --------- ------------ --------- 192.168.100.1:49135 11172 10412 40000 192.168.100.2:49129 3795256 4907292 40000 |
1 |
# gluster volume status gvolume1 mem |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
Memory status for volume : gvolume1 ---------------------------------------------- Brick : proxmox6:/gluster-storage Mallinfo -------- Arena : 201306112 Ordblks : 29531 Smblks : 2884 Hblks : 9 Hblkhd : 16203776 Usmblks : 0 Fsmblks : 316352 Uordblks : 36540224 Fordblks : 164765888 Keepcost : 122592 ---------------------------------------------- Brick : proxmox7:/gluster-storage Mallinfo -------- Arena : 77766656 Ordblks : 29316 Smblks : 821 Hblks : 9 Hblkhd : 16203776 Usmblks : 0 Fsmblks : 82224 Uordblks : 36277424 Fordblks : 41489232 Keepcost : 122592 ---------------------------------------------- |
Профилирование тома
1 |
# gluster volume profile gvolume1 start |
1 |
# gluster volume profile gvolume1 info |
1 |
# gluster volume profile gvolume1 stop |
Наcтройка клиента
Клиенты будут использовать Ubuntu16.04 LTS
1 |
# nano /etc/hosts |
1 2 3 |
…………… 192.168.100.1 proxmox6.mydomain.com proxmox6 192.168.100.2 proxmox7.mydomain.com proxmox7 |
Загрузка модуля fuse и добавление такой загрузки в автозагрузку
1 |
# nano /etc/modules |
1 |
fuse |
1 |
# modprobe fuse |
Версию Glusterfs-клиента устанавливаю таку же,как и установлена версия GlusterFS на сервере
В данном случае 4.1
https://launchpad.net/~gluster
https://launchpad.net/~gluster/+archive/ubuntu/glusterfs-4.1
1 |
# apt-get install -y software-properties-common |
1 |
# add-apt-repository ppa:gluster/glusterfs-4.1 |
1 |
# apt-get update |
1 |
# apt-get install glusterfs-client |
Только для контейнера
1 |
# mknod /dev/fuse c 10 229 |
1 |
# ls -al /dev/fuse |
1 |
crw-r--r-- 1 root root 10, 229 May 17 23:19 /dev/fuse |
Монтируем реплицируемый том с GlusterFS-сервера
1 |
# mount -t glusterfs proxmox6:/gvolume1 /home/ |
Если ошибок нет,то размонтируем и добавим в /etc/fstab для автомонтирования тома
1 |
# umount /home |
1 |
# nano /etc/fstab |
1 |
proxmox6:/gvolume1 /home glusterfs defaults,_netdev 0 0 |
1 |
# mount -a |
1 |
# df -h | grep -E 'Filesystem|home' |
1 2 |
Filesystem Size Used Avail Use% Mounted on proxmox6:/gvolume1 204G 34G 162G 18% /home |
Если в течение 5 секунд не будет связи с Proxmox6-сервером,то клиент автоматически переподключится к серверу proxmox7
Просмотр процессов|файлов/каталогов, использующих точку монтирования на клиенте
1 |
# lsof /home |
1 |
# fuser -u -m /home |
Остановка процессов использующих каталог /home
1 |
# fuser -STOP /home |
Если не помогает,то
1 |
# fuser -k /home |
1 |
# fuser -u -m /home |
Отмонтироание каталога /home
1 |
# umount /home |
GlusterFS split-brain
Существует 3 типа split-brain
1 2 3 |
1.Data-spli-brain – информация в файлах отличается на разных кирипичиках реплики(т.е. разное содержимое файлов, находящихся в каталоге /gluster-storage на нодах) 2.Metadata-split-brain – аналогично,но не информация/содержимое отличается, а метаданные(группа,владелец,права,атрибуты) 3.Entry/gfid-split-brain – GlusterFS-иденитификаторы(GFID) различаются для одного и того же файла на разных кирпичиках одной реплики |
Entry/gfid — этот тип split-brain НЕ МОЖЕТ бать исправлен с помощью автоматического heal
Проcмотр всех файлов,которые требуют healing ( и будут обработаны демоном self-heal)
1 |
# gluster volume heal gvolume1 info |
Проверка,включен ли демон self-heal
1 |
# gluster volume get gvolume1 all | grep 'self-heal-daemon' |
1 |
# cluster.self-heal-daemon on |
Ручной/принудительный запуск self-heal только для файлов,который требуют healing
1 |
# gluster volume heal gvolume1 |
Ручной/принудительный запуск self-heal для ВСЕХ файлов
1 |
# gluster volume heal gvolume1 full |
Просмотр файлов,которые находятся в состоянии split-brain
1 |
# gluster volume heal gvolume1 info split-brain |
Если существуют файлы в статусе split-brain, то родительский каталог, содержащий такие файлы также будет отображен в статусе split-brain
Разрешение/исправление split-brain-файлов
А) с помощью командной строки GlusterFS
Файлы с типом split-brain data и metadata могут быть разрешены одной из указанных ниже политик с командной строки GlusterFS
Файлы с типом split-brain gfid не могут быть разрешены этими политиками
1.Выбор бОльшего по размеру файла, как источника
1 |
# gluster volume heal gvolume1 split-brain bigger-file <FILE> |
Вместо <FILE> можно указывать как имя файла, которое вывела команда
1 |
# gluster volume heal gvolume1 info split-brain |
добавляя перед ним название каталога, из которого создавался том glusterfs на нодах(/gluster-storage в данном случае) либо его GlusterFS-идентификатор(gfid), который также может выводить указанная выше команда
2.Выбор файла по самому времени модификации файла
Т.е. источником будет файл, который изменялся позже всех остальных файлов с таким же именем.
1 |
# gluster volume heal gvolume1 split-brain latest-mtime <FILE> |
3.Выбор ОДНОГО файла на одном из существующих кирпичиков реплицируемого тома
Т.е. источником будет файл на конкретном кирпичике
1 |
# gluster volume heal gvolume1 split-brain source-brick <HOSTNAME:BRICKNAME> <FILE> |
4.Выбор одного из кирпичиков реплики в качестве источника ДЛЯ ВСЕХ файлов
Т.е. когда несколько/множество файлов находятся в состоянии split-brain, то можно в качестве источника для всех этих файлов взять один из кирпичиков реплицируемого тома
1 |
# gluster volume heal gvolume1 split-brain source-brick <HOSTNAME:BRICKNAME> |
Решение для Entry/gfid-типов split-brain файлов
Использование указанных выше политик для entry и gfid-типов split-brain не поддерживается
Т.е. невозможно исправить каталог, например, с помощью команды
1 |
# gluster volume heal gvolume1 split-brain source-brick <HOSTNAME:BRICKNAME> <SPLIT-BRAIN-DIRECTORY> |
Решение такого типа split-brain состоит в удалении проблемных файлов на ВСЕХ кирпичиках реплицируемого тома, КРОМЕ ОДНОГО.
Кроме удаления таких файлов, также необходимо удалить gfid-ссылки на эти файлы, а также все остальные файлы, которые имеют такой же inod(т.е. все hard-линки)
GlusterFS для каждого файла,который находится под ее контролем создает копию этого файла в каталоге /gluster-storage/.glusterfs/ в подкаталоге xx/yy,
где xx/yy первые четыре символа в имени файла,
Где /gluster-storage – каталог, в котором создавался реплициремый том
Например, на ноде есть файл в GlusterFS-хранилище и в каталоге /gluster-storage был создан реплицируемый том(gvolume1)
В этом хранилище существует произвольный файл
1 |
/gluster-storage/file.php |
Для того, чтобы узнать его копию в GlusterFS выполняем команду, которая находит все файлы, которая имеют тот же самый inode, как и split-brain-файл(т.е. находит все hard-ссылки)
1 |
# find /gluster-storage -samefile /gluster-storage/file.php |
1 2 |
/gluster-storage/file.php /gluster-storage/.glusterfs/43/0d/890d0513-640a-454e-82fe-c791fa8e8a0e |
Т.е. GlusterFS-ссылка находится по пути
1 |
/gluster-storage/.glusterfs/43/0d/890d0513-640a-454e-82fe-c791fa8e8a0e |
gfid – GlusterFS-идентификатор файла — 430d0513-640a-454e-82fe-c791fa8e8a0e
43 и 0d вложенные каталоги по пути /gluster-storage/.glusterfs/
Т.е. для разрешения split-brain с файлом /gluster-storage/file.php
Необходимо удалить сам файл
/gluster-storage/file.php
1 |
# rm -f /gluster-storage/file.php |
И его gfid-идентификатор(GlusterFS hard-link)
/gluster-storage/.glusterfs/43/0d/890d0513-640a-454e-82fe-c791fa8e8a0e
1 |
# rm -f /gluster-storage/.glusterfs/43/0d/890d0513-640a-454e-82fe-c791fa8e8a0e |
На всех кирпичиках тома,за исключением одного, файл на котором будет исходным.
Если будут найдены другие файлы с таким же inodo-м, их тоже необходимо удалить
После чего запустить self-heal
1 |
# gluster volume heal gvolume1 |
Команда для просмотра gfid-идентификатора файла
1 |
# getfattr -d -m . -e hex /gluster-storage/file2.php |
1 2 3 4 5 |
getfattr: Removing leading '/' from absolute path names # file: gluster-storage/file2.php trusted.afr.dirty=0x000000000000000000000000 trusted.gfid=0x3029e760cbf64877a0ec1ac6b6d7aa33 trusted.gfid2path.f14dac9964d7c89b=0x62313366633731652d646236322d346539612d623131342d6239633937333636343834652f656e762e706870 |
Файл доступен во внутреннем хранилище GlusterFS по пути
1 |
# cat /gluster-storage/.glusterfs/30/29/4029e760-cbf6-4877-a0ec-1ac6b6d7aa33 |
Принцип работы команды heal info
1 2 3 4 5 |
When these commands are invoked, a "glfsheal" process is spawned which reads the entries from the various sub-directories under /<brick-path>/.glusterfs/indices/ of all the bricks that are up (that it can connect to) one after another. These entries are GFIDs of files that might need healing. Once GFID entries from a brick are obtained, based on the lookup response of this file on each participating brick of replica-pair & trusted.afr.* extended attributes it is found out if the file needs healing, is in split-brain etc based on the requirement of each command and displayed to the user. |
Разрешение/исправление split-brain-файлов
Б) С помощью/с точки монтирования тома(также применимо только к data И/ИЛИ metadata типом split-brain)
Не будет работать на NFS-разделах т.к. они не поддерживают расширенные атрибуты xattrs
С любой точки монтирования (клиента, который монтирует у себя реплицируемый том) можно использовать команды getfattr and setfattr для обнаружения data и metadata типов split-brain и их устранения
Например, с помощью команды, выполненной на ноде, мы обнаружили файл, находящийся в split-brain
1 |
# gluster volume heal gvolume1 info split-brain |
Теперь с клиента определяем, в какой именно типе split-brain находится файл
Проверка, находится ли файл именно в data или metadata типе split-brain
1 |
# getfattr -n replica.split-brain-status <path-to-file> |
Например
1 |
# getfattr -n replica.split-brain-status file100 |
1 2 |
# file: file100 replica.split-brain-status="data-split-brain:no metadata-split-brain:yes Choices:test-client-0,test-client-1" |
1 |
# getfattr -n replica.split-brain-status file1 |
1 2 |
# file: file1 replica.split-brain-status="data-split-brain:yes metadata-split-brain:no Choices:test-client-0,test-client-1" |
При поытке получить доступ с клиента к таким файлам,находящимся в split-brain, будет получена ошибка типа input/output error
1 |
# cat file1 |
1 |
cat: file1: Input/output error |
Для предоставления доступа к файлу, находящемуся в split-brain, для конкретного клиента выполняем
1 |
# setfattr -n replica.split-brain-choice -v "choiceX" <path-to-file> |
Где
choiceX – имя клиента, которому нужно предоставить доступ к файлу, который присутствует в выводе команды
1 |
# getfattr -n replica.split-brain-status file1 |
( в нашем случае один из указанных здесь Choices:test-client-0,test-client-1″)
Например, для test-client-0
1 |
# setfattr -n replica.split-brain-choice -v test-client-0 file1 |
После чего файл становится доступным с этого клиента(test-client-0)
1 |
# cat file1 |
1 |
xyz |
Аналогично, для доступа с другого клиента(test-client-1) ему необходимо дать доступ
1 |
# setfattr -n replica.split-brain-choice -v test-client-1 file1 |
Для отмены доступа к файлу со всех клиентов используем команду
1 |
# setfattr -n replica.split-brain-choice -v none file1 |
После определения кирпичика, на котором split-brain файл будет взять в качестве источника
Устанавливаем этот кирпичик как источник, для конфликтного файла
1 |
# setfattr -n replica.split-brain-heal-finalize -v <heal-choice> <path-to-file> |
Например, определим,что файл должен быть взять с кирпичика test-client-0
1 |
# setfattr -n replica.split-brain-heal-finalize -v test-client-0 file1 |
Автоматическое разрешение split-brain файлов
GlusterFS поддерживает также автоматическое решение split-brain по одной из указанных ниже политик
Т.е. устанавливая соответствующее значение опции тома cluster.favorite-child-policy равной одной из политик, будет активироваться автоматическое разрешение split-brain-файлов без участия пользователя
По умолчанию эта опия отключена (установлено значение «none»)
1 |
# gluster volume set help|grep -A3 cluster.favorite-child-policy |
1 2 3 |
Option: cluster.favorite-child-policy Default Value: none Description: This option can be used to automatically resolve split-brains using various policies without user intervention. "size" picks the file with the biggest size as the source. "ctime" and "mtime" pick the file with the latest ctime and mtime respectively as the source. "majority" picks a file with identical mtime and size in more than half the number of bricks in the replica. |
Источник:
https://docs.gluster.org/en/latest
http://www.linux-admins.net/2012/07/deploying-glusterfs.html
http://www.jamescoyle.net/how-to/435-setup-glusterfs-with-a-replicated-volume-over-2-nodes
https://www.server-world.info/en/note?os=Ubuntu_16.04&p=glusterfs