Solving IT problems and building solutions

  • Wednesday, November 7, 2012

    Отказоустойчивый кластер на Ubuntu

    Кластер – это набор независимых компьютеров, работающих совместно для повышения доступности служб и приложений. Кластеризованные серверы (называемые узлами) соединены друг с другом с помощью кабелей и программного обеспечения. В случае отказа одного узла предоставлять услугу начинает другой узел, используя процесс, называемый перемещением.Отказоустойчивые кластеры (High-availability clusters, HA, кластеры высокой доступности) создаются для обеспечения высокой доступности сервиса, предоставляемого кластером. Избыточное число узлов, входящих в кластер, гарантирует предоставление сервиса в случае отказа одного или нескольких серверов. Типичное число узлов — два, это минимальное количество, приводящее к повышению доступности. Создано множество программных решений для построения такого рода кластеров.
    Что получим: Два сервера объединённых в кластер, при том что каждый из них (UbuntuServer1 и UbuntuServer2) будет считать себя резервным (делаем это осознанно, чтобы в обычном режиме работы, запросы обрабатывали оба сервера, каждый по своему ip, а в случае отключения одного из серверов, работающий будет обрабатывать запросы к первому и второму серверам). В случае падения «псевдо основного» на резервном поднимался ip адрес «псевдо основной» ноды кластера. Тоесть при падении одного из серверов, другой сервер возьмёт обслуживание запросов «упавшего» сервера на себя. Между серверами будет организован drbd в режиме primary-primary, тоесть на каждом из серверов будут актуальные данные, файлы пользователей (раздел home), а режим primary-primary позволит монтировать эти разделы на каждом из нод. На каждом сервере будет по два жёстких диска (виртуальных), один под сиситему, второй под блочное устройство drbd на котором распологаться будет home.
    Так же вместо использования drbd можно использовать распределённую реплицируемую  файловую систему GlusterFS.
    1. Установка Ubuntu (на двух серверах).
    Установка системы производиться в серверном варианте, без рабочих столов и X-сервера. После чего производиться доустановка всех необходимых пакетов для работы сервера и выполнения его основных функций.
    UbuntuServer1:
    eth0 10.250.30.201/24 (для подключения к нему пользователей, осн работы)
     
    eth1 10.0.3.201/24 (для HeartBeat)
    UbuntuServer2:
    eth0 10.250.30.205/24 (для подключения к нему пользователей, осн работы)
     
    eth1 10.0.3.205/24 (для HeartBeat)
    2. Организация кластера с помощью Heartbeat
    1. Установка heartbeat
    $ sudo apt-get install heartbeat
    2. Настройка heartbeat
    В /etc/ha.d/authkeys добавляем:
    auth 2
    2 sha1 password
    Затем назначаем разрешения на чтение этого файла только для пользователя “root”:
    root@UbuntuServer1 ~# chmod 600 /etc/ha.d/authkeys
     
    root@UbuntuServer2 ~# chmod 600 /etc/ha.d/authkeys
    В файл /etc/ha.d/ha.cf (на обоих серверах), добавим:
    autojoin none
     
    logfacility local0
     
    udpport 694
     
    bcast (eth0) eth1
     
    keepalive 40ms
     
    warntime 1
     
    deadtime 2
     
    #initdead 10
     
    auto_failback on # при восстановлении «упавшего» сервера адрес вернуть
     
    node UbuntuServer1 # в /etc/hosts должны быть прописаны оба сервера, на серверах
     
    node UbuntuServer2 # 10.0.3.201 UbuntuServer1, 10.0.3.205 UbuntuServer2 см. uname -n
     
    respawn hacluster /usr/lib/heartbeat/ipfail
     
    use_logd yes
     
    debugfile /var/log/ha-debug
     
    logfile /var/log/ha-log
    Создадим файлы для логов heartbeat на обеих нодах:
    root@UbuntuServer1 ~# touch /var/log/{ha-log,ha-debug}
     
    root@UbuntuServer2 ~# touch /var/log/{ha-log,ha-debug}
    Добавляем Heartbeat в запуск при старте системы (если chkconfig нет в системе его можно установить apt-get install chkconfig):
    root@UbuntuServer1 ~# chkconfig --level 2345 heartbeat on
     
    root@UbuntuServer2 ~# chkconfig --level 2345 heartbeat on
    Редактируем/создаём файл /etc/ha.d/haresources
    для UbuntuServer1:
    UbuntuServer2 Ipaddr::10.250.30.205/24 "здесь можно указать разделяемую службу"
    для UbuntuServer2:
    UbuntuServer1 Ipaddr::10.250.30.201/24 "здесь можно указать разделяемую службу"
    В соответствии с этими настройками на «псевдо-резервном» сервере будет подниматься интерфейс упавшего, и «разделяемая» служба.
    3. Установка и настройка блочного сетевого устройства (DRBD) для создания RAID1 по сети.
    Как показала практика при высокой нагрузке на реплецируемую распределённую систему хранения данных, лучше использовать в случае с кластером серверов — GlusterFS, а не связку drbd+ocfs2, так как она даёт меньшую нагрузку на систему.
    3.1. Установка DRBD
    $sudo apt-get install drbd8-module-source drbd8-utils (на обоих серверах)
    3.2 Настройка DRBD
    Смотрим какой раздел у нас под блочное устройство:
    $sudo fdisk -l
    (на обоих серверах)
    В нашем случае /dev/sdb
    Создаём раздел на /dev/sdb (на обоих серверах):
    $sudo fdisk /dev/sdb
     
    Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
     
    Building a new DOS disklabelwith disk identifier 0x882944df.
     
    Changes will remain in memory only, until you decide to write them.
     
    After that, of course, the previous content won't be recoverable.
     
    The number of cylinders for this disk is set to 20480.
     
    There is nothing wrong with that, but this is larger than 1024,
     
    and could in certain setups cause problems with:
     
    1)software that runs at boot time (e.g., old versions of LILO)
     
    2)booting and partitioning software from other OSs
     
    (e.g., DOS FDISK, OS/2 FDISK)
     
    Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
     
    Command (m for help):<-- n
     
    Command action
     
    e extended
     
    p primary partition (1-4)<-- p
     
    Partition number (1-4):<-- 1
     
    First cylinder (1-20480, default 1): <-- ENTER
     
    Using default value 1
     
    Last cylinder or +size or +sizeM or +sizeK (1-20480, default 280480): <-- ENTER
     
    Using default value 20480
     
    Command (m for help):<-- t
     
    Selected partition 1
     
    Hex code (type L to list codes):<-- 83
     
    Command (m for help):<-- w
     
    The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.
    Теперь на каждом из серверов есть раздел /dev/sdb1
    Конфигурируем сам DRBD (на двух серверах):
    $sudo nano /etc/drbd.d/global_common.conf
     
    global {
     
    usage-count no; он-лайн статистика на сайте разработчиков откл.
     
    }
     
    common {
     
    protocol C
     
    }
     
    resource r0 {
     
    startup {
     
    become-primary-on both;
     
    }
     
    net {
     
    allow-two-primaries;
     
    cram-hmac-alg sha1;
     
    shared-secret "123456";
     
    after-sb-0pri discard-zero-changes;
     
    after-sb-1pri discard-secondary;
     
    after-sb-2pri disconnect;
     
    rr-conflict violently;
     
    }
     
    syncer {
     
    rate 40M;
     
    }
     
    on UbuntuServer1 {
     
    device /dev/drbd0;
     
    disk /dev/sdb1;
     
    address 10.0.3.201:7789;
     
    meta-disk internal;
     
    }
     
    on UbuntuServer2 {
     
    device /dev/drbd0;
     
    disk /dev/sdb1;
     
    address 10.0.3.205:7789;
     
    meta-disk internal;
     
    }
     
    }
    В /etc/drbd.conf закомментировать строчку «include »drbd.d/*.res»;».
    Очищаем /dev/sdb1 (на двух серверах, процесс долгий, можно не дожиться окончания и прервать минут через 5-10):
    $sudo dd if=/dev/zero of=/dev/sdb1
    Инициализируем метаданные DRBD (на обоих серверах):
    $sudo drbdadm create-md r0
    После успешной инициализации, запускаем drbd на обоих нодах:
    $sudo service drbd start
    Переводим одну из нод (UbuntuServer1) в состояние Primary:
    $sudo drbdsetup /dev/drbd0 primary -o
    Дождаться окончания синхронизации, отслеживать процесс:
    $cat /proc/drbd
    После окончания синхронизации на второй ноде выполнить:
    $sudo drbdsetup /dev/drbd0 primary -o
    Теперь у нас есть два сервера с drbd в режиме primary-primary, что даст нам возможность монтировать устройства на своих серверах локально и не только.
    4. Установка и настройка кластерной файловой системы OCFS2
    4.1. Установка OCFS2
    $sudo apt-get install ocfs2-tools
    4.2 Настройка OCFS2
    Форматирование устройства /dev/drbd0 в ocfs2 (только на одной из нод):
    $sudo mkfs.ocfs2 -b 4K -N 2 -v /dev/drbd0
    Далее для того, чтобы было возможно монтирование раздела по ocfs2 нам надо настроить для него кластер o2cb:
    Создаём файл конфигурации кластера для OCFS2 (на обоих нодах, файл чувствителен к пробелам и табуляции):
    $sudo nano /etc/ocfs2/cluster.conf
     
    cluster:
     
    node_count = 2
     
    name = ocfs2
     
    node:
     
    ip_port = 7777
     
    ip_address = 10.0.3.201
     
    number = 0
     
    name = UbuntuServer1
     
    cluster = ocfs2
     
    node:
     
    ip_port = 7777
     
    ip_address = 10.0.3.205
     
    number = 1
     
    name = UbuntuServer2
     
    cluster = ocfs2
    Загружаем модули и запускаем кластер o2cb на обоих нодах:
    $sudo /etc/init.d/o2cb load
     
    $sudo /etc/init.d/o2cb online
    Запустить конфигуратор ocfs2, в котором выбрать «да» при вопросе о запуске ocfs2 при загрузке системы (либо в /etc/default/o2cb в строке O2CB_ENABLE поставить true), остальное оставить как есть.
    $sudo dpkg-reconfigure ocfs2-tools
    5. Монтирование файловой системы ocfs2 и автомонтирование
    Производим монтирование раздела в /home по ocfs2 на обоих нодах:
    $sudo mount -t ocfs2 /dev/drbd0 /home
    Создадим скрипт на обоих нодах /etc/init.d/mountdrbd для монтирования раздела drbd (fstab в данном случае не подошёл, т. к. монтирует до запуска drbd, тоесть не сможет смонтировать):
    $sudo nano /etc/init.d/mountdrbd
     
    #!/bin/bash
     
    mount -t ocfs2 /dev/drbd0 /etc_drbd
    Сделать файл скрипта выполняемым:
    $sudo chmod 755 /etc/init.d/mountdrbd
    Сделать символические ссылки (на обоих нодах) на /etc/init.d/mountdrbd вида /etc/rc2.d/@S72mountdrbd, /etc/rc3.d/@S72mountdrbd, /etc/rc4.d/@S72mountdrbd, /etc/rc5.d/@S72mountdrbd.
    6. Заметки
    Если случилась неприятная ситуация, когда основной сервер просто грубо перезагрузили, а на втором – подняли drbd primary. Синхронизация нарушилась, и связка primary/secondary перестала работать. Нужно тот сервер, который упал или который грубо перезагружали насильно синхронизировать (допустим, это UbuntuServer1):
    UbuntuServer1:~ # drbdadm -- --discard-my-data connect all
     
    UbunruServer2:~ # drbdadm connect all

    No comments:

    Post a Comment