Масштабируемый отказоустойчивый файловый сервис на базе CTDB, GlusterFS

Статья является пошаговым руководством по построению масштабируемого отказоустойчивого файлового хранилища, доступ к которому будет осуществлен по протоколам Samba, NFS. В качестве файловой системы, которая будет непосредственно отвечать за сохранение и масштабирование файловой шары будем использовать GlusterFS, о котором было уже достаточно написано хабрасообществом. Так как GlusterFS — часть Red Hat Storage, туториал написан для RH — like систем.



Каким же образом эти сервисы взаемодействуют?

GlusterFS

Использую версию 3.3.1, rpm-ки скачаны с официального сайта. После создания volume, клиент может получить к нему доступ несколькими способами:
  • # mount.glusterfs
  • # mount -o mountproto=tcp,async -t nfs
  • # mount.cifs

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


CTDB

Отлично механика работы описана в этом посте. Хотелось бы добавить, что распределение нагрузки на кластер с использованием LVS в документации прописана только для сети NAT, по этому будем использовать Round Robbin DNS. Есть в стандартных репозиториях, так же как и SMB, NFS:
# yum install ctdb samba nfs-utils cifs-utils

Приступим

Допустим, у нас есть 2 ноды:
gluster1, 192.168.122.100
gluster2, 192.168.122.101

Еще необходима парочка IP, которые будут воплощать отказоустойчивость — мигрировать между серверами.
192.168.122.200
192.168.122.201

RR DNS для домена data выглядит так:

; zone file fragment
data. 86400 IN A 192.168.122.200
data. 86400 IN A 192.168.122.201

В создание volume для GlusterFS я углубляться не буду. Скажу, что нам необходимо распределенно — репликационный раздел (distributed+replicated volume). Назовём его smb. Для начала монтируем его локально для каждой ноды:

# mount.glusterfs gluster1:smb /mnt/glustersmb

Каждый сервер в качестве опции использует свой hostname . Не забываем занести запись в /etc/fstab.
Теперь правим конфигурацию Samba (на каждом сервере).

# vim /etc/samba/smb.conf

[global]
# Основной параметр, отвечает за кластеризацию.
clustering = yes
# Связь с БД, которая хранит обращения пользователей (см. ссылку про механику работы )
idmap backend = tdb2
# Папка, с конфигурационными файлами
private dir = /mnt/glustersmb/lock

И туда же добавим секцию самой шары:
[pub]
path = /mnt/glustersmb/lock
browseable = YES
force user = smbcli
force group = smbcli
writable = yes
guest ok = yes
guest account = smbcli
guest only = yes

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

# mkdir /mnt/glustersmb/lock
И добавим файл:
# touch /mnt/glustersmb/lock/lockfile

Конфигурационный файл CTDB на каждом сервере приводим к виду:
# vim /etc/sysconfig/ctdb
CTDB_RECOVERY_LOCK=/mnt/glustersmb/lock/lockfile
CTDB_PUBLIC_ADDRESSES=/etc/ctdb/public_addresses
CTDB_MANAGES_SAMBA=yes
CTDB_NODES=/etc/ctdb/nodes
CTDB_MANAGES_NFS=yes
# Файл, который исполняется каждый раз, когда нода кластера CTDB изменяет свой статус (например письмецо отправлять)
CTDB_NOTIFY_SCRIPT=/etc/ctdb/notify.sh

Указываем наши public adresses (на каждом сервере):
# vim /etc/ctdb/public_addesses
192.168.122.200/24 eth0
192.168.122.201/24 eth0

Указываем ноды кластера CTDB (на каждом сервере):
# vim /etc/ctdb/nodes
192.168.122.100
192.168.122.101

SElinux я отключаю, IPtables выглядят следующим образом (естественно, для каждого сервера):
# vim /etc/sysconfig/iptables
-A INPUT -p tcp --dport 4379 -j ctdb
-A INPUT -p udp --dport 4379 -j ctdb
-A INPUT -p tcp -m multiport --ports 137:139,445 -m comment --comment "SAMBA" -j SMB
-A INPUT -p udp -m multiport --ports 137:139,445 -m comment --comment "SAMBA" -j SMB
-A INPUT -p tcp -m multiport --ports 111,2049,595:599 -j NFS
-A INPUT -p udp -m multiport --ports 111,2049,595:599 -j NFS
-A INPUT -p tcp -m tcp --dport 24007:24220 -m comment --comment "Gluster daemon" -j ACCEPT
-A INPUT -p tcp -m tcp --dport 38465:38667 -m comment --comment "Gluster daemon(nfs ports)" -j ACCEPT
# Вместо названия цепочек, можно укзать просто ACCEPT.

Вернемся к Samba и пользователю smbcli (на каждом сервере):
# useradd smbcli
# chown -R smbcli.smbcli /mnt/glustersmb/pub

Предпоследние штрихи:
# chkconfig smbd off
# chkconfig ctdb on
# service ctdb start

Теперь можно наблюдать
# ctdb status
Number of nodes:2
pnn:0 192.168.122.100 OK (THIS NODE)
pnn:1 192.168.122.101 OK
Generation:1112747960
Size:2
hash:0 lmaster:0
hash:1 lmaster:1
Recovery mode:NORMAL (0)
Recovery master:0

Список публичных мигрирующих IP и их приналежность к серверам получаем командой
# ctdb ip
Public IPs on node 0
192.168.122.200 node[1] active[] available[eth0] configured[eth0]
192.168.122.201 node[0] active[eth0] available[eth0] configured[eth0]

Монтируем клиенту по протоколу SMB или NFS командами:
# mount.cifs data:smb /mnt
# mount -o mountproto=tcp,async -t nfs data:smb /mnt

Из личного опыта скажу, что падения сети тестирую до сих пор, результат очень даже сносный. Обрыв соединения практически не заметен. Все обьясняет AndreyKirov
Ликбез
Узел, который принял на себя IP адрес другого, знает о старых TCP соединениях только то, что они были, и не знает «TCP squence number» соединений. Соответственно, не может их продолжить. Также как и клиент, ничего не знает о том, что соединения теперь осуществляются с другим узлом.

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

Новый узел, получив себе ip адрес, посылает клиенту пакет с флагом ACK и заведомо неправильным «squence number» равным нулю. В ответ клиент, в соответствии с правилами работы протокола TCP, отправляет назад пакет ACK Reply с корректным «squence number». Получив корректный «squence number» узел формирует пакет с флагом RST и этим «squence number». Получив его, клиент незамедлительно перезапускает соединение.


Приятного коддинга!
  • +13
  • 18k
  • 3
Share post

Comments 3

    +1
    «SElinux я отключаю...» Есть вообще кто-нибудь, кто пользуется этой хреновиной ))

    Не очень понял, зачем использовать CTDB и какие задачи он решает. Если балансировка и отказоустойчивость, то можно просто обойтись LVS+Pyball (например).

      0
        0
        При написании я хотел ознакомить с одним из возможных вариантов реализации данной схемы. Статья, наверно, будет предпочтительней для системных, а не сетевых администраторов, котрые не каждый день настраивают BGP (Pyball). Что касаеться LVS, я использую продукт keepalive, но не для мультипортовых сервисов.

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

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