UMGUM.COM (лучше) 

Автоматизация DRBD ( Контроль за зеркалированием дисковых устройств файловой системы. )

1 августа 2010  (обновлено 15 августа 2016)

OS: Debian Linux.

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

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

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

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


Создаем файл списка DRBD устройств:

# mkdir -p /etc/custom/hdd/drbd
# touch /etc/custom/hdd/drbd/list

Наименования устройств вносим с разделителем в виде пробельного символа. К имени устройства, через разделитель в виде "слэша", прикрепляем назначенный ему статус (primary или secondary):

# cat /etc/custom/hdd/drbd/list

drbd0/primary drbd1/primary drbd2/secondary ... drbdX/status

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

Напишем скрипт проверяющий состояние членов устройств DRBD с определённой периодичностью, в течении работы, устанавливающий режим работы устройства и информирующего администратора об обнаруженных проблемах:

# touch /etc/custom/hdd/drbd/check-drbd.sh
# chmod ugo+x /etc/custom/hdd/drbd/check-drbd.sh

#!/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
HOSTNAME=`cat /etc/hostname`
OBJECTS=`cat /etc/custom/hdd/drbd/list`
DATE=`date +"%Y-%m-%d %H:%M:%S"`
EMAIL=`cat /etc/custom/hdd/email`
mkdir -p /tmp/custom/drbd
# Поднимаем флаг обнаружения ошибок при отработке скрипта
FLAG="1"

# Устанавливаем флаг блокировки на время работы скрипта
echo "0" > /tmp/custom/drbd/flag

# Проверяем факт запуска DRBD по созданным им конструкциям
if [ ! -e /proc/drbd ]
then
  # Устанавливаем флаг обнаружения ошибки
  FLAG="0"
  echo >&2 "Warning! DRBD не работает или работает некорректно."
  exit 1
fi

function send-report() {
  local LOCAL_OBJECT=$1
  local LOCAL_REPORT=$2
  # Посылаем электронное письмо с уведомлением о проблеме
  echo -e "Content-Type: text/plain; charset="utf-8"\nSubject: Warning DRBD: $HOSTNAME: /dev/$LOCAL_OBJECT\n$DATE.\nHost: $HOSTNAME.\nDevice: /dev/$LOCAL_OBJECT.\n$LOCAL_REPORT" | sendmail -F$HOSTNAME $EMAIL
}

# Перебираем в цикле все наши DRBD устройства
for OBJECTIVE in $OBJECTS
do
  # Получаем в переменные имя устройства и назначенную ему роль
  OBJECT=`echo $OBJECTIVE | awk -F / '{print $1}'`
  ROLE=`echo $OBJECTIVE | awk -F / '{print $2}'`
  # Проверяем, доступно ли DRBD устройство для полноценного использования локально
  if [ "`drbdadm dstate $OBJECT 2>/dev/null | awk -F / '{print $1}'`" = "UpToDate" ]
  then
    # Проверяем на предмет уже назначенной роли
    if [ "`drbdadm state $OBJECT | awk -F / '{print $1}' | tr A-Z a-z`" != "$ROLE" ]
    then
      # Если локальный член DRBD устройства корректно работает, то назначаем ему роль
      echo "Waiting 10 seconds for correct setup role DRBD resource /dev/$OBJECT..."
      drbdsetup /dev/$OBJECT $ROLE
      sleep 10
      if [ "`drbdadm state $OBJECT | awk -F / '{print $1}' | tr A-Z a-z`" != "$ROLE" ]
      then
        # Устанавливаем флаг обнаружения ошибки
        FLAG="0"
        send-report $OBJECT "Panic! За 10 секунд не произошло применение ролей членов DRBD устройства."
        echo >&2 "Panic! За 10 секунд не произошло применение ролей членов DRBD устройства /dev/$OBJECT."
      fi
    fi
  else
    # Устанавливаем флаг обнаружения ошибки
    FLAG="0"
    send-report $OBJECT "Panic! DRBD устройство работает не корректно или не применимо в текущей конфигурации."
    echo >&2 "Panic! DRBD устройство /dev/$OBJECT работает не корректно или не применимо в текущей конфигурации."
  fi
  # Проверяем DRBD устройство на наличие связи с удалённым узлом
  if [ ! `drbdadm cstate $OBJECT 2>/dev/null | grep "Connected"` ]
  then
    send-report $OBJECT "Warning! DRBD устройство работает некорректно в ожидании подключения к удалённому узлу."
    echo >&2 "Warning! DRBD устройство /dev/$OBJECT работает некорректно в ожидании подключения к удалённому узлу."
  fi
done

# Снимаем флаг блокировки если не было обнаружено ни одной ошибки
if [ "$FLAG" = "1" ]
then
  echo "1" > /tmp/custom/drbd/flag
fi

exit 0

Цель скрипта в том, чтобы сделать доступным виртуальное блочное устройство в том случае, если доступен в полной мере один или более из его членов. Для кластерных систем достаточно было бы сделать всех членов блочного устройства доступными для чтения и записи (условно говоря, сделать всем роли Primary), но в нашем случае необходимо следить за отсутствием конфликтов чтения/записи и целостностью данных членов виртуального устройства. Суть в том, что если скрипт обнаружит недоступность того из членов DRBD устройства, что должен иметь роль первичного, об этом должен сразу же узнать администратор, провести соответствующие работы с последующим восстановлением файловой системы.

Одна из операций созданного нами скрипта производит проверку на подключение виртуального устройства с помощью команды "drbdadm cstate". У упомянутой команды довольно многовариантный вывод, но только одно из них говорит о том, что все члены виртуального устройства подключены и доступны, это: "Connected" - оно говорит о том, что все устройства на связи и готовы к любым операциям с ними. Все остальные варианты вывода команды "drbdadm cstate" говорят о том или ином уровне недоступности устройства и все эти состояния возникают в момент неисправности связки членов виртуального устройства, что служит достаточным поводом объявить тревогу. Устройства могут быть недоступны в момент ввода их в рабочую схему, и для обхода этих критических ситуаций мы создали ручной список проверяемых DRBD устройств; просто не будем включать в него устройства, что ещё не синхронизированы и не введены в рабочую схему.

Созданный нами скрипт автоматического применения ролей членов устройств DRBD должен запускаться периодически. Думаю, что период в десять минут вполне приемлем; если роли к устройствам уже применены ранее, то скрипт просто это проверит (доли секунды), а в случае сбоя работы устройств - чем раньше мы это обнаружим, тем лучше.

И так, размещаем команду запуска скрипта в таблице /etc/crontab:

# cat /etc/crontab

....
*/10  * * * *   root    /etc/custom/hdd/drbd/check-drbd.sh &
....

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

# cat /etc/init.d/drbd

....
case "$1" in
  start)
....
      # Проверяем успешность загрузки модуля DRBD по наличию созданных им служебных конструкций
      if [ -e /proc/drbd ]
      then
        /etc/custom/hdd/drbd/check-drbd.sh &
        echo >&2 "DRBD driver started."
....
  reload)
....
    drbdadm adjust all
    /etc/custom/hdd/drbd/check-drbd.sh &
  ;;
....


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )