Надежное хранилище с DRBD9 и Proxmox (Часть 2: iSCSI+LVM)

image

В предыдущей статье я рассмотрел возможность создания отказоустойчивого NFS-сервера с помощью DRBD и Proxmox. Получилось довольно неплохо, но не будем останавливаться на достигнутом и теперь постараемся «выжать все соки» из нашей хранилки.

В этой статье я расскажу как подобным образом создать отказоустойчивый iSCSI-таргет, который при помощи LVM мы будем нарезать на маленькие кусочки и использовать под виртуальные машины.

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

Пара слов о DRBD

DRBD достаточно простое и зрелое решение, код восьмой версии принят в состав ядра Linux. По сути представляет ссобой сетевое зеркало RAID1. В девятой версии появилась поддержка кворума и репликации с больше чем двумя нодами.

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

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

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

Пара слов об iSCSI

iSCSI — это протокол доставки блочного устройства по сети.

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

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

Пара слов об LVM

Стоит упомянуть, что у LINBIT существует собственное решение для Proxmox, оно должно работать из коробки и позволит добиться похожего результата, но в данной статье я не хотел бы заострять внимание только на Proxmox а описать некоторое более унивирсальное решение которое подойдет как для Proxmox так и для чего-нибудь еще, в данном примере proxmox используется только как средство оркестрации контейнеров, по сути вы можете заменить его на другое решение, например запускать контейнеры с таргетом в Kubernetes.

Что касается конкретно Proxmox, то он отлично работает с shared LUN и LVM, используя только собственные стандратные драйверы.

К плюсам LVM можно отнести то, что его использование не является чем-то революционно новым и недостаточно обкатанным, а наоборот, оно показывает сухую стабильность, что обычно и требуется от хранилища. Стоит упомянуть что LVM довольно активно используются и в других средах, например в OpenNebula или в Kubernetes и достаточно неплохо там поддерживается.

Таким образом вы получите универсальное хранилище которое можно использовать в разных системах (не только в proxmox), используя только готовые драйверы, без особой необходимости дорабатывать его напильником.

К сожалению, при выборе решения под хранилище всегда приходится идти на какие-нибудь компромиссы. Так и тут, данное решение не даст вам той-же гибкости как например Ceph.
Размер виртуального диска ограничен размером LVM-группы, а область размеченная под конкретный виртуальный диск обязательно будет преаллоцирована — это сильно улучшает скорость доступа к данным, но не дает возможности к Thin-Provisioning (когда виртуальный диск занимает меньше места чем есть на самом деле). Стоит упомянуть что производительность LVM достаточно сильно проседает при использовании снапшотов, в связи с чем возможность свободного их использования, часто исключается.

Да, LVM поддерживает Thin-Provision пулы, которые лишены данного недостатка, но к сожалению их использование возможно только в контексте одной ноды и нет возможности расшарить один Thin-Provision пул на несколько нод в кластере.

Но несмотря на эти недостатки, из-за своей простоты LVM по прежнему не дает возможности конкурентам обойти его и полностью вытеснить с поля боя.

При достаточно небольших накладных расходах LVM по прежнему представляет очень быстрое, стабильное и достаточно гибкое решение.

Общая схема

  • У нас есть три ноды
  • На каждой ноде распределенное drbd-устройство.
  • Поверх drbd-устройства запущен LXC-контейнер с iSCSI-таргетом.
  • Таргет подключен ко всем трем нодам.
  • На подключенном таргете создана LVM-группа.
  • При необходимости LXC-конейнер может переехать на другую ноду, вместе с iSCSI-таргетом

Настройка

С идеей разобрались теперь перейдем к реализации.

По умолчанию в комплекте с ядром Linux поставляется модуль восьмой версии drbd, к сожалению он нам не подходит и нам необходимо установить модуль девятой версии.

Подключим репозиторий LINBIT и установим все необходимое:

wget -O- https://packages.linbit.com/package-signing-pubkey.asc | apt-key add -  echo "deb http://packages.linbit.com/proxmox/ proxmox-5 drbd-9.0" \   > /etc/apt/sources.list.d/linbit.list  apt-get update && apt-get -y install pve-headers drbd-dkms drbd-utils drbdtop

  • pve-headers — заголовки ядра необходимые для сборки модуля
  • drbd-dkms — модуль ядра в формате DKMS
  • drbd-utils — основные утилиты для управления DRBD
  • drbdtop — интерактивный инструмент, как top только для DRBD

После установки модуля проверим, все ли с ним в порядке:

# modprobe drbd # cat /proc/drbd  version: 9.0.14-1 (api:2/proto:86-113)

Если вы увидите в выводе команды восьмую версию значит что-то пошло не так и загружен in-tree модуль ядра. Проверьте dkms status что-бы разобраться в чем причина.

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

В качестве такого раздела может выступать любое блочное устройство, это может быть lvm, zvol, раздел диска или весь диск целиком. В этой статье я буду использовать отдельный nvme диск с разделом под drbd: /dev/nvme1n1p1

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

Найти такой симлинк для /dev/nvme1n1p1 можно таким образом:

# find /dev/disk/ -lname '*/nvme1n1p1' /dev/disk/by-partuuid/847b9713-8c00-48a1-8dff-f84c328b9da2 /dev/disk/by-path/pci-0000:0e:00.0-nvme-1-part1 /dev/disk/by-id/nvme-eui.0000000001000000e4d25c33da9f4d01-part1 /dev/disk/by-id/nvme-INTEL_SSDPEKKA010T7_BTPY703505FB1P0H-part1

Опишем наш ресурс на всех трех нодах:

# cat /etc/drbd.d/tgt1.res resource tgt1 {   meta-disk internal;   device    /dev/drbd100;   protocol  C;   net {      after-sb-0pri discard-zero-changes;     after-sb-1pri discard-secondary;     after-sb-2pri disconnect;   }   on pve1 {     address   192.168.2.11:7000;     disk      /dev/disk/by-partuuid/95e7eabb-436e-4585-94ea-961ceac936f7;     node-id   0;   }   on pve2 {     address   192.168.2.12:7000;     disk      /dev/disk/by-partuuid/aa7490c0-fe1a-4b1f-ba3f-0ddee07dfee3;     node-id   1;   }   on pve3 {     address   192.168.2.13:7000;     disk      /dev/disk/by-partuuid/847b9713-8c00-48a1-8dff-f84c328b9da2;     node-id   2;   }   connection-mesh {     hosts pve1 pve2 pve3;   } }

Желательно для синхронизации drbd использовать отдельную сеть.

Теперь создадим метаданные для drbd и запустим его:

# drbdadm create-md tgt1 initializing activity log initializing bitmap (320 KB) to all zero Writing meta data... New drbd meta data block successfully created. success # drbdadm up tgt1

Повторим эти действия на всех трех нодах и проверим состояние:

# drbdadm status tgt1 role:Secondary   disk:Inconsistent   pve2 role:Secondary     peer-disk:Inconsistent   pve3 role:Secondary     peer-disk:Inconsistent

Сейчас наш диск Inconsistent на всех трех нодах, это потому, что drbd не знает какой диск должен быть взят в качестве оригинала. Мы должны пометить один из них как Primary, что бы его состояние синхронизировалось на остальные ноды:

drbdadm primary --force tgt1 drbdadm secondary tgt1

Сразу после этого начнется синхронизация:

# drbdadm status tgt1 role:Secondary   disk:UpToDate   pve2 role:Secondary     replication:SyncSource peer-disk:Inconsistent done:26.66   pve3 role:Secondary     replication:SyncSource peer-disk:Inconsistent done:14.20 

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

Стоит не забыть активировать автозапуск drbd-сервиса на нодах:

systemctl enable drbd.service

Настройка LXC-контейнера

Опустим часть настройки кластера Proxmox из трех нод, эта часть хорошо описана в официальной wiki

Как я говорил раньше наш iSCSI-таргет будет работать в LXC-контейнере. Сам контейнер мы будем держать на устройстве /dev/drbd100, которое мы только что создали.

Сначала нам нужно создать файловую систему на нем:

mkfs -t ext4 -O mmp -E mmp_update_interval=5 /dev/drbd100

Proxmox по умолчанию включает multimount protection на уровне файловой системы, в принципе мы можем обойтись и без нее, т.к. DRBD по умолчанию имеет собственную защиту, он просто запретит второй Primary для устройства, но осторожность нам не повредит.

Теперь скачаем шаблон Ubuntu:

# wget http://download.proxmox.com/images/system/ubuntu-16.04-standard_16.04-1_amd64.tar.gz -P /var/lib/vz/template/cache/

И создадим из него наш контейнер:

pct create 101 local:vztmpl/ubuntu-16.04-standard_16.04-1_amd64.tar.gz \   --hostname=tgt1 \   --net0=name=eth0,bridge=vmbr0,gw=192.168.1.1,ip=192.168.1.11/24 \   --rootfs=volume=/dev/drbd100,shared=1

В данной команде мы указываем что корневая система нашего контейнера будет находиться на устройстве /dev/drbd100 и добавим параметр shared=1 что бы разрешить миграцию контейнера между нодами.

Если что-то пошло не так, вы всегда можете поправить это через интерфейс Proxmox или в конфиге контейнера /etc/pve/lxc/101.conf

Proxmox распакует шаблон и подготовит корневую систему контейнера для нас. После этого мы можем запустить наш контейнер:

pct start 101

Настройка iSCSI-таргета.

Из всего множества таргетов я выбрал istgt, так как он обладает наибольшей производительностью и работает в пространстве пользователя.

Теперь давайте залогинимся в наш контейнер:

pct exec 101 bash

Установим обновления и istgt:

apt-get update  apt-get -y upgrade apt-get -y install istgt

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

mkdir -p /data fallocate -l 740G /data/target1.img

Теперь нам нужно написать конфиг для istgt /etc/istgt/istgt.conf:

[Global]   Comment "Global section"   NodeBase "iqn.2018-07.org.example.tgt1"   PidFile /var/run/istgt.pid   AuthFile /etc/istgt/auth.conf   MediaDirectory /var/istgt   LogFacility "local7"   Timeout 30   NopInInterval 20   DiscoveryAuthMethod Auto   MaxSessions 16   MaxConnections 4   MaxR2T 32   MaxOutstandingR2T 16   DefaultTime2Wait 2   DefaultTime2Retain 60   FirstBurstLength 262144   MaxBurstLength 1048576   MaxRecvDataSegmentLength 262144   InitialR2T Yes   ImmediateData Yes   DataPDUInOrder Yes   DataSequenceInOrder Yes   ErrorRecoveryLevel 0 [UnitControl]   Comment "Internal Logical Unit Controller"   AuthMethod CHAP Mutual   AuthGroup AuthGroup10000   Portal UC1 127.0.0.1:3261   Netmask 127.0.0.1 [PortalGroup1]   Comment "SINGLE PORT TEST"   Portal DA1 192.168.1.11:3260 [InitiatorGroup1]   Comment "Initiator Group1"   InitiatorName "ALL"   Netmask 192.168.1.0/24 [LogicalUnit1]   Comment "Hard Disk Sample"   TargetName disk1   TargetAlias "Data Disk1"   Mapping PortalGroup1 InitiatorGroup1   AuthMethod Auto   AuthGroup AuthGroup1   UseDigest Auto   UnitType Disk   LUN0 Storage /data/target1.img Auto

Перезапустим istgt:

systemctl restart istgt

На этом настройка таргета закончена

Настройка HA

Теперь мы можем перейти к кофигурации HA-manager. Создадим отдельную HA-группу для нашего устройства:

ha-manager groupadd tgt1 --nodes pve1,pve2,pve3 --nofailback=1 --restricted=1

Наш ресурс будет работать только на нодах указанных для этой группы. Добавим наш контейнер в эту группу:

ha-manager add ct:101 --group=tgt1 --max_relocate=3 --max_restart=3

Рекомендации и тюнинг

DRBD

Как я отметил выше, всегда желательно использовать отдельную сеть под репликацию. Крайне желательно использовать 10-гигабитные сетевые адаптеры, в противном случае у вас все упрется в скорость портов.
Если репликация вам кажется достаточно медленной попробуйте потюнить некоторые параметры для DRBD. Вот конфиг, который на мой взгляж является оптимальными для моей 10G-сети:

# cat /etc/drbd.d/global_common.conf global {  usage-count yes;  udev-always-use-vnr;  } common {  handlers {  }  startup {  }  options {  }  disk {   c-fill-target 10M;   c-max-rate   720M;   c-plan-ahead   10;   c-min-rate    20M;  }  net {   max-buffers     36k;   sndbuf-size   1024k;   rcvbuf-size   2048k;  } }

Подробнее про каждый параметр вы можете получить информацию из официальной документации DRBD

Open-iSCSI

Так как мы не используем multipathing, в нашем случае рекомендуется отключить переодические проверки соединения на клиентах, а так же увеличить таймауты ожидания для восстановления сессии в /etc/iscsi/iscsid.conf.

node.conn[0].timeo.noop_out_interval = 0 node.conn[0].timeo.noop_out_timeout = 0 node.session.timeo.replacement_timeout = 86400

Использование

Proxmox

Полученный iSCSI-таргет можно сразу-же подключить в Proxmox, не забыв снять галочку с Use LUN Directly.

Сразу после этого станет возможным создание LVM поверх него, не забудьте поставить галочку напротив shared:

Другие среды

Если вы планируете использовать это решение в другой среде возможно вам потребуется установить кластерное расширение для LVM на данный момент из существует две реализации. CLVM и lvmlockd.

Настройка CLVM не совесм тривиальна и требует работающего кластер менеджера.
Куда как второй метод lvmlockd — еще не до конца протестирован и только-только начинает появляться в стабильных репозиториях.

Рекомендую к прочтению отличную статью о блокировах в LVM

При использовании LVM с Proxmox кластерное дополнение не требуется, так как управление томами обеспечивается самим proxmox, который обновляет и следит за метаданными LVM самостоятельно. Тоже касается и OpenNebula, на что явно указывает официальная документация.

FavoriteLoadingДобавить в избранное
Posted in Без рубрики

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *