Бесплатная замена VMware vSphere Storage Appliance на основе DRBD

    Недавно компания VMware анонсировала новые продукты в линейке vSphere 5, и нам стало очень интересно, что же такое VMware vSphere Storage Appliance?

    Вкратце суть заключается в возможности построения отказоустойчивой виртуальной инфраструктуры без внешней СХД. Для реализации устанавливается две или три виртуальные машины (по одной на каждый хост), которые реплицируют между собой свободное пространство дисковой подсистемы ESXi-серверов и предоставляют его в качестве общего хранилища все тем же хостам ESXi. Подробно на русском языке Storage Appliance описан здесь.

    Интересная задумка, но кусается цена — в районе $6К. Кроме того, если задуматься о производительности, то не получится ли просадки по скорости работы дискового массива? Подходя к вопросу с другой стороны, можно придумать много других способов организации внешней СХД. Например, можно создать внешнее хранилище из практически любого железа с необходимым количеством дисков и установленным софтом Openfiler, FreeNAS, Nexenta, Open-E — в этих программных продуктах есть возможность репликации между системами.

    Такой подход практикуют многие компании, у которых нет возможности приобрести дорогостоящую СХД именитого производителя, которая бы обеспечила достаточную производительность и надежность. Как правило, такие системы оснащаются двумя контроллерами, избыточной системой питания, скоростными дисками и прочее…

    Впрочем, вернемся к началу и посмотрим на схему, которую предлагает VMware:



    Что мы видим? 3 хоста ESXi с развернутыми на них виртуальными машинами по одной на каждый хост. Машины собраны в кластер и отдают нам внутренние диски как внешние.

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

    Решений по построению отказоустойчивого хранилища — куча, например, на основе Openfiler+DRBD+Heartbeat. Но в основе всех этих решений лежит идея построения именно внешнего хранилища. Почему бы не попробовать сделать что-то подобное, но на основе виртуальных машин?

    В качестве фундамента возьмем 2 виртуалки с OS Ubuntu, документацию Ubuntu по построению failover iSCSI-target и попытаемся сделать свой Appliance.

    Разбиение дисков на обоих узлах кластера:

    /dev/sda1 - 10 GB / (primary' ext3, Bootable flag: on)
    /dev/sda5 - 1 GB swap (logical)

    /dev/sdb1 - 1 GB (primary) DRBD meta-данные. Не монтируем.
    /dev/sdc1 - 1 GB (primary) DRBD диск, используемый для хранения конфигурационных файлов iSCSI. Не монтируем.
    /dev/sdd1 - 50 GB (primary) DRBD диск для iSCSI-target.


    Размер диска sdd1 выбран для примера. На самом деле берется все оставшееся свободное место на локальном хранилище ESXi-хоста.

    Сеть iSCSI:
    iSCSI server1: node1.demo.local IP address: 10.11.55.55
    iSCSI server2: node2.demo.local IP address: 10.11.55.56
    iSCSI Virtual IP address 10.11.55.50


    Приватная сеть:
    iSCSI server1: node1-private IP address: 192.168.22.11
    iSCSI server2: node2-private IP address: 192.168.22.12


    /etc/network/interfaces:

    Для node1:
    auto eth0
    iface eth0 inet static
    address 10.11.55.55
    netmask 255.0.0.0
    gateway 10.0.0.1

    auto eth1
    iface eth1 inet static
    address 192.168.22.11
    netmask 255.255.255.0


    Для node2:
    auto eth0
    iface eth0 inet static
    address 10.11.55.56
    netmask 255.0.0.0
    gateway 10.0.0.1

    auto eth1
    iface eth1 inet static
    address 192.168.22.12
    netmask 255.255.255.0


    Файл /etc/hosts для обоих узлов:

    127.0.0.1 localhost
    10.11.55.55 node1.demo.local node1
    10.11.55.56 node2.demo.local node2
    192.168.22.11 node1-private
    192.168.22.12 node2-private


    Установка пакетов:
    apt-get -y install ntp ssh drbd8-utils heartbeat jfsutils

    Перезагрузим серверы.

    Меняем владельцев файлов и разрешения на них:
    chgrp haclient /sbin/drbdsetup
    chmod o-x /sbin/drbdsetup
    chmod u+s /sbin/drbdsetup
    chgrp haclient /sbin/drbdmeta
    chmod o-x /sbin/drbdmeta
    chmod u+s /sbin/drbdmeta


    Используем /etc/drbd.conf для описания конфигурации. Определяем 2 ресурса:
    1. DRBD устройство, которое будет содержать файлы конфигурации ISCSI;
    2. DRBD устройство, которое станет нашим ISCSI-target.

    Для node1:

    /etc/drbd.conf:

    resource iscsi.config {
    protocol C;

    handlers {
    pri-on-incon-degr "echo o > /proc/sysrq-trigger ; halt -f";
    pri-lost-after-sb "echo o > /proc/sysrq-trigger ; halt -f";
    local-io-error "echo o > /proc/sysrq-trigger ; halt -f";
    outdate-peer "/usr/lib/heartbeat/drbd-peer-outdater -t 5";
    }

    startup {
    degr-wfc-timeout 120;
    }

    disk {
    on-io-error detach;
    }

    net {
    cram-hmac-alg sha1;
    shared-secret "password";
    after-sb-0pri disconnect;
    after-sb-1pri disconnect;
    after-sb-2pri disconnect;
    rr-conflict disconnect;
    }

    syncer {
    rate 100M;
    verify-alg sha1;
    al-extents 257;
    }

    on node1 {
    device /dev/drbd0;
    disk /dev/sdc1;
    address 192.168.22.11:7788;
    meta-disk /dev/sdb1[0];
    }

    on node2 {
    device /dev/drbd0;
    disk /dev/sdc1;
    address 192.168.22.12:7788;
    meta-disk /dev/sdb1[0];
    }
    }

    resource iscsi.target.0 {
    protocol C;

    handlers {
    pri-on-incon-degr "echo o > /proc/sysrq-trigger ; halt -f";
    pri-lost-after-sb "echo o > /proc/sysrq-trigger ; halt -f";
    local-io-error "echo o > /proc/sysrq-trigger ; halt -f";
    outdate-peer "/usr/lib/heartbeat/drbd-peer-outdater -t 5";
    }

    startup {
    degr-wfc-timeout 120;
    }

    disk {
    on-io-error detach;
    }

    net {
    cram-hmac-alg sha1;
    shared-secret "password";
    after-sb-0pri disconnect;
    after-sb-1pri disconnect;
    after-sb-2pri disconnect;
    rr-conflict disconnect;
    }

    syncer {
    rate 100M;
    verify-alg sha1;
    al-extents 257;
    }

    on node1 {
    device /dev/drbd1;
    disk /dev/sdd1;
    address 192.168.22.11:7789;
    meta-disk /dev/sdb1[1];
    }

    on node2 {
    device /dev/drbd1;
    disk /dev/sdd1;
    address 192.168.22.12:7789;
    meta-disk /dev/sdb1[1];
    }
    }


    Копируем конфигурацию на второй узел:
    scp /etc/drbd.conf root@10.11.55.56:/etc/

    Инициализируем диски с мета-данными на обоих серверах:
    [node1]dd if=/dev/zero of=/dev/sdс1
    [node1]dd if=/dev/zero of=/dev/sdd1
    [node1]drbdadm create-md iscsi.config
    [node1]drbdadm create-md iscsi.target.0

    [node2]dd if=/dev/zero of=/dev/sdс1
    [node2]dd if=/dev/zero of=/dev/sdd1
    [node2]drbdadm create-md iscsi.config
    [node2]drbdadm create-md iscsi.target.0


    Запускаем drbd:
    [node1]/etc/init.d/drbd start
    [node2]/etc/init.d/drbd start


    Теперь необходимо решить, какой сервер будет выступать первичным, а какой вторичным, чтобы выполнить синхронизацию между дисками. Допустим, что первичным (Primary) будет node1.
    Выполним команду на первом узле:
    [node1]drbdadm -- --overwrite-data-of-peer primary iscsi.config

    Вывод команды
    cat /proc/drbd:

    version: 8.3.9 (api:88/proto:86-95)
    srcversion: CF228D42875CF3A43F2945A
    0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:1048542 nr:0 dw:0 dr:1048747 al:0 bm:64 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
    1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:52428768


    Отформатируем и монтируем раздел /dev/drbd0:
    [node1]mkfs.ext3 /dev/drbd0
    [node1]mkdir -p /srv/data
    [node1]mount /dev/drbd0 /srv/data


    Создадим файл на первом узле и затем переключим второй в режим Primary:
    [node1]dd if=/dev/zero of=/srv/data/test.zeros bs=1M count=100

    Для node1:
    [node1]umount /srv/data
    [node1]drbdadm secondary iscsi.config


    Для node2:
    [node2]mkdir -p /srv/data
    [node2]drbdadm primary iscsi.config
    [node2]mount /dev/drbd0 /srv/data


    На втором узле будет виден файл размером 100 Мб.
    ls –l /srv/data

    Удаляем его и опять переключаемся на первый узел:

    On node2:
    [node2]rm /srv/data/test.zeros
    [node2]umount /srv/data
    [node2]drbdadm secondary iscsi.config


    On node1:
    [node1]drbdadm primary iscsi.config
    [node1]mount /dev/drbd0 /srv/data


    Выполним команду ls /srv/data. Если на разделе никаких данных нет, значит репликация прошла успешно.

    Переходим к установке iSCSI-target. Выбираем первый узел как Primary и выполняем синхронизацию разделов:
    [node1]drbdadm -- --overwrite-data-of-peer primary iscsi.target.0

    cat /proc/drbd

    version: 8.3.9 (api:88/proto:86-95)
    srcversion: CF228D42875CF3A43F2945A
    0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:135933 nr:96 dw:136029 dr:834 al:39 bm:8 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
    1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:1012864 nr:0 dw:0 dr:1021261 al:0 bm:61 lo:1 pe:4 ua:64 ap:0 ep:1 wo:f oos:51416288
    [>....................] sync'ed: 2.0% (50208/51196)M
    finish: 0:08:27 speed: 101,248 (101,248) K/sec


    Дождемся синхронизации…

    cat /proc/drbd

    version: 8.3.9 (api:88/proto:86-95)
    srcversion: CF228D42875CF3A43F2945A
    0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:135933 nr:96 dw:136029 dr:834 al:39 bm:8 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
    1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:52428766 nr:0 dw:0 dr:52428971 al:0 bm:3200 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0


    Устанавливаем пакет iscsitarget на обоих узлах:
    [node1]apt-get -y install iscsitarget
    [node2]apt-get -y install iscsitarget


    Включаем опцию запуска iscsi как сервиса:
    [node1]sed -i s/false/true/ /etc/default/iscsitarget
    [node2]sed -i s/false/true/ /etc/default/iscsitarget


    Удаляем записи со всех скриптов:
    [node1]update-rc.d -f iscsitarget remove
    [node2]update-rc.d -f iscsitarget remove


    Перемещаем конфиг.файлы на drbd раздел:
    [node1]mkdir /srv/data/iscsi
    [node1] mv /etc/iet/ietd.conf /srv/data/iscsi
    [node1]ln -s /srv/data/iscsi/ietd.conf /etc/iet/ietd.conf
    [node2]rm /etc/iet/ietd.conf
    [node2]ln -s /srv/data/iscsi/ietd.conf /etc/iet/ietd.conf


    Описываем iSCSI-target в файле /srv/data/iscsi/ietd.conf:

    Target iqn.2011-08.local.demo:storage.disk.0
    # IncomingUser geekshlby secret - закомментируем, чтоб не авторизоваться при подключении
    # OutgoingUser geekshlby password
    Lun 0 Path=/dev/drbd1,Type=blockio
    Alias disk0
    MaxConnections 1
    InitialR2T Yes
    ImmediateData No
    MaxRecvDataSegmentLength 8192
    MaxXmitDataSegmentLength 8192
    MaxBurstLength 262144
    FirstBurstLength 65536
    DefaultTime2Wait 2
    DefaultTime2Retain 20
    MaxOutstandingR2T 8
    DataPDUInOrder Yes
    DataSequenceInOrder Yes
    ErrorRecoveryLevel 0
    HeaderDigest CRC32C,None
    DataDigest CRC32C,None
    Wthreads 8


    Теперь необходимо настроить heartbeat для контроля за виртуальным IP-адресом iSCSI-target’а при отказе узла.

    Описываем кластер в файле /etc/heartbeat/ha.cf:

    logfacility local0
    keepalive 2
    deadtime 30
    warntime 10
    initdead 120
    bcast eth0
    bcast eth1
    node node1
    node node2


    Механизм аутентификации
    /etc/heartbeat/authkeys:

    auth 2
    2 sha1 NoOneKnowsIt


    Меняем разрешения на файл /etc/heartbeat/authkeys:
    chmod 600 /etc/heartbeat/authkeys

    Описываем ресурсы кластера в файле /etc/heartbeat/haresources — главный узел, виртуальный IP, файловые системы и службы, которые будут запускаться:

    /etc/heartbeat/haresources

    node1 drbddisk::iscsi.config Filesystem::/dev/drbd0::/srv/data::ext3
    node1 IPaddr::10.11.55.50/8/eth0 drbddisk::iscsi.target.0 iscsitarget


    Копируем конфигурацию на второй узел:
    [node1]scp /etc/heartbeat/ha.cf root@10.11.55.56:/etc/heartbeat/
    [node1]scp /etc/heartbeat/authkeys root@10.11.55.56:/etc/heartbeat/
    [node1]scp /etc/heartbeat/haresources root@10.11.55.56:/etc/heartbeat/


    Отмонтируем /srv/data, делаем первый узел как Secondary.
    Стартуем heartbeat
    [node1]/etc/init.d/heartbeat start

    Перезагружаем оба сервера.

    [node1]/etc/init.d/drbd start
    [node2]/etc/init.d/drbd start

    [node1]drbdadm secondary iscsi.config - необязательно
    [node1]drbdadm secondary iscsi.target.0 - необязательно

    [node2]drbdadm primary iscsi.config
    [node2]drbdadm primary iscsi.target.0

    [node1]cat /proc/drbd

    [node1]/etc/init.d/heartbeat start


    После старта heartbeat’а переводим первый узел в режим primary, второй — secondary (в противном случае, не заведется).

    [node2]drbdadm secondary iscsi.config
    [node2]drbdadm secondary iscsi.target.0

    [node1]drbdadm primary iscsi.config
    [node1]drbdadm primary iscsi.target.0


    Смотрим tail –f /var/log/syslog
    Ждем…
    Спустя некоторое время…

    Aug 26 08:32:14 node1 harc[11878]: info: Running /etc/ha.d//rc.d/ip-request-resp ip-request-resp
    Aug 26 08:32:14 node1 ip-request-resp[11878]: received ip-request-resp IPaddr::10.11.55.50/8/eth0 OK yes
    Aug 26 08:32:14 node1 ResourceManager[11899]: info: Acquiring resource group: node1 IPaddr::10.11.55.50/8/eth0 drbddisk::iscsi.target.0 iscsitarget
    Aug 26 08:32:14 node1 IPaddr[11926]: INFO: Resource is stopped
    Aug 26 08:32:14 node1 ResourceManager[11899]: info: Running /etc/ha.d/resource.d/IPaddr 10.11.55.50/8/eth0 start
    Aug 26 08:32:14 node1 IPaddr[12006]: INFO: Using calculated netmask for 10.11.55.50: 255.0.0.0
    Aug 26 08:32:14 node1 IPaddr[12006]: INFO: eval ifconfig eth0:0 10.11.55.50 netmask 255.0.0.0 broadcast 10.255.255.255
    Aug 26 08:32:14 node1 avahi-daemon[477]: Registering new address record for 10.11.55.50 on eth0.IPv4.
    Aug 26 08:32:14 node1 IPaddr[11982]: INFO: Success
    Aug 26 08:32:15 node1 ResourceManager[11899]: info: Running /etc/init.d/iscsitarget start
    Aug 26 08:32:15 node1 kernel: [ 5402.722552] iSCSI Enterprise Target Software - version 1.4.20.2
    Aug 26 08:32:15 node1 kernel: [ 5402.723978] iscsi_trgt: Registered io type fileio
    Aug 26 08:32:15 node1 kernel: [ 5402.724057] iscsi_trgt: Registered io type blockio
    Aug 26 08:32:15 node1 kernel: [ 5402.724061] iscsi_trgt: Registered io type nullio
    Aug 26 08:32:15 node1 heartbeat: [12129]: debug: notify_world: setting SIGCHLD Handler to SIG_DFL
    Aug 26 08:32:15 node1 harc[12129]: info: Running /etc/ha.d//rc.d/ip-request-resp ip-request-resp
    Aug 26 08:32:15 node1 ip-request-resp[12129]: received ip-request-resp IPaddr::10.11.55.50/8/eth0 OK yes
    Aug 26 08:32:15 node1 ResourceManager[12155]: info: Acquiring resource group: node1 IPaddr::10.11.55.50/8/eth0 drbddisk::iscsi.target.0 iscsitarget
    Aug 26 08:32:15 node1 IPaddr[12186]: INFO: Running OK
    Aug 26 08:33:08 node1 ntpd[1634]: Listen normally on 11 eth0:0 10.11.55.50 UDP 123
    Aug 26 08:33:08 node1 ntpd[1634]: new interface(s) found: waking up resolver


    ifconfig
    eth0 Link encap:Ethernet HWaddr 00:50:56:20:f9:6c
    inet addr:10.11.55.55 Bcast:10.255.255.255 Mask:255.0.0.0
    inet6 addr: fe80::20c:29ff:fe20:f96c/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:3622 errors:0 dropped:0 overruns:0 frame:0
    TX packets:8081 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:302472 (302.4 KB) TX bytes:6943622 (6.9 MB)
    Interrupt:19 Base address:0x2000

    eth0:0 Link encap:Ethernet HWaddr 00:50:56:20:f9:6c
    inet addr:10.11.55.50 Bcast:10.255.255.255 Mask:255.0.0.0
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    Interrupt:19 Base address:0x2000


    eth1 Link encap:Ethernet HWaddr 00:50:56:20:f9:76
    inet addr:192.168.22.11 Bcast:192.168.22.255 Mask:255.255.255.0
    inet6 addr: fe80::20c:29ff:fe20:f976/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:1765 errors:0 dropped:0 overruns:0 frame:0
    TX packets:3064 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:171179 (171.1 KB) TX bytes:492567 (492.5 KB)
    Interrupt:19 Base address:0x2080


    Подключаем получившийся iSCSI-target к обоим хостам ESX(i). После того как оба хоста увидели СХД собираем HA-кластер. Хотя места для создания виртуальных машин на самих хостах и не осталось, теперь это место представляется виртуальным хранилищем. При отказе любого из узлов виртуальная машина на втором узле перейдет в режим Primary и будет продолжать работу как iSCSI-target.

    С помощью hdparm замерил скорость работы диска в виртуальной машине, установленной на target'e:



    Естественно, для серьезных production-систем такая СХД не подойдет. Но если нет высоконагруженных виртуальных машин или необходимо протестировать возможность построения HA-кластера, то такой способ предоставления общего хранилища имеет право на жизнь.

    Прочитав данный материал, многие возможно скажут, что это «неправильно», «будут просадки по производительности», «возможность отказа обоих узлов» и т.д. Да! Может, оно так все и будет, но ведь, зачем-то компания VMware выпустила свой Storage Appliance?

    P.S.: Кстати, кому лень лопатить все вручную, существует Management Console для настройки DRBD-кластера: http://www.drbd.org/mc/screenshot-gallery/.

    madbug,
    старший системный инженер DEPO Computers
    DEPO Computers
    86.46
    Company
    Share post

    Comments 13

      +1
      Сразу напрашивается вопрос, если нет денег, то нафига использовать VMware?
        +3
        Представьте себе такую ситуацию, что был куплен один сервер. Поработал какое-то время, затем купили второй, захотели построить отказоустойчивую конфигурацию, но денег впритык — хватило только на лицензии. А свободного места на локальных хардах еще много.
          0
          Как-то не корпоративно, по домашнему, чтоли
            +1
            Почти в самом низу: «Естественно, для серьезных production-систем такая СХД не подойдет.»
              +1
              Да я не про реализацию… Виртуальная СХД, вообще не для серьезных вещей. Я про подход
                +1
                Не спорю. Однако сама vmware зачем-то выпустила свой продукт. Видимо из тех же соображений, что когда нет денег на нормальную схд, то почему бы не воспользоваться тем, что есть сейчас.
            +1
            Если денег хватает на лицензии VMware и не хватает на хранилище, то может имеет смысл воспользоваться бесплатными версиями софта для виртуализации а деньги пустить на хранилище?
            А уж зачем тот или иной разработчик выпускает приложения, иногда и сам разработчик не знает, пришла кому то из руководства мысль вот ее и реализовали.
            +2
            Почему не GlusterFS?
              +2
              Может, чуть позже то же самое попробую сделать на GlusterFS.
              +3
              Я так понимаю, что в вашем решении split brain никак не учитывается?
                +3
                Да, недочет, надо учесть замечание, спасибо.
                +2
                А теперь перезагрузите их пару раз рандомно. Да и вообще, поэксплуатируйте полученную систему пару месяцев. Увлекательные приключения гарантирую.
                  0
                  Согласен с вами. Использование DRBD неоправданно, так как при падении одной из ноды, получится отличный геморрой с синхронизацией нод.

                Only users with full accounts can post comments. Log in, please.