Моя шпаргалка :)

Мануалы и настройки => Настройки *nix (почта, web, система etc) => Тема начата: George от Сен. 14, 2026, 11:25

Название: Glusterfs не поднимается после перезагрузки всех нод
Отправлено: George от Сен. 14, 2026, 11:25
[size=200]Автоматический mount GlusterFS после перезагрузки[/size]



[size=150]Проблема[/size]

Есть кластер из трёх Docker Swarm-нод:

Docker-HUB   — 10.110.10.46
Docker-HUB-2 — 10.110.10.47
Docker-HUB-3 — 10.110.10.48

GlusterFS volume:

docker-data

Тип volume:

Replicate

Три brick:

10.110.10.46:/gluster/data
10.110.10.47:/gluster/data
10.110.10.48:/gluster/data

Общий mount:

/mnt/gluster-storage

В /etc/fstab:

localhost:/docker-data /mnt/gluster-storage glusterfs defaults,_netdev,backupvolfile-server=10.110.10.47:10.110.10.48,log-level=WARNING 0 0

После одновременной перезагрузки всех трёх нод (например, после отключения питания) GlusterFS мог не успеть полностью поднять brick-процессы к моменту запуска mount.

В результате:

Mount failed

В логе появлялось:

Client-quorum is not met
All subvolumes are down. Going offline until at least one of them comes back up.

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

mount -a

сразу успешно монтировала volume.

Причина: проблема была не в самом GlusterFS и не в /etc/fstab, а в порядке запуска сервисов после загрузки системы.



[size=150]Решение[/size]

Создаём отдельный systemd service, который ждёт готовности GlusterFS volume docker-data.

После этого mount зависит от этого service.

Итоговый порядок запуска:

network
↓
glusterd
↓
gluster-storage-ready.service
↓
mnt-gluster-storage.mount
↓
Docker



[size=150]1. Проверяем GlusterFS[/size]

Проверяем volume:

gluster volume info docker-data

Проверяем состояние brick:

gluster volume status docker-data

В рабочем состоянии:

Brick 10.110.10.46:/gluster/data ... Y
Brick 10.110.10.47:/gluster/data ... Y
Brick 10.110.10.48:/gluster/data ... Y

Y в колонке Online означает, что brick доступен.



[size=150]2. Создаём systemd service[/size]

На каждой Docker Swarm-ноде:

vi /etc/systemd/system/gluster-storage-ready.service

Содержимое файла:

[Unit]
Description=Wait for GlusterFS docker-data volume
Requires=glusterd.service
After=glusterd.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'until gluster volume status docker-data 2>/dev/null | grep -qE "Brick .* [0-9]+ +0 +Y"; do sleep 2; done'
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Что здесь происходит:

Requires=glusterd.service

Требует запущенный glusterd.

After=glusterd.service

Говорит systemd сначала запустить glusterd.

Проверка:

gluster volume status docker-data

повторяется каждые 2 секунды до тех пор, пока не будет найден работающий brick.

После готовности volume service завершается успешно:

Active: active (exited)
status=0/SUCCESS

Это нормальное поведение для Type=oneshot.



[size=150]3. Включаем service[/size]

После создания файла:

systemctl daemon-reload
systemctl enable gluster-storage-ready.service

Проверяем:

systemctl is-enabled gluster-storage-ready.service

Ожидаемый результат:

enabled

Запускаем:

systemctl start gluster-storage-ready.service

Проверяем:

systemctl status gluster-storage-ready.service --no-pager

При работающем Gluster:

Active: active (exited)

и:

status=0/SUCCESS



[size=150]4. Добавляем зависимость mount от GlusterFS[/size]

Так как unit mnt-gluster-storage.mount генерируется systemd из /etc/fstab, сам unit редактировать не нужно.

Создаём drop-in:

mkdir -p /etc/systemd/system/mnt-gluster\x2dstorage.mount.d

Создаём файл:

vi /etc/systemd/system/mnt-gluster\x2dstorage.mount.d/gluster.conf

Содержимое:

[Unit]
Requires=gluster-storage-ready.service
After=gluster-storage-ready.service



[size=150]5. Перечитываем конфигурацию systemd[/size]

systemctl daemon-reload

Проверяем:

systemctl cat mnt-gluster\x2dstorage.mount

В конце должно присутствовать:


# /etc/systemd/system/mnt-gluster\x2dstorage.mount.d/gluster.conf

[Unit]
Requires=gluster-storage-ready.service
After=gluster-storage-ready.service

Проверяем зависимости:

systemctl show mnt-gluster\x2dstorage.mount -p Requires -p After

В выводе должен присутствовать:

gluster-storage-ready.service



[size=150]6. Проверяем mount вручную[/size]

Проверяем, смонтирован ли volume:

mountpoint -q /mnt/gluster-storage && echo "MOUNTED" || echo "NOT MOUNTED"

Если:

NOT MOUNTED

запускаем:

systemctl start mnt-gluster\x2dstorage.mount

Проверяем:

systemctl status mnt-gluster\x2dstorage.mount --no-pager

Ожидаем:

Active: active (mounted)

И:

ls /mnt/gluster-storage/

должен показать содержимое общего GlusterFS-хранилища.



[size=150]7. Проверяем порядок запуска[/size]

Для mount:

systemctl show mnt-gluster\x2dstorage.mount
-p Requires
-p After

Должен присутствовать:

gluster-storage-ready.service

Для service:

systemctl show gluster-storage-ready.service
-p Before
-p After

Должен присутствовать:

glusterd.service

Таким образом получается:

glusterd.service
↓
gluster-storage-ready.service
↓
mnt-gluster-storage.mount



[size=150]8. Настройка на всех трёх нодах[/size]

Одинаковая конфигурация должна находиться на:

Docker-HUB
Docker-HUB-2
Docker-HUB-3

На каждой ноде:

/etc/systemd/system/gluster-storage-ready.service

/etc/systemd/system/mnt-gluster\x2dstorage.mount.d/gluster.conf

В /etc/fstab остаётся:

localhost:/docker-data /mnt/gluster-storage glusterfs defaults,_netdev,backupvolfile-server=10.110.10.47:10.110.10.48,log-level=WARNING 0 0



[size=150]9. Проверка после перезагрузки[/size]

После перезагрузки проверяем:

mountpoint /mnt/gluster-storage

Ожидаем:

/mnt/gluster-storage is a mountpoint

Проверяем содержимое:

ls /mnt/gluster-storage/

Проверяем GlusterFS:

gluster volume status docker-data

Все три brick должны иметь:

Online  Y

Проверяем service:

systemctl status gluster-storage-ready.service --no-pager

Ожидаем:

Active: active (exited)

Проверяем mount:

systemctl status mnt-gluster\x2dstorage.mount --no-pager

Ожидаем:

Active: active (mounted)



[size=150]10. Почему это работает[/size]

Раньше при холодной загрузке мог происходить такой порядок:

boot
↓
glusterd запускается
↓
mount пытается подключиться
↓
Gluster bricks ещё не готовы
↓
mount падает
↓
Gluster через несколько секунд полностью готов
↓
mount автоматически не повторяется

После добавления зависимости:

boot
↓
glusterd запускается
↓
gluster-storage-ready.service
↓
ждёт готовности docker-data
↓
brick становится Online
↓
service завершается успешно
↓
mnt-gluster-storage.mount
↓
GlusterFS подключён



[size=150]Итог[/size]

После настройки всех трёх нод была выполнена одновременная перезагрузка.

После загрузки:

ls /mnt/gluster-storage/

сразу показал содержимое общего хранилища.

Ручной:

mount -a

больше не потребовался.

Таким образом, при одновременной перезагрузке всех трёх Docker Swarm-нод systemd сначала дожидается готовности GlusterFS volume docker-data, и только после этого выполняет mount общего хранилища.

Важно: настраивать нужно одинаково на всех трёх нодах. Отдельная зависимость от glusterd в docker.service для этой схемы не требуется — Docker уже стартует после готового mount, если соответствующая зависимость настроена в системе.