Abstract: как работает open-iscsi (ISCSI initiator в linux), как его настраивать и чуть-чуть про сам протокол ISCSI.
Лирика: В интернете есть множество статей довольно хорошо объясняющих,
как настроить ISCSI target, однако, почему-то, практически нет статей
про работу с инициатором. Не смотря на то, что target технически
сложнее, административной возни с initiator больше — тут больше
запутанных концепций и не очень очевидные принципы работы.

ISCSI
Перед тем, как рассказать про ISCSI — несколько слов о разных типах удалённого доступа к информации в современных сетях.
NAS vs SAN
Существует два метода доступа к данным, находящимся
на другом компьютере: файловый (когда у удалённого компьютера
запрашивают файл, а какими файловыми системами это сделано — никого не
волнует), характерные представители NFS, CIFS (SMB); и блочный — когда у
удалённого компьютера запрашивают блоки с дискового носителя
(аналогично тому, как их читают с жёсткого диска). В этом случае
запрашивающая сторона сама себе делает на блочном устройстве файловую
систему, а сервер, отдающий блочное устройство, знать не знает про
файловые системы на нём. Первый метод называют NAS (network attached
storage), а второй — SAN (storage area network). Названия вообще
указывают на другие признаки (SAN подразумевает выделенную сеть до
хранилищ), но так сложилось, что NAS — это файлы, а SAN — это блочные
устройства по сети. И хотя все (?) понимают, что это неправильные
названия, чем дальше, тем больше они закрепляются.
scsi over tcp
Одним из протоколов доступа к блочным устройствам
является iscsi. Буква 'i' в названии относится не к продукции эппл, а к
Internet
Explorer. По своей сути это 'scsi over tcp'. Сам
протокол SCSI (без буквы 'i') — это весьма сложная конструкция,
поскольку он может работать через разные физические среды (например,
UWSCSI — параллельная шина, SAS — последовательная — но протокол у них
один и тот же). Этот протокол позволяет делать куда больше, чем просто
«подтыкать диски к компьютеру» (как это придумано в SATA), например, он
поддерживает имена устройств, наличие нескольких линков между блочным
устройством и потребителем, поддержку коммутации (ага, SAS-коммутатор,
такие даже есть в природе), подключение нескольких потребителей к одному
блочному устройству и т.д. Другими словами, этот протокол просто
просился в качестве основы для сетевого блочного устройства.
Терминология
В мире SCSI приняты следующие термины:
target — тот, кто предоставляет блочное устройство. Ближайший аналог из обычного компьютерного мира — сервер.
initiator — клиент, тот, кто пользуется блочным устройством. Аналог клиента.
WWID — уникальный идентификатор устройства, его имя. Аналог DNS-имени.
LUN — номер «кусочка» диска, к которому идёт обращение. Ближайший аналог — раздел на жёстком диске.
ISCSI приносит следующие изменения: WWID исчезает, на его место приходит
понятие IQN (iSCSI Qualified Name) — то есть чистой воды имя, сходное
до степени смешения с DNS (с небольшими отличиями). Вот пример IQN:
iqn.2011-09.test:name.
IETD и open-iscsi (сервер и клиент под линукс) приносят ещё одну очень
важную концепцию, о которой чаще всего не пишут в руководствах по iscsi —
portal. Portal — это, если грубо говорить, несколько target'ов, которые
анонсируются одним сервером. Аналогии с www нет, но если бы веб-сервер
можно было попросить перечислить все свои virtualhosts, то это было бы
оно. portal указывает список target'ов и доступные IP, по которым можно
обращаться (да-да, iscsi поддерживает несколько маршрутов от initiator к
target).
target
Статья не про target, так что даю очень краткое описание того, что
делает target. Он берёт блочное устройство, пришлёпывает к нему имя и
LUN и публикет его у себя на портале, после чего позволяет всем желающим
(авторизация по вкусу) обращаться к нему.
Вот пример простенького файла конфигурации, думаю, из него будет понятно что делает target (файл конфигурации на примере IET):
Target iqn.2011-09.example:data
IncomingUser username Pa$$w0rd
Lun 0 Path=/dev/md1
(сложный от простого отличается только опциями экспорта). Таким образом,
если у нас есть target, то мы хотим его подключить. И тут начинается
сложное, потому что у initiator'а своя логика, он совсем не похож на
тривиальное mount для nfs.
Initiator
В качестве инициатора используется open-iscsi. Итак, самое важное — у него есть
режимы работы и
состояние. Если мы дадим команду не в том режиме или не учтём состояние, результат будет крайне обескураживающий.
Итак, режимы работы:
- Поиск target'ов (discovery)
- Подключение к target'у
- Работа с подключенным target'ом
Из этого списка вполне понятен жизненный цикл — сначала найти, потом
подключиться, потом отключиться, потом снова подключиться. Open-iscsi
держит сессию открытой, даже если блочное устройство не используется.
Более того, он держит сессию открытой (до определённых пределов,
конечно), даже если сервер ушёл в перезагрузку. Сессия iscsi — это не то
же самое, что открытое TCP-соединение, iscsi может прозрачно
переподключаться к target'у. Отключение/подключение — операции, которыми
управляют «снаружи» (либо из другого ПО, либо руками).
Немного о состоянии. После discovery open-iscsi
запоминает все
найденные target'ы (они хранятся в /etc/iscsi/), другими словами,
discovery — операция постоянная, совсем НЕ соответствующая, например,
dns resolving). Найденные target можно удалить руками (кстати, частая
ошибка — когда у open-iscsi, в результате экспериментов и настройки,
пачка найденных target'ов, при попытке логина в которые выползает
множество ошибок из-за того, что половина target'ов — старые строчки
конфига, которые уже давно не существуют на сервере, но помнятся
open-iscsi). Более того, open-iscsi позволяет менять настройки
запомненного target'а — и эта «память» влияет на дальнейшую работу с
target'ами даже после перезагрузки/перезапуска демона.
Блочное устройство
Второй вопрос, который многих мучает по-началу — куда оно попадает после
подключения? open-iscsi создаёт хоть и сетевое, но БЛОЧНОЕ устройство
класса SCSI (не зря же оно «я сказя»), то есть получает букву в
семействе /dev/sd, например, /dev/sdc. Используется первая свободная
буква, т.к. для всей остальной системы это блочное устройство — типичный
жёсткий диск, ничем не отличающийся от подключенного через usb-sata или
просто напрямую к sata.
Это часто вызывает панику «как я могу узнать имя блочного устройства?».
Оно выводится в подробном выводе iscsiadm (# iscsiadm -m session -P 3).
Авторизация
В отличие от SAS/UWSCSI, ISCSI доступно для подключения кому попало. Для
защиты от таких, есть логин и пароль (chap), и их передача iscsiadm'у —
ещё одна головная боль для начинающих пользователей. Она может
осуществляться двумя путями — изменением свойств уже найденного ранее
target'а и прописываем логина/пароля в файле конфигурации open-iscsi.
Причина подобных сложностей — в том, что пароль и процесс логина — это
атрибуты не пользователя, а системы. ISCSI — это дешёвая версия
FC-инфраструктуры, и понятие «пользователь» в контексте человека за
клавиатурой тут неприменимо. Если у вас sql-база лежит на блочном
устройстве iscsi, то разумеется, вам будет хотеться, чтобы sql-сервер
запускался сам, а не после минутки персонального внимания оператора.
Файл конфигурации
Это очень важный файл, потому что помимо логина/пароля он описывает ещё
поведение open-iscsi при нахождении ошибок. Он может отдавать ошибку
«назад» не сразу, а с некоторой паузой (например, минут в пять, чего
достаточно для перезагрузки сервера с данными). Так же там
контролируется процесс логина (сколько раз пробовать, сколько ждать
между попытками) и всякий тонкий тюнинг самого процесса работы. Заметим,
эти параметры довольно важны для работы и вам нужно обязательно
понимать, как поведёт ваш iscsi если вынуть сетевой шнурок на 10-20с,
например.
Краткий справочник
Я не очень люблю цитировать легконаходимые маны и строчки, так что приведу типовой сценарий употребения iscsi:
сначала мы находим нужные нам target, для этого мы должны знать IP/dns-имя инициатора:
iscsiadm -m discovery -t st -p 192.168.0.1
-t st — это команда send targets.
iscsiadm -m node
(список найденного для логина)
iscsiadm -m node -l -T iqn.2011-09.example:data
(залогиниться, то есть подключиться и создать блочное устройство).
iscsiadm -m session
(вывести список того, к чему подключились)
iscsiadm -m session -P3
(вывести его же, но подробнее — в
самом конце вывода будет указание на то, какое блочное устройство какому
target'у принадлежит).
iscsiadm - m session -u -T iqn.2011-09.example:data
(вылогиниться из конкретной )
iscsiadm -m node -l
(залогиниться во все обнаруженные target'ы)
iscsiadm -m node -u
(вылогиниться из всех target'ов)
iscsiadm -m node --op delete -T iqn.2011-09.example:data
(удалить target из обнаруженных).
mulitpath
Ещё один вопрос, важный в серьёзных решениях — поддержка нескольких
маршрутов к источнику. Прелесть iscsi — в использовании обычного ip,
который может быть обычным образом обработан, как и любой другой трафик
(хотя на практике обычно его не маршрутизируют, а только коммутируют —
слишком уж великая там нагрузка). Так вот, iscsi поддерживает multipath в
режиме «не сопротивляться». Сам по себе open-iscsi не умеет
подключаться к нескольким IP одного target'а. Если его подключить к
нескольким IP одного target'а, то это приведёт к появлению нескольких
блочных устройств.
Однако, решение есть — это multipathd, который находит диски с
одинаковым идентифиатором и обрабатывает их как положено в multipath, с
настраиваемыми политиками. Эта статья не про multipath, так что подробно
объяснять таинство процесса я не буду, однако, вот некоторые важные
моменты:
- При использовании multipath следует ставить маленькие таймауты —
переключение между сбойными путями должно происходить достаточно быстро
- В условиях более-менее быстрого канала (10G и выше, во многих
случаях гигабит) следует избегать параллелизма нагрузки, так как
теряется возможность использовать bio coalesing, что в некоторых типах
нагрузки может неприятно ударить по target'у.
Комментарии (58)