dm-multipath на CentOS 7: два пути к iSCSI-хранилищу и автоматический failover
Настраиваем dm-multipath на CentOS 7 для подключения Linux-хостов к iSCSI-хранилищу через два независимых пути и проверяем автоматическое переключение при отказе одного из них.
Рост SAN-инфраструктуры на базе iSCSI с multipath для Linux-хостов в корпоративных средах
Клиент расширял SAN-инфраструктуру. Раньше к iSCSI-хранилищу подключалось несколько Windows-хостов - там multipath через MPIO настраивается относительно цивилизованно, есть GUI, кнопки. Теперь добавились Linux-серверы под CentOS 7, и задача та же: два независимых пути к хранилищу через разные коммутаторы, автоматический failover при потере одного из них. Это задача на сопровождении, поэтому конфигурация осталась у нас, и мы можем её описать.
Зачем два пути
iSCSI - это блочное хранилище поверх обычной IP-сети. В отличие от FC-SAN с выделенными HBA и специализированной сетью, тут используются обычные сетевые карты и свитчи. Плюс - дёшево и привычно. Минус - единственная точка отказа там, где у FC её нет по определению.
Два пути через разные коммутаторы решают именно это: умер свитч, оборвался кабель, перезагружается одна из сетевых карт - трафик к хранилищу переходит на второй путь. Если storage-сеть используется для критичных данных, без этого запускать в продакшн неловко.
Архитектура
На каждом хосте - две сетевые карты, каждая в отдельном сторедж-VLAN через свой свитч. Хранилище - две независимых target-сессии, по одной на каждый интерфейс. Linux видит это как два блочных устройства, например /dev/sdb и /dev/sdc, указывающих на один и тот же LUN. dm-multipath агрегирует их в одно виртуальное устройство /dev/dm-0 (или /dev/mapper/mpatha), с которым работает ОС и прикладной слой.
Установка и базовая настройка
На CentOS 7 пакет уже в базовом репозитории:
yum install -y device-mapper-multipath
Генерируем дефолтный конфиг - он пишет /etc/multipath.conf с закомментированными секциями:
mpathconf --enable --with_multipathd y
Дефолтный конфиг умеет работать с большинством хранилищ «из коробки», но его надо уточнить. Самое важное - vendor/product строки от хранилища и политика переключения путей. Смотрим что видит система до настройки:
multipath -ll
Если хранилище не попало в дефолтные hardware tables, устройства будут без имени или вообще не будут агрегированы. Добавляем секцию devices в /etc/multipath.conf:
devices {
device {
vendor "VENDOR_NAME"
product "PRODUCT_MODEL"
path_grouping_policy multibus
path_checker tur
failback immediate
no_path_retry queue
}
}
Значения vendor и product берём из lsscsi или udevadm info. Политика multibus означает что все работающие пути в одной группе и нагрузка балансируется между ними. failback immediate - при восстановлении пути немедленно возвращаться к нему.
Настройка iSCSI-инициатора для двух путей
Сначала убеждаемся что iscsid настроен на оба интерфейса. В /etc/iscsi/iscsid.conf ключевой параметр - node.session.timeo.replacement_timeout, его имеет смысл уменьшить с дефолтных 120 секунд, иначе при потере пути приложение будет видеть зависший ввод-вывод больше двух минут:
node.session.timeo.replacement_timeout = 20
Обнаружение target-а выполняется с каждого интерфейса отдельно:
iscsiadm -m discovery -t st -p 192.168.10.1 -I eth1
iscsiadm -m discovery -t st -p 192.168.20.1 -I eth2
После логина (iscsiadm -m node --loginall=automatic) система должна показать два устройства на один LUN. multipath -ll покажет их агрегированными.
Проверка failover
Это самая важная часть - проверить, что переключение реально работает, а не только выглядит правильно в конфиге.
Запускаем непрерывную запись на multipath-устройство:
dd if=/dev/urandom of=/dev/mapper/mpatha bs=1M &
Смотрим текущий активный путь:
multipath -ll
Имитируем отказ - просто физически гасим один интерфейс на хосте или блокируем порт на свитче:
ip link set eth1 down
Через несколько секунд multipath -ll должен показать один путь как failed и трафик продолжает идти через второй. Процесс dd не должен прерваться - максимум небольшая пауза, пока multipathd детектирует потерю пути. С replacement_timeout = 20 и path_checker = tur задержка у нас составила порядка 5-8 секунд до переключения.
Возвращаем интерфейс:
ip link set eth1 up
При failback immediate multipathd должен переключиться обратно на оба пути автоматически, без вмешательства.
Несколько вещей, которые нас удивили
path_checker = tur. Дефолтный checker для большинства хранилищ - directio, он просто проверяет возможность чтения с устройства. tur (Test Unit Ready) - SCSI-команда, которую понимают все нормальные хранилища. Для некоторых вендоров directio давал ложные срабатывания; после переключения на tur поведение стало стабильнее.
no_path_retry queue. Без этого параметра, когда оба пути теряются (совсем редкая ситуация, но бывает при обслуживании двух свитчей), ввод-вывод сразу начинает возвращать ошибки приложению. С queue - I/O ставится в очередь и ждёт восстановления хотя бы одного пути. Для баз данных это принципиальная разница: ошибка при записи в большинстве случаев хуже, чем зависание.
/etc/scsi_id.config. На некоторых хранилищах SCSI идентификаторы по умолчанию не уникальны или возвращаются некорректно. В таком случае multipath не может однозначно определить какие устройства соответствуют одному LUN. Симптом - multipath -ll показывает несколько отдельных групп вместо одной агрегированной. Лечится через настройку uid_attribute или getuid_callout в секции defaults.
Текущее состояние
Два хоста на CentOS 7 работают с multipath уже несколько недель. За это время был один реальный тест - обслуживание одного из свитчей, порт перешёл в down примерно на 20 минут. Переключение произошло автоматически, приложение (PostgreSQL на этом хосте) не почувствовало: в логах нет ни ошибок, ни таймаутов. Когда свитч вернули, multipathd восстановил оба пути самостоятельно.
Масштабировать схему на оставшиеся хосты планируем постепенно - там разные версии ОС, нужно дополнительное тестирование на каждой.
- Zabbix на Docker-хостах: почему мы ушли на Prometheus и Grafana · 9 февраля 2016
- Filebeat вместо Logstash-агентов: 150+ серверов, 12 МБ вместо 256 МБ на хост · 29 января 2016