UMGUM.COM 

FCoE + Multipath + LVM + KVM ( Подготовка ко вводу в эксплуатацию "standalone" сервера виртуализации Qemu-KVM. )

7 июля 2018  (обновлено 5 января 2019)

OS: "Linux Debian 8/9 (Jessie/Stretch)", "Linux Ubuntu 14/16 (Trusty/Xenial) LTS".

Задача: подготовить к вводу в работу одиночный сервер KVM-виртуализации, воссоздав конфигурацию такового после аппаратного сбоя дисковой подсистемы, для унификации с уже имеющейся пачкой аналогичной функциональности серверов.

Обращаю внимание на то, что по сути это история восстановления сервиса в том виде, как он есть - без попыток сделать лучше. Года четыре назад "уже забыто кто" установил на десяток лезвий в корзине "HP BladeSystem" не связанные между собой инстансы KVM-виртуализации, подключил всё это посредством "Fibre Channel" к внешнему хранилищу "HP 3PAR", нарезал индивидуально для каждого лезвия "луны", навесил на всё это гроздь виртуальных машин - и не время сейчас было менять схему.

Последовательность действий по вводу в строй лезвия с KVM-виртуализацией:

1. Активируем поддержку ядром системы контроллера "Emulex FCoE".
2. Адаптируем "SCSI Multipath" для подключения к "HP 3PAR".
3. Настраиваем совместную работу "SCSI Multipath" и LVM.
4. Устанавливаем и преднастраиваем виртуальный коммутатор "Open vSwitch".
5. Добавляем VLAN-ы в виртуальный коммутатор.
6. Подключаемся к системе виртуализации через LibVirt-клиента.

Для начала установим несколько утилит для удобства работы в консоли:

# apt-get install aptitude sudo acl psmisc host mc htop iotop bmon


Активируем поддержку контроллера "Emulex OneConnect 10Gb FCoE".

Исходно у нас на борту два HDD, объединённых в RAID1, на который установлена операционная система, и интерфейсная карта "Fibre Channel", через два оптоволоконных канала которой подключена внешняя система хранения, на которой располагаются "диски" виртуальных машин:

# lspci

....
04:00.2 Fibre Channel: Emulex Corporation OneConnect 10Gb FCoE Initiator (be3) (rev 01)
04:00.3 Fibre Channel: Emulex Corporation OneConnect 10Gb FCoE Initiator (be3) (rev 01)
....

Чуть больше сведений об оборудовании:

# dmesg | grep -i emu

Emulex LightPulse Fibre Channel SCSI driver 11.2.0.0.
Copyright(c) 2004-2016 Emulex.  All rights reserved.
be2net 0000:04:00.0: Emulex OneConnect(be3): PF FLEX10 port 1
be2net 0000:04:00.1: Emulex OneConnect(be3): PF FLEX10 port 2
scsi host1: Emulex OneConnect OCe11100, FCoE Initiator on PCI bus 04 device 02 irq 87
scsi host2: Emulex OneConnect OCe11100, FCoE Initiator on PCI bus 04 device 03 irq 92

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

Проблемой это не является - нужно просто передать драйверу "Emulex FCoE" (реализованному в виде модуля ядра "lpfc", в нашем случае) выверенные производителями оборудования и предложенные в руководстве по эксплуатации такового параметры сопряжения c "HP 3PAR".

Создаём файл конфигурации модуля ядра "lpfc" (драйвера "Emulex FCoE"):

# vi /etc/modprobe.d/emulex-hba-3par.conf

# Emulex HBA driver tuning for HP 3PAR Storage
options lpfc lpfc_devloss_tmo=14 lpfc_lun_queue_depth=16 lpfc_discovery_threads=32

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

# modinfo lpfc | grep -i lpfc_devloss_tmo

Уже сейчас сканирование посредством "blkid" доступных блочных устройств должно показать те, что расположены на внешней системе хранения.

Внедряем дополненную конфигурацию модуля в образ "Initrd".

В современном Linux-е драйверы устройств и файловых систем обычно загружаются на этапе начальной инициализации ядра операционной системы, собранного вместе с необходимыми модулями в компактном образе "Initrd" (от "Initial RAM Disk"), которому первым делом передаётся управление от BIOS-а несущей платформы. Так вот, каждый раз при изменении параметров ядра или его модулей необходимо всё это пересобирать в комплект "Initrd", чтобы ещё до загрузки системного и пользовательского окружения получить корректно инициализированные устройства.

Подстраховываясь, делаем резервную копию нынешнего "Initrd":

# mkdir /boot/.backup
# cp /boot/initrd.img-$(uname -r) /boot/.backup/initrd.img-$(uname -r).bak

Запускаем процедуру пересборки "Initrd", в процессе которой умная утилита просканирует директории с модулями и их настройками, после чего соберёт в новый образ всё необходимое:

# update-initramfs -v -d -k `uname -r` && update-initramfs -v -c -k `uname -r`

update-initramfs: Deleting /boot/initrd.img-4.9.0-6-amd64
update-initramfs: Generating /boot/initrd.img-4.9.0-6-amd64
....
Adding config /etc/modprobe.d/emulex-hba-3par.conf
....
Building cpio /boot/initrd.img-4.9.0-6-amd64.new initramfs

После перезагрузки проверяем, успешно ли модулем приняты новые значения параметров, из заданных выше:

# cat /sys/module/lpfc/parameters/lpfc_devloss_tmo

Настраиваем "SCSI Multipath" на связку с "HP 3PAR".

Сейчас, когда драйвер "Emulex FCoE" наконец смог доставить с внешнего хранилища в сервер виртуализации блочные SCSI-устройства, мы увидим, что они умножены в числе по количеству каналов контроллера - в действии технология резервирования соединений "Multipath", позволяющая сохранить связь с удалённым устройством при разрыве одного из каналов - доставка данных идёт сразу по всем доступным каналам. Какое из устройств выбирать - непонятно.

Специально для работы с многоканальной поставкой SCSI-устройств в Linux-е имеется служба "multipathd". Инсталлируем её и запускаем:

# aptitude install multipath-tools
# service multipathd start

С максимальной детализацией ознакомится с состоянием сервиса "Multipath" можно следующей командой - там отображается всё необходимое, от загруженного модуля ядра, перечня полученных блочных устройств с их параметрами и привязкой к FC-каналу, до описания финального виртуального блочного устройства "multipath", которое предлагается к использованию (если оно вообще сформировано, разумеется):

# multipath -v3

Однако наверняка первое, что мы увидим при запросе статистики состояния подсистемы приведённой выше командой, в случае использования "HP 3PAR", так это уведомление об отсутствии поддержки внешним хранилищем протокола балансировки ALUA, в результате чего заготовленное виртуальное блочное устройство "multipath" не может быть предложено в эксплуатацию:

sde: alua not supported
sdb: alua not supported
....
sdh: alua not supported
DM message failed [queue_if_no_path]
reject: 360002ac0000000000000000d00005743 undef 3PARdata,VV
size=2.6T features='0' hwhandler='1 alua' wp=undef....

Для полной уверенности уточняем, как именно полученные через FC блочные устройства анонсируют своего производителя:

# cat /sys/block/sdb/device/vendor

3PARdata

В общем, проблема совместимости "3PARdata" и "Multipath" известная, и легко решается корректировкой параметров их связки, приведением конфигурационного файла сервиса к следующему виду:

# vi /etc/multipath.conf

# Глобальные параметры сервиса
defaults {
  polling_interval 10
  user_friendly_names yes
  find_multipaths yes
}

# Явное описание параметров сопряжения с внешними хранилищами
# (перекрывают возможно уже имеющиеся настройки "по умолчанию")
devices {
  device {
    vendor   "3PARdata"
    product  "VV"
    path_grouping_policy  multibus
    path_selector     "round-robin 0"
    path_checker      "tur"
    hardware_handler  "0"
    prio              "const"
    failback          "immediate"
    rr_weight         "uniform"
    rr_min_io         100
    no_path_retry     18
  }
}

blacklist {
  devnode "^sda"
}

multipaths {
  multipath {
    # Уникальный идентификатор виртуального блочного устройства
    # (генерируется автоматически при первой попытке собрать устройство)
    wwid   360002ac0000000000000000d00005743
    alias  mpath0
  }
}

Перезагружаем сервис:

# service multipathd restart

Теперь, когда "Multipath" не пытается использовать для балансировки протокол ALUA, блочные устройства поставляемые через многоканальный FC должны быть приняты в работу и на их основе сформировано виртуальное блочное устройство, обращаться к которому можно по его символическому имени "mpath0":

# multipath -l

mpath0 (360002ac0000000000000000d00005743) dm-2 3PARdata,VV
size=2.6T features='2 queue_if_no_path retain_attached_hw_handler' hwhandler='0' wp=rw
`-+- policy='round-robin 0' prio=0 status=enabled
  |- 1:0:3:0 sde 8:64  active undef running
  |- 2:0:3:0 sdi 8:128 active undef running
  ....
  `- 2:0:2:0 sdh 8:112 active undef running

Напомню, что всё внесённое в конфигурацию службы "Multipath" необходимо будет занести и в образ "Initrd", чтобы уже на первичном этапе загрузки ядра система в оптимальном режиме начала работать со множественно адресуемыми устройствами. Это мы сделаем чуть позже.

Настраиваем совместную работу "Multipath" и LVM.

Конфигурация LVM для применения такового на доставленных посредством "Multipath" блочных устройствах потребует дополнительной настройки. Дело в том, что по умолчанию сканирование на предмет LVM-разметки производится на всех доступных операционной системе блочных устройствах - а у нас некоторые из них множественно продублированы, поставляемые разным каналам "Fibre Channel".

Самый простой способ - определить фильтр, выбирающий для подсистемы LVM только те устройства, которые нам действительно нужны для работы:

# vi /etc/lvm/lvm.conf

....
# Задействуем обратный фильтр, отвергая часть неподходящих "блочных" устройств и разрешая всё остальное
filter = [ "r|/dev/block/.*|", "r|/dev/disk/.*|", "r|/dev/cciss/.*|", "a|/dev/sda.*|", "r|/dev/sd.*|", "a|.*|" ]
....

Очень поможет исключить проблемы с определением конфигурации "блочных" устройств выключение напрочь подсистемы кеширования метаданных LVM-разметки, некстати активированную в "Debian 9" (что-то мейтейнеры в этой версии Linux сломали, отчего спарка "LVMetad" и "systemd-udevd" банально виснет и блокирует работу с LVM-разметкой):

# vi /etc/lvm/lvm.conf

....
use_lvmetad = 0
....

Деактивируем и выключаем сервис кеширования метаданных LVM:

# systemctl disable lvm2-lvmetad
# systemctl stop lvm2-lvmetad

Производим сканирование доступных "блочных" устройств с LVM-разметкой и просматриваем перечень доступных:

# pvscan -v
# vgscan -v
# lvscan -v
# lsblk -f
# pvs

PV                  VG                   Fmt  Attr PSize  PFree  
/dev/mapper/mpath0  r2b10-storage-vg0 lvm2 a--    2.64t  1.04t
/dev/sda1           r2b10-vg0         lvm2 a--  838.33g     0

После того, как мы убедимся в корректной работе фильтра "блочных" устройств для LVM, необходимо записать эту конфигурацию в "Initrd", чтобы загрузчик так же правильно работал с доступными ему "блочными" устройствами:

# mkdir /boot/.backup
# cp /boot/initrd.img-$(uname -r) /boot/.backup/initrd.img-$(uname -r).bak
# update-initramfs -v -d -k `uname -r` && update-initramfs -v -c -k `uname -r`

Важно помнить, что после каждого изменения конфигурации "Multipath" и LVM нужно заново генерировать образ "Initrd", чтобы таковые применялись уже на этапе загрузки ядра системы.

Запускаем виртуальный коммутатор "Open vSwitch".

Устанавливаем пакеты программного обеспечения виртуального коммутатора, утилиты агрегирования и настройки параметров интерфейсов:

# aptitude install openvswitch-switch ifenslave ethtool

Заранее подготавливаем желаемую схему включения сервера виртуализации в сетевую инфраструктуру, агрегированным сетевым интерфейсом и "мостом" от него для виртуального коммутатора "Open VSwitch" (имеем в виду, что на период переключения в эту схему сетевые подключения пропадут):

# vi /etc/network/interfaces

....
# The primary network interface
allow-hotplug eno1
iface eno1 inet manual
  address 0.0.0.0

# The secondary network interface
allow-hotplug eno2
iface eno2 inet manual
  address 0.0.0.0

# The aggregated network interface
auto bond0
iface bond0 inet manual
  address 0.0.0.0
  bond-mode balance-tlb
  bond-miimon 100
  bond-downdelay 200
  bond-updelay 200
  bond-slaves eno1 eno2

# The bridge network interface for Open-vSwitch
#auto br0
iface br0 inet static
  address 10.20.30.123
  netmask 255.255.255.0
  gateway 10.20.30.1
  dns-nameservers 10.20.4.4 172.16.8.8
  dns-search example.net
....

Обращаю внимание на то, что в системном конфигурационном файле описания сетевых интерфейсов выше я не запускаю автоматически "мостовой" интерфейс "br0", явно оставляя опцию "#auto br0" неактивной - это будет сделано позже написанным нами скриптом, вместе с объяснением причины.

Вручную переводим сетевую конфигурацию в активное состояние:

# ifconfig eno1 0.0.0.0 down
# ifconfig eno2 0.0.0.0 down
# ifup bond0
# ifup br0

Явно добавляем к виртуальному коммутатору "мост" и агрегированный порт к таковому:

# ovs-vsctl add-br br0
# ovs-vsctl add-port br0 bond0

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

# ovs-vsctl show

Bridge "br0"
  Port "br0"
    Interface "br0"
    type: internal
  Port "bond0"
    Interface "bond0"
ovs_version: "2.6.2"

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

# ovs-vsctl del-port br0 vnet0

Ознакомится с действующей конфигураций "Open-vSwitch" можно следующим образом:

# ovsdb-client dump | less S

Чиним связку "Systemd" и "Open-vSwitch" в "Debian Stretch".

Как частенько случается с "этими вашими линуксами", в "Debian Stretch" слегка поломали связку "Systemd" и "Open-vSwitch", отчего виртуальный "мостовой" интерфейс попросту не создаётся на этапе загрузки системы. После загрузки всех компонентов сетевой подсистемы интерфейс "br0" активируется без проблем - но не в процессе. Полагаю, что дело в очерёдности инициирования компонентов, но разбираться в причине было некогда - оказалось быстрее добавить службу, загружаемую после инициирования сети и добавляющую все необходимые связи.

# mkdir -p /usr/local/etc/openvswitch && cd /usr/local/etc/openvswitch
# vi ./ovs-networking.sh && chmod +x ./ovs-networking.sh

#!/bin/bash

# Инициируем сетевые интерфейсы
/sbin/ifup bond0
/sbin/ifup br0

# Добавляем сетевые интерфейсы в OpenVSwitch
ovs-vsctl --may-exist add-br br0
ovs-vsctl --may-exist add-port br0 bond0

# Отключаем поддержку ненужного (как правило) STP/rSTP
ovs-vsctl set bridge br0 stp_enable=false
ovs-vsctl set bridge br0 rstp_enable=false

exit ${?}

Создаём файл описания "юнита" запуска скрипта конфигурирования посредством Systemd:

# vi /etc/systemd/system/ovs-networking.service

[Unit]
Description=OpenVSwitsh custom networking
Requires=network-online.target networking.service openvswitch-switch.service
After=network-online.target networking.service openvswitch-switch.service

[Service]
User=root
Type=notify
RemainAfterExit=yes

ExecStart=/bin/bash /usr/local/etc/openvswitch/ovs-networking.sh

[Install]
WantedBy=multi-user.target

# systemctl daemon-reload
# systemctl enable ovs-networking.service

Рекомендую сразу проконтролировать, верно ли настроены зависимости для запуска нашего скрипта:

# systemctl list-dependencies ovs-networking.service

ovs-networking.service
  ├─networking.service
  ├─openvswitch-switch.service
  ├─network-online.target
....

# systemctl start ovs-networking.service
# journalctl -u ovs-networking.service

Добавляем VLAN-ы в "Open-vSwitch".

С интерфейсами обслуживающими тегированный трафик (в рамках заданного VLAN-а) всё просто - это одна из основополагающих сущностей в "Open-vSwitch", так что инструментарий отлажен.

Например, добавляем в виртуальный коммутатор сетевой интерфейс "vlan450" (это произвольное имя), пропускающий только пакеты с 450-м тегом, в имеющийся мост "br0":

# ovs-vsctl add-br vlan450 br0 450

Установка "Qemu-KVM" и "LibVirt".

Публикация не про настройку системы виртуализации, так что здесь мы просто установим минимально необходимый набор пакетов, достаточный для проверки удалённого подключения:

# aptitude install qemu-kvm libvirt-daemon libvirt-daemon-system libvirt-clients

Разумеется, чтобы управлять виртуальными машинами последством "LibVirt", нужно иметь запущенным соответствующий сервис:

# systemctl status libvirtd

В качестве примера возможностей - так инструментами "LibVirt" можно узнать состояние имеющихся виртуальных машин:

# virsh list --all

Очистка от лишних подсистем "LibVirt".

Пакет приложений "LibVirt", используемый для управления средой виртуализации "Qemu-KVM", по умолчанию создаёт свои сетевые подсистемы, которые при использовании "Open-vSwitch" не нужны:

# virsh net-list --all

Name    State  Autostart Persistent
------------------------------------
default active no        yes

Удаляем лишнее:

# virsh net-destroy default
# virsh net-undefine default
# service libvirtd restart

Определяем круг пользователей "LibVirt".

По умолчанию право на подключение к сервису "LibVirt" имеет член соответствующей группы:

Для "Linux Ubuntu":

# usermod -a -G libvirtd libvirt-user

Для "Linux Debian":

# usermod -a -G libvirt libvirt-user

Подключение к "LibVirt".

На рабочей станции администратора устанавливаем простенький GUI-интерфейс управления "LibVirt":

# aptitude install virt-manager

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


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )