HA - как много в этом слове: Автоматический перенос виртуальных машин в кластере. 8 секунд и, например, сервер терминалов сменил место жительства совместно со всеми своими предустановленными программами - в другую серверную.
И ... оставил аппаратные лицензии и ЭЦП, заботливыми руками проброшенные в виртуалки, тоскливо торчать из, возможно, погибшего железа.
Настройки без лирики
При проектировании кластера виртуализации приходится учитывать и такой сценарий - шанс его достаточно высок - и, скорее всего, выпадет на период обслуживания - штатный перенос с ноды на ноду прошел гладко - вечернее обновление, инженер-техник дождался отключения, продувает пыль, меняет термопасту, ssd, добавляет оперативу (нужное подчеркнуть). Вторая нода ласково подхватила машины и контейнеры и где -то далеко тихо подвывает в опечатанном и совершенно недоступном помещении. Админ в полглаза наблюдает за возросшей нагрузкой на ноду - ничего заслуживающего дополнительного внимания - какой то час и их снова две, и нагрузка мягко размажется как масло по бутербродам.
На руке бешено начинают дрожать смарт-часы - с гневом сообщая, что :
«ВсеПропало/ ЕдьСамДелай/СрокГорит/ Тендер по Магаданскому времени/Подпись недоступна/Лицензии отъехали»
Все мы знаем, что такое (обязательно произойдет) не произойдет - регламент, согласование - прочие защитные механизмы. Но удобнее совсем не позволить выполниться сценарию.
С проблемой удаленного проброса прекрасно справляются множества аппаратных устройств USBoverIP и можно выделить бюджет, отстоять необходимость приобретения, стоически пробиться через бюрократические джунгли, но статья не об этом. Наш путь - самим собрать свой программно-аппаратный пепелац "USB через родную ЛВС".
Железо берем с достаточным количеством портов USB, одним, а лучше двумя портами ethernet (не забываем про резервирование коммутаций), SSD в Первый RAID . Накатим Ось -в примере - Alt -Linux/Debian, зададим имя хоста, ip адрес, если не резервируете в DHCP.
Далее установка - которая мало отличается от всех описанных, ранее (например в USB over IP для личного использования):
sudo apt-get update
sudo apt-get install usbip
загрузка модулей
sudo modprobe usbip-core
sudo modprobe usbip-host
sudo modprobe vhci-hcd
настройка их автозагрузки
sudo nano /etc/modules
добавим в конец файла
usbip‑core
usbip‑host
vhci‑hcd
Здесь вводная часть статьи заканчивается - вот мы и дошли до сути.
Серверная часть
в ручную
Сам по себе USB-IP ничего биндить, да расшаривать не желает, предлагая каждое устройство выбрасывать в сеть руками
usbip list -l
#Получили список портов
- busid 1-1 (064f:0bd7)
usbip bind -b 1-1
полуавтомат
Жить это будет до перезагрузки, что легко решается через systemd
sudo nano /etc/systemd/system/usbip-device@1-1.service
sudo nano /opt/check_usb_device.sh
usbip-device@1-1.service
[Unit]
Description=USBIP Device %I
Requires=usbipd.service
After=usbipd.service
[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/usr/sbin/usbip bind -b %i
ExecStop=/usr/sbin/usbip unbind -b %i
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Включаем наш сервис - и можем переходить к настройке клиента или читаем дальше:
sudo systemctl enable usbip-device@1-1 --now
автомат
поставили - барышню вынули
Но мы то желаем вставить ключ и на старт, и пусть лишние ключи сами убираются из списка расшаренных. А еще нам не нужны клавиатуры, мыши usb сетевые карты :
sudo nano /opt/check_usb_device.sh
check_usb_device.sh
!/bin/bash
declare -A usbdevices
current_usbdevices=()
bind_usb_device() {
local busid="$1"
if usbip bind -b "$busid"; then
logger -t usbip-service "bind Key $busid"
# echo "bind Key $busid"
fi
}
unbind_usb_device() {
local busid="$1"
if usbip bind -b "$busid"; then
logger -t usbip-service "unbind Key $busid"
# echo "unbind Key $busid"
fi
}
while true; do
output="$(/usr/sbin/usbip list -p -l)"
updated_usbdevices=()
while IFS='#' read -r line; do
busid="$(echo "$line" | grep -oE 'busid=[0-9]+-[0-9]+.[0-9]+|busid=[0-9]+-[0-9]+' | cut -d '=' -f 2)"
usbid="$(echo "$line" | grep -oE '[0-9a-fA-F]{4}:[0-9a-fA-F]{4}')"
usbdevices["${busid}"]="${usbid}"
updated_usbdevices+=("$busid")
done <<< "$output"
echo "UPD: ${updated_usbdevices[@]}"
for busid in "${current_usbdevices[@]}"; do
if [[ ! " ${updated_usbdevices[@]} " =~ " $busid " ]]; then
# busid отсутствует в обновленном списке, удаляем е
current_usbdevices=(${current_usbdevices[@]//$busid/})
unbind_usb_device "$busid"
fi
done
for busid in "${!usbdevices[@]}"; do
result=$(lsusb | grep "${usbdevices[$busid]}" | grep -ivE 'keyBoard|mouse|ethernet|wireless' && echo true || echo false)
if [ "$result" != false ]; then
if [[ ! " ${current_usbdevices[@]} " =~ " $busid " ]]; then
current_usbdevices+=("$busid")
bind_usb_device "$busid"
fi
fi
done
# echo CUR: "${current_usbdevices[@]}"
sleep 10
done
sudo chmod ugo+x /opt/check_usb_device.sh
Описываем наш сервис и включаем
sudo nano /etc/systemd/system/usbip-device@allusb.service
usbip-device@allusb.service
[Unit]
Description=USBIP Device Binding Service
After=usbipd.service
Requires=usbipd.service
[Service]
Type=simple
ExecStart=/opt/check_usb_device.sh
Restart=always
StartLimitBurst=0
StartLimitIntervalSec=1
KillMode=control-group
[Install]
WantedBy=multi-user.target
sudo systemctl enable usbip-device@allusb --now
Устройства теперь будут доступны всем разрешенным их увидеть (а запрещаем, например поставив и настроив firewalld , iptables - но это вне рамок данной статьи).
Можно переходить к клиентской части.
клиент
Тут все тот же systemd и описание сервиса (скрипт поместился прямо в тело юнита в одну строку).
sudo nano /etc/systemd/system/usbip-device@1-1.service
usbip-device@1-1.service
#вместо <usbip-servername> подставьте свое имя сервера
[Unit]
Description=USBIP Attach Device %I
After=network.target
[Service]
Type=simple
ExecStart=/usr/sbin/usbip attach -r keys -b %i
RemainAfterExit=yes
ExecStartPre=/bin/bash -c 'while trueusbip list; do result=$(usbip list -p -r <usbip-servername> | grep -q /%i && echo True || echo False); if [ "$result" != "False" ]; then logger -t usbip-service "Key %i available to attache"; usr/sbin/usbip attach -r keys -b %i; fi; sleep 60; done'
ExecStop=/usr/sbin/usbip detach -p 00
Restart=always
StartLimitBurst=0
StartLimitIntervalSec=1
KillMode=control-group
[Install]
WantedBy=multi-user.target
Включаем сервис
sudo systemctl enable usbip-device@1-1 --now
Вместо заключения
Сервис сам будет отслеживать доступность и подключаться к USB устройствам через USBIP.
Связка достаточно стабильна и надежна чтобы использоваться до тех пор, пока ее место не займет сертифицированный и обмазанный гарантиями продукт. Хотя всегда можно сделать точную копию, положить на полку и быстро-быстро заменить - переткнув ключи, но мы так делать не будем.