Привет всем 👋,

В рамках задачи по масштабированию сервисов на одном из проектов, потребовалось объединить раздел с данными между несколькими нодами кластера.

Самый быстрый и простой вариант это вынести все на nfs-шару и забыть об этом. Но в таком случае мы сталкиваемся с проблемой отказаустойчивости, ведь в случае выхода из строя nfs-cервера все данные будут потеряны.

Вот так мы пришли к GlusterFS и реплицируемым томам. По сути, это файловая система, которая не имеет какого-либо центрального сервера, и работает по принципу peer-to-peer.

С её помощью мы можем организовать диски с нескольких серверов в один общий реплицируемый том, либо использовать общий том для шардирования.

Ближе к делу.. ⌨️

В моём окружении имеется два веб-сервера на базе AlmaLinux 8.10. Со стороны виртуализации на сервера я добавил каждому дополнительный диск. Эти выделенные диски мы и будем объединять в реплицируемый том.

В продакшен среде для надежной работы GlusterFS и воизбежания риска получить Split brain рекомендуется использовать нечетное количество серверов - нужно это для работы кворума.

Поэтому в своем сетапе, буду использовать соседнюю виртуалку в качестве арбитра. Но данные будут зеркаливаться только на веб-серверах..

  +--------------------+          +--------------------+          +--------------------+
  |       WEB01        |          |       WEB02        |          |       ARBT01       |
  |   (Gluster Node)   |          |   (Gluster Node)   |          |   (Gluster Node)   |
  |--------------------|          |--------------------|          |--------------------|
  |   /var/glusterfs   | <------> |   /var/glusterfs   | <------> |     (No Data)      |
  |   (Replica Data)   |          |   (Replica Data)   |          +--------------------+
  +--------------------+          +--------------------+          

Подготовка серверов

Перед настройкой сервиса требуется выполнить ряд предварительных действий:

  • Убедиться в работе ntp-клиента,
  • Добавить локальные записи в /etc/hosts.
  • Разметить диск и создать точки монтирования.

Из коробки ntp-клиент (chronyd) уже должен быть засинхронизирован с вышестоящим сервером. Поэтому просто убеждаемся в этом, командой:

[All Servers]# timedatectl | grep 'System clock synchronized'
System clock synchronized: yes

Дополнительно можно проверить статус синхронизации с конкретным сервером командой: chronyc sources.

Настройка DNS.. Для надежности предпочитаю в локальный файлик - /etc/hosts на каждом сервере продублировать записи о нодах кластера. В случае каких-либо артефактов со стороны DNS-серверов, наш кластер не сломается.

Обновляем hosts:

[All Servers]# cat <<EOF >> /etc/hosts

# GlusterFS nodes
10.8.5.14   web01.mydomain.local  web01
10.8.5.24   web02.mydomain.local  web02
10.8.5.29   arch.mydomain.local   arch
EOF

Как упоминалось ранее, серверам web01/web02 выделил отдельные диски, которые мы будем использовать под кирпичи (bricks). В терминологии GlusterFS, это определенный каталог/точка монтирования под хранение данных.

На всех серверах создаем директорию для бриков:

[All Servers]# mkdir /mnt/gfs/brick01 -p

На новых дисках создаем файловую систему - xfs:

[web01/web02]# mkfs.xfs /dev/sdb

Обратите внимание, тут мы не делаем партицирование диска и не создаем LVM разметку. В ситуациях, когда нужно будет увеличить диск, мы просто добавляем дисковое пространство со стороны гипервизора. И далее внутри виртуальной машины выполняем команды:

  • partprobe /dev/sdb
  • xfs_growfs /dev/sdb

Обновим файлик /etc/fstab:

[web01/web02]# cat <<EOF >> /etc/fstab

# GlusterFS mount points:
/dev/sdb /mnt/gfs/brick01           xfs     defaults        0 0
EOF

Перечитываем конфигурацию systemd и монтируем диски:

[web01/web02]# systemctl daemon-reload
[web01/web02]# mount -a

Как вы можете заметить диски настраиваются только на двух серверах. На третьем сервере мы пропускаем данный этап и просто создаем каталог, так как арбитр-сервер не будет хранить ничего, кроме метаданных.

Установка GlusterFS

Для AlmaLinux 8.10 пакет glusterfs-server не найден в стандартных репозиториях, поэтому придется вручную создать свой repo-файл.

В каталоге /etc/yum.repos.d создаем новый репозиторий командой:

[All Servers]# cat <<EOF > /etc/yum.repos.d/glusterfs.repo
[glusterfs-10]
name=GlusterFS 10 - Repository 
baseurl=https://dl.rockylinux.org/vault/centos/8/storage/x86_64/gluster-10/
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux
EOF

Теперь устанавливаем пакеты:

[All Servers]# yum install -y glusterfs glusterfs-libs glusterfs-server

На стороне фаервола открываем доступ к сервису только для участников данного пула:

[All Servers]# firewall-cmd --new-zone=glusterfs-access --permanent && firewall-cmd --reload
[All Servers]# firewall-cmd --zone=glusterfs-access --add-service=glusterfs --permanent
[All Servers]# firewall-cmd --zone=glusterfs-access \
               --add-source=10.8.5.14/24 \
               --add-source=10.8.5.24/24 \
               --add-source=10.8.5.29/24 \
               --permanent && firewall-cmd --reload

Для просмотра конфигурации данной зоны воспользуемся командой:

[All Servers]# firewall-cmd --zone=glusterfs-access --list-all

Запускаем сервис glusterfs:

[All Servers]# systemctl enable --now glusterd glusterfsd

Собираем кластер

Перед созданием реплицируемых томов необходимо объединить серверы в один одноранговый пул (Trusted Storage Pool).

На первом сервере просто выполняем команды:

[web01]# gluster peer probe web02
[web01]# gluster peer probe arch

Для просмотра статуса участников пула, используем команду:

[All Servers]# gluster peer status
[All Servers]# gluster pool list

Следующим этапом создаем GlusterFS реплицируемый том, командой:

[web01]# gluster volume create web-storage replica 3 arbiter 1 transport tcp \
web01:/mnt/gfs/brick01 \
web02:/mnt/gfs/brick01 \
arch:/mnt/gfs/brick01 force

В данном примере, мы создаем новый том с именем - web-storage. Указываем, что хотим использовать три реплики и один арбитр, тип транспорта - tcp.

Далее перечисляем сервера и точки монтирования. По логике создания томов, последний сервер из списка будет арбитором (в моем случае это - arch:/mnt/gfs/brick01).

После создания нового тома, смотрим информацию о нем:

[web01]# gluster volume info
---
Volume Name: web-storage
Type: Replicate
Volume ID: 1c0b2352-443fd7d31f7a-kl089nO11-pAN809a4g2
Status: Created
Snapshot Count: 0
Number of Bricks: 1 x (2 + 1) = 3
Transport-type: tcp
Bricks:
Brick1: web01:/mnt/gfs/brick01
Brick2: web02:/mnt/gfs/brick01
Brick3: arch:/mnt/gfs/brick01 (arbiter)
Options Reconfigured:
cluster.granular-entry-heal: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off

Как видно из вывода, реплицируемый том с именем web-storage был создан, но не запущен (об этом говорит статус - Created).

Поле Number of Bricks:

  • 1 - один реплицируемый том,
  • (2 + 1) - 2 брика в реплике и 1 брик в качестве арбитра,
  • = 3 - всего три кирпича (Brick’а)

Опционально, если важна надежность, можно отключить кеширование:

[web01]# gluster volume set web-storage performance.stat-prefetch off
[web01]# gluster volume set web-storage performance.write-behind off

Отключение кеширования, может сказаться на производительности. Если важна производительность, то просто пропускаем эти командочки =)

Далее запускаем том:

[web01]# gluster volume start web-storage

Для того чтобы проверить статус раздела, воспользуемся командой:

[All Servers]# gluster volume status

Раздел готов к использованию. Последним этапом остается только примонтировать его к файлухе.

Монтируем раздел

В каталоге, где запускается сервис, есть поддиректория с системными/пользовательскими данными. Перед монтироваем переименовываем ее, далее создаем точку монтирования с аналогичным именем. И в конце при помощи rsync копируем данные.

Процесс с создаем каталогов и копирования файлов упустим. Обратим внимание только на монтирование диска. Для того, что бы в ручную примонтировать диск воспользуемся командой:

[web01]# mount -t glusterfs web01:/web-storage /var/www/myapp/storage

Параметры:

  • -t glusterfs — указывает тип файловой системы.
  • web01:/web-storage — сервер и имя тома (<Server-IP/Hostname>:/<VolumeName>).
  • /var/www/myapp/storage — путь для монтирования на локальном сервере.

Обновляем /etc/fstab, добавляя в него запись:

[web01/web01]# vim /etc/fstab
---
# ClusterFS to Storage on web01:
web01:/web-storage  /var/www/myapp/storage   glusterfs defaults,_netdev 0 0

# ClusterFS to Storage on web02:
web02:/web-storage  /var/www/myapp/storage   glusterfs defaults,_netdev 0 0

Перечитываем конфигурацию systemd и монтируем том:

[web01/web02]# systemctl daemon-reload
[web01/web02]# mount -a

Теперь том успешно смонтирован и будет автоматически подключаться при перезагрузке системы. 🚀

В данной статье мы разобрали процесс настройки GlusterFS на серверах AlmaLinux 8.10 – от установки и конфигурирования до создания реплицируемого тома и его монтирования. Мы настроили отказоустойчивый диск, который обеспечит надежность данных и их доступность для нашего приложения..