Интересный пост с телеграм канала
BASH DAYS | LINUX
- @bashdays. Чтобы не забыть, выкладываю тут, все со слов автора.
Как-то года 3 назад мы настолько устали каждую неделю ремонтировать маунтшары через glusterfs, что было принято решение выкинуть его нахуй и пойти в сторону упрощения. Много что попробовали, но остановились на sshfs.
Автоматическое монтирование SSHFS
GlusterFS
— это распределённая, параллельная, линейно масштабируемая файловая система с возможностью защиты от сбоев. НУ-НУ 😠
SSHFS
— это клиентская программа для Linux
, используемая для удаленного управления файлами по протоколу SSH таким образом, как будто они находятся на локальном компьютере.
Проблема
По вводным: у нас есть baremetal
сервер с огромными HDD дисками на овер 500 терабайт. На диске хранится статика, которую отдаем через nginx
. Задача: подключать этот диск в облачную инфраструктуру к различным нодам.
Условия: чтобы работало и не воняло. 🤒
Тут все достаточно просто. Даем команду на нужной нам ноде и шара монтируется в папку /mnt/storage
:
sshfs -o compression=no,allow_other,reconnect storage@bashdayz.ru:/storage /mnt/storage
compression
- не использовать компрессиюallow_other
- разрешить доступ к шареreconnect
- нативный реконект если шара отвалилась
Из плюсов: на baremetal
сервере не надо устанавливать никакой дополнительный софт, все работает по протоколу ssh
.
Но есть нюансы. Допустим если ноду перезагрузить, то всё отвалится. Либо придут сетевые ножницы и оно тоже отвалится.
Запихать в fstab
не вариант. Так как на этапе маунта еще нет сети и загрузка сервера просто остановится в попытках примонтировать шару. А ключик reconnect
работает как ему захочется, даже если выставить таймауты проверок.
Решение
Решение простое, создаем три юнита в systemd
.
Юнит 1
[Unit]
Description=Mount remote filesystem over sshfs with fuse
After=network.target
[Install]
WantedBy=multi-user.target
[Mount]
What=storage@bashdayz.ru:/storage
Where=/mnt/storage
Type=fuse.sshfs
Options=kernel_cache,compression=no,allow_other,reconnect
After=network.target
- запускать маунт только после того, как на хосте поднимется сетьWhat=storage@bashdayz.ru:/storage
- что монтируемWhere=/mnt/storage
- куда монтируем
Файл юнита должен называться в соответствии с путем куда монтируем. Узнать имя можно командой:
systemd-escape -p /mnt/storage
Первый юнит сохраняем сюда: /etc/systemd/system/mnt-storage.mount
sudo vim /etc/systemd/system/mnt-storage.mount
Теперь нужно сделать юнит проверки, если шара отвалилась. Для начала создаем юнит с таймером:
Юнит 2
[Unit]
Description=Run ssh mount /mnt/storage check
After=mnt-storage.mount
[Timer]
Unit=mnt-storage.service
OnCalendar=*-*-* *:*:00
[Install]
WantedBy=timers.target
After=mnt-storage.mount
- обеспечит запуск таймера после загрузки сервера, но только после того, как маунт юнит будет запущен, то есть после того, как удалённая ФС смонтируется.Unit=mnt-storage.service
- какой юнит будем запускать при срабатывании таймера. О нём чуть ниже.OnCalendar=*-*-* *:*:00
- это означает каждую минуту.
Юнит-файл таймера можно называть как угодно. Но чтобы было понятнее, будем называть также, как и маунт-юнит. Итак, сохраняем в /etc/systemd/system/mnt-storage.timer
sudo vim /etc/systemd/system/mnt-storage.timer
Теперь нужно создать юнит, который будет заниматься проверкой маунта и его перезапуском при необходимости:
Юнит 3
[Unit]
Description=SSH mount /mnt/storage check
[Service]
Type=oneshot
ExecStart=/bin/bash -c "if [[ ! -f /mnt/storage/mount.yes ]] ;then systemctl restart mnt-storage.mount;fi"
TimeoutSec=300
[Install]
WantedBy=multi-user.target
Здесь всё просто. Bash строка в ExecStart
это bash’евый однострочник,
проверяющий наличие маркерного файла mount.yes
, при отсутствии которого будет перезапущен маунт-юнит.
В более новой версии systemd
можно было бы это всё сделать иначе, но зато такой вариант более универсален.
Cохраняем в /etc/systemd/system/mnt-storage.service
sudo vim /etc/systemd/system/mnt-storage.service
Активация
Релодим и активируем:
systemctl daemon-reload
systemctl enable mnt-storage.mount
systemctl enable mnt-storage.timer
Третий юнит mnt-storage.service
при загрузке сервера активировать не нужно, поскольку этот юнит вызывается таймером mnt-storage.timer
.
Он будет всегда Active: inactive (dead)
, это нормально.
Ну и в финале запускаем таймер:
systemctl start mnt-storage.timer
Итог
Вот и все! Наша шара успешно взята под контроль, подключена. А в случае отвала по любым причинам, она сама перемонтируется без лишних вопросов. Ну и после перезагрузки ноды, тоже все поднимется из коробки.
Способ рабочий, полет стабильный более трёх лет. Можешь приспособить к своим каким-то изобретениям и использовать уже юниты, а не закроненные bash
скрипты. А шары монтировать через sshfs
, а не через вонючий, разваливающийся gluster
. Фак еее! 🐄
Подпишись: @bashdays
Дополнительно
Посмотреть подключенные машины по sshfs
cat /etc/mtab
или в современных системах 2020г и выше - использовать утилиту findmnt
findmnt -t fuse.sshfs
В ручную отмонтировать диск
fusermount -u /temp/user/harddrive