Как стать автором
Обновить
РТЛабс
Разработчик Госуслуг

Ещё один рецепт отказоустойчивого файлового сервера средствами PaceMaker

Уровень сложностиСложный
Время на прочтение9 мин
Количество просмотров6.8K

В конце прошлого года нам поступила задача по реализации отказоустойчивого хранилища для разрабатываемого сервиса.

Ранее для этих целей предложили бы готовое решение в виде СХД с поддержкой сетевых протоколов вроде Hitachi NAS Platform (HNAS). Но текущая ситуация и особенности контракта обязывали проработать решение на мощностях заказчика.

В итоге выбрали и реализовали решение с использованием ОС на ядре Linux и кластере PaceMaker — с общим диском, поддержкой кворума, демона SDB и протокола NFS. Кому интересны особенности реализации, прошу под кат.

Статья рассчитана на читателя, знакомого с основами PaceMaker. В ней использую собственные ВМ, так как от заказчика сложно получить данные

Исходная задача

Цель — реализовать на площадке клиента хранение пользовательских файлов для разрабатываемого сервиса. Сервис — java-приложение, запущенное на нескольких ВМ.

Критерии выбора решения

  1. Простота реализации

  2. Низкая стоимость поддержки и высокая автономность работы

  3. Проверенные технологии

  4. Максимальная живучесть решения

  5. Использование текущих возможностей инфраструктуры заказчика

При этом мы учитывали нашу финансовую ответственность при недоступности файлового хранилища. Для понимания, заказчик — крупная организация, основная деятельность которой не IT, типичный кровавый Enterprise.

Проектируемая нагрузка

  • Не более 15 000 файлов за сутки

  • Средний размер файла — до 1 Мб

  • Ожидаемое увеличение данных за год — до 5 Тб

  • Глубина хранения — 3 или 5 лет

Выбор решения

Мы хотели найти POSIX-совместимое решение для снижения затрат на разработку и дальнейшую поддержку.

S3 не подходил из-за высокой стоимости поддержки и нецелесообразности для планируемых нагрузок. GlusterFS выглядел хорошо, но с ним имелся негативный опыт работы. Может сейчас работает хорошо, и я знаю проекты, где хранятся миллионы объектов и терабайты данных, но осадочек остался. Другие кластерные ФС нами не рассматривались ввиду отсутствия опыта их внедрения и сопровождения.

Поэтому выбор свёлся к следующим решениям на базе протокола NFS:

  • отдельные диски с репликацией по DRDB + PaceMaker

  • отдельные диски с репликацией через LsyncD + PaceMaker

  • общие диски (Shared Storage) + PaceMaker

Мы остановились на 3 варианте из-за низких затрат на дисковое пространство, минимального количества точек потенциального отказа и объектов для мониторинга.

По сути в выбранном решении только файловая система и является единственной точкой отказа. Используется некластерная файловая система, которая не поддерживает множественный доступ с различных серверов. За монопольный доступ отвечает PaceMaker.

Стенд

У меня будет 3 ВМ с CentOS 7 — у заказчика это основная ОС: большие компании с основными статьями дохода, не связанными с ИТ, сложно и медленно переходят на что-то новое.

Надеюсь, под другие ОС предложенное решение подойдёт и найдутся нужные пакеты

Имя ВМ

IP

Nfs1

10.55

Nfs2

10.56

Nfs3

10.57

10.58 будет использоваться под VIP NFS.

Ко всем ВМ подключён общий диск на 20 Гб для хранения данных.

sdb 8:16 0 20G 0 disk

Мой стенд развёрнут через VirtualBox. У заказчика система виртуализации WMWare, диски поданы по FC.

Особенности реализации решения

  • ВМ одинаковы в своих аппаратных ресурсах. Если у вас сложности с ресурсами, сделайте третью ВМ с минимальными аппаратными характеристиками и запретите запускаться на ней ресурсам файлового сервера

  • Для ВМ должно быть реализовано правило Anfi Affinity для размещения на разных физических серверах

  • Общие диски должны быть презентованы ВМ с одного хранилища (Datastore)

  • Общие диски должны быть доступны по одинаковым путям внутри ВМ

  • Нужна отдельная сетка для работы приклада и файлового хранилища. Это может быть виртуальная сеть, реализованная поверх существующей физической сети, но со своим QOS

  • Самое важное — к узлам файлового кластера надо относиться, как к контроллерам СХД. На них не должны запускать скрипты для создания резервных копий или другое ПО, работающее с данными. Вся пишущая и читающая нагрузка должна приходить снаружи кластера через VIP

Схематичное представление

Реализация

Базовая настройка

Теория и всякие требования — это скучно, переходим к практике.

У нас 3 новеньких сервера. Обновляемся и ставим пакеты на всех серверах

[root]# yum update -y 
[root]# yum install pcs pacemaker fence-agents-sbd sbd dlm -y

В /etc/hosts добавляем записи по нашим серверам или на DNS создаем соответствующие A-записи.

DLM (Distributed Lock Manager) по факту не используется: он нужен для работы кластерных файловых систем. Однако он прописан как зависимость службы SBD, поэтому его устанавливаем, но не настраиваем. Альтернативное решение правка service unit SBD с удалением зависимостей от DLM

Разрешим сетевое взаимодействие между узлами кластера

[root]# firewall-cmd --permanent --add-service=high-availability`
[root]# firewall-cmd --permanent --add-service=nfs 
[root]# firewall-cmd --reload

Обращаю внимание, что SELinux оставляем включённым.

Настроим общий диск на первом сервере

[root@nfs1 ~]# parted /dev/sdb
(parted) mklabel gpt
(parted) mkpart primary xfs 1 100%FREE
(parted) quit
[root@nfs1 ~]# partprobe
[root@nfs1 ~]# lsblk
sdb               8:16   0   20G  0 disk
└─sdb1            8:17   0   20G  0 part 
[root@nfs1 ~]# mkfs.xfs /dev/sdb1

Если на другом сервере выполнить команду partprobe и lsblk, увидим идентичные изменения в структуре дисков.

Не использую LVM, так как это усложнит схему и нет надобности под текущую задачу и структуру организации данных. Скорее всего, нужно будет дополнительно отключать lvmetad и вносить правки

На всех серверах задаём пароль для пользователя и включаем службы

echo "CHANGE_ME" | passwd hacluster --stdin 
systemctl enable pcsd --now

Собираем кластер, выполняем разово на любом узле

pcs cluster auth nfs1 nfs2 nfs3 -u hacluster -p CHANGE_ME
pcs cluster setup --start --name nfs_cluster nfs1 nfs2 nfs3
pcs cluster enable --all

Проверяем, что получилось

[root@nfs1 ~]# pcs status
Cluster name: nfs_cluster

WARNINGS:
No stonith devices and stonith-enabled is not false
Stack: corosync
Current DC: nfs3 (version 1.1.23-1.el7_9.1-9acf116022) - partition with quorum

3 nodes configured
0 resource instances configured

Online: [ nfs1 nfs2 nfs3 ]

No resources

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

Обратите внимание, что ругается на отсутствие stonith devices и среди статуса демонов только 3 службы.

Настройка stonith device

SBD (Storage-Based Death) умеет вызывать stonith через watchdog, обмениваться сообщениями между узлами кластера и интегрироваться с PaceMaker.

Все прочитанные мной статьи по настройке отказоустойчивых решений на базе PaceMaker предлагали настраивать stonith device через IPMI или vCenter или вообще отключать stonith, брррр.

Используя SBD, можно обойтись без внешних зависимостей, что идеально подходит для виртуальных машин.

SBD может работать в двух режимах:

  • без общего диска — участники SBD обмениваются сообщениями по сети, поэтому нужно 3 сервера для правильного формирования кворума и обработки отказов в работе одного из узлов

  • с общим диском или дисками — участники SBD обмениваются сообщениями через общий диск

Благодаря SBD удалось добиться нужного поведения, когда при недоступности общего диска или сети происходит перезагрузка сервера.

Так как у нас ВМ, то для перезапуска будем использовать softdog — программную реализацию watchdog, которая в ОС присутствует в виде модуля ядра.

На всех серверах проверим наличие softdog, добавим в автозагрузку и протестируем его работу

/sbin/modprobe softdog
ls -al /dev/watchdog
echo softdog > /etc/modules-load.d/softdog.conf
systemctl restart systemd-modules-load
lsmod | grep softdog
sbd query-watchdog
Discovered 2 watchdog devices:

[1] /dev/watchdog
Identity: Software Watchdog
Driver: softdog
CAUTION: Not recommended for use with sbd.

[2] /dev/watchdog0
Identity: Software Watchdog
Driver: softdog
CAUTION: Not recommended for use with sbd.

Softdog не отработает, если зависнут все ядра CPU. Если в вашем случае это критично, нужно использовать аппаратный watchdog. В этом решении пошли на обозначенный риск

Отключаем stonith на уровне кластера

pcs property set stonith-enabled="false"
pcs property set stonith-timeout=0
pcs property set stonith-watchdog-timeout=0

Настраиваем SBD, за нас это может сделать pcs

pcs stonith sbd enable \
    --watchdog=/dev/watchdog \
    SBD_STARTMODE=clean

Проверяем его настройки

cat /etc/sysconfig/sbd
# This file has been generated by pcs.
SBD_DELAY_START=no
SBD_OPTS="-n nfs1"
SBD_PACEMAKER=yes
SBD_STARTMODE=clean
SBD_WATCHDOG_DEV=/dev/watchdog
SBD_WATCHDOG_TIMEOUT=5

Перезагружаем все узлы. По умолчанию службу sbd нельзя остановить или запустить руками

[root@nfs1 ~]# pcs stonith sbd status --full
SBD STATUS
<node name>: <installed> | <enabled> | <running>
nfs1: YES | YES | YES
nfs3: YES | YES | YES
nfs2: YES | YES | YES

[root@nfs1 ~]# sbd query-watchdog
Discovered 2 watchdog devices:

[1] /dev/watchdog
Identity: Error: Check if hogged by e.g. sbd-daemon!
Driver: <unknown>

[2] /dev/watchdog0
Identity: Error: Check if hogged by e.g. sbd-daemon!
Driver: <unknown>

Вернёт ошибку, и это ожидаемо. Мы убеждаемся, что softdog занят запущенным процессом SBD.

Теперь статус кластера выглядит нормально

[root@nfs1 ~]# pcs status
Cluster name: nfs_cluster
Stack: corosync
Current DC: nfs3 (version 1.1.23-1.el7_9.1-9acf116022) - partition with quorum

3 nodes configured
0 resource instances configured

Online: [ nfs1 nfs2 nfs3 ]

No resources

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled
  sbd: active/enabled

Ушло предупреждение o stonith devices среди статуса демонов 4 службы.

Возвращаем настройки stonith и проверяем

pcs property set stonith-timeout="12s"
pcs property set stonith-watchdog-timeout="6s"
pcs property set cluster-recheck-interval="1m"
pcs property set stonith-enabled="true"
pcs property set fence-reaction="panic"
pcs property set no-quorum-policy=suicide

Так как watchdog занят запущенным процессом SBD, для проверки тестирования эти команды не подойдут:

  • pcs stonith sbd watchdog test

  • pcs stonith fence <node>

Проверить stonith можно, завершив процесс SBD

[root@nfs1 ~]# systemctl status sbd
● sbd.service - Shared-storage based fencing daemon
   Loaded: loaded (/usr/lib/systemd/system/sbd.service; enabled; vendor preset: disabled)
   Active: active (running)
  Process: 695 ExecStart=/usr/sbin/sbd $SBD_OPTS -p /var/run/sbd.pid watch (code=exited, status=0/SUCCESS)
 Main PID: 715 (sbd)
   CGroup: /system.slice/sbd.service
           ├─715 sbd: inquisitor
           ├─724 sbd: watcher: Pacemaker
           └─725 sbd: watcher: Cluster
[root@nfs1 ~]# kill -9 715

После этого должна произойти перезагрузка сервера.

Создание NFS-кластера

На всех серверах установим необходимые компоненты

yum install nfs-utils -y
systemctl stop nfs-lock && systemctl disable nfs-lock

Службу nfs-lock выключаем, так как NFS-сервером будет управлять PaceMaker.

На любом узле получаем UUID диска

[root@nfs1 ~]# blkid -o list
device            fs_type    label     mount point         UUID
----------------------------------------------------------------------------------------------
/dev/sdb1         xfs                  (not mounted)       96a78db6-1d4b-421c-8888-747e5aa61094

Монтируем диск

pcs resource create nfs_fs1 ocf:heartbeat:Filesystem \
  device=-U96a78db6-1d4b-421c-8888-747e5aa61094 directory=/nfs_server fstype=xfs \
  options=noatime,nodiratime,noexec,nosuid \
  --group nfs_group \
  op monitor interval=1s timeout=5s on-fail=fence \
  OCF_CHECK_LEVEL=10

OCF_CHECK_LEVEL=10 проверяет диск на доступность, ЧИТАЯ первые 16 бит. Это позволяет перезагрузить узел при недоступности диска (опция on-fail=fence), и запустить ресурсы на другом узле кластера.

Первый общий диск хранит на себе состояние работы NFS-сервера

pcs resource create nfs_server ocf:heartbeat:nfsserver \
  nfs_shared_infodir=/nfs_server/server nfs_no_notify=true nfsd_args="--grace-time 10"\
  --group nfs_group --after nfs_fs1 \
  op monitor interval=1s timeout=10s on-fail=fence

Публикуем NFS-ресурс

mkdir -p /nfs_server/data1
pcs resource create nfs_data1 ocf:heartbeat:exportfs \
  clientspec="10.0.0.0/24" options=rw,sync,no_root_squash directory=/nfs_server/data1 \
  fsid=1001 wait_for_leasetime_on_stop=false unlock_on_stop="1"\
  --group nfs_group --after nfs_server \
  op monitor interval=1s timeout=10s on-fail=fence

В отдельной группе создаём VIP

pcs resource create nfs_vip ocf:heartbeat:IPaddr2 \
  ip=10.0.0.54 cidr_netmask=24 op monitor interval=1s \
  --group nfs_vip_group

В конце устанавливаем зависимости

pcs constraint order start nfs_group then nfs_vip_group
pcs constraint colocation add nfs_group with nfs_vip_group INFINITY

Проверяем состояние кластера и зависимостей

[root@nfs1 ~]# pcs status
Cluster name: nfs_cluster
Stack: corosync
Current DC: nfs3 (version 1.1.23-1.el7_9.1-9acf116022) - partition with quorum

3 nodes configured
4 resource instances configured

Online: [ nfs1 nfs2 nfs3 ]

Full list of resources:

 Resource Group: nfs_group
     nfs_fs1    (ocf::heartbeat:Filesystem):    Started nfs2
     nfs_server (ocf::heartbeat:nfsserver):     Started nfs2
     nfs_data1  (ocf::heartbeat:exportfs):      Started nfs2
 Resource Group: nfs_vip_group
     nfs_vip    (ocf::heartbeat:IPaddr2):       Started nfs2

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled
  sbd: active/enabled

[root@nfs1 ~]# pcs constraint
Location Constraints:
Ordering Constraints:
  start nfs_group then start nfs_vip_group (kind:Mandatory)
Colocation Constraints:
  nfs_group with nfs_vip_group (score:INFINITY)
Ticket Constraints:

В дальнейшем планируется увеличивать количество дисков через ocf:heartbeat:Filesystem и публиковать доступ к ним, используя ocf:heartbeat:exportfs в пределах группы nfs_group.

Подключение клиентов и тестирование

NFS-клиенты подключаются стандартным образом.

Основные особенности

  1. Режим монтирования soft — в нём при недоступности NFS-ресурса клиенту вернётся ошибка ввода вывода. Разработки учитывают этот момент в реализации сервиса

  2. Версия NFS 4.1, используем её . Если когда-нибудь возникнут проблемы, к примеру, с блокировками, попробуем NFS 3

Проведённые тесты

  1. Штатное выключение / перезагрузка

  2. Аварийное выключение / перезагрузка

  3. Потеря общего диска

  4. Потеря сети

  5. Потеря кворума, например, непровальная настройка firewall

  6. Выключение и включение всего кластера

  7. Недоступность большинства узлов

Все тесты проводились под пишущей и читающей нагрузкой и показали нужное поведение: перезагрузку тестируемого узла и миграцию ресурсов на другие.

Со стороны клиента замерялось самое длительное время недоступности NFS — до 12-14 секунд при выходе из строя активного узла.

Заключение

Решение получилось простым, отказоустойчивым и для данной задачи масштабируемым без внешних зависимостей.

Возможные риски

Представляет опасность отсутствие отказоустойчивости на уровне файловой системы общего диска и возможность множественного доступа, который приведёт к порче файловой системы.

Для минимизации рисков можно было бы реализовать SCSI SPC-3 persistent reservations, но нет агента sg_persist для Pacemaker в Centos7. Однако для спокойного сна мы пробовали монтировать ФС на нескольких узлах кластера, с операциями записи через один узел — и это не привело к гибели ФС.

Взвесив все «за» и «против», мы выбрали описанную выше реализацию.

Ещё раз, главное

  1. К узлам кластера относиться как к контроллерам СХД — не допускать локальных процессов с пишущими операциями на общие диски. Все активности должны приходить снаружи кластера через отказоустойчивый адрес

  2. Не пытаться смонтировать ФС руками. Все операции должен проводить Pacemaker

  3. В полученном решении вероятность порчи ФС минимальна

Надеюсь, вы узнали что-то новое для себя. Всем добра!

Теги:
Хабы:
Всего голосов 20: ↑20 и ↓0+20
Комментарии10

Публикации

Информация

Сайт
rtlabs.ru
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия