Pull to refresh

Multiseat для Windows рабочих мест

Reading time10 min
Views47K

Хочу вам рассказать о необычном способе создания многопользовательской рабочей станции, в качестве основы которого лежит VMPlayer.

Данное решение разрабатывалось для коммерческой эксплуатации, а в качестве посыла к решению этой задачи ставилось утверждение, что текущие характеристики приобретаемого оборудования превосходят потребности пользователей и используемого ими программного обеспечения. Конечно, это касается в основном типового офисного планктона и многих периферийных должностей. Также это будет полезно для решения проблем у тех, кому руководство по своим, вполне обоснованным соображениям, отказало или с большой вероятностью откажет в просьбе обновления рабочей станции. Печально, но так бывает…

Для того чтобы решение стало достойным применения, ему были предъявлены следующие требования:
  • В качестве операционной системы для конечных пользователей должна остаться Windows.
  • Стоимость системного блока для двух сотрудников, в идеале должна быть сравнима со стоимостью одного типового, из приобретаемых на тот момент.
  • Работа пользователей не должна сколько-нибудь заметно замедлится или быть некомфортной, от того, что используется один компьютер.

Ну собственно, бизнес-требования ясны, значит пора переходить к решению…

Техническая часть


Разработка велась на рабочей станции со скромными на текущий момент параметрами – AMD Athlon 64 X2, GeForce GT 440, DDR II 4Gb, HDD 320GB, и хотя результат оказался вполне приемлемым, для соответствия вышеуказанным требованиям, при выборе технической составляющей следует учесть следующие рекомендации:
  • Процессор с двумя ядрами — каждой VM выделяется по одному, и конечно желательна поддержка современных технологий виртуализации, тогда можно ожидать производительность, приближенную к «железной» рабочей станции.
  • Оперативная память не является особо дорогим составляющим, поэтому лучше, не жалея, рассчитать по 3Gb на каждое рабочее место, плюс 1 Gb для хост системы. Но в определенных ситуациях вполне можно обойтись и по 1,5 Gb для каждого места.
  • Жесткий диск, на котором будет расположена виртуальная машина, желательно, чтобы был отдельный для каждого рабочего места, это даст независимость операций ввода/вывода и виртуальные машины будут меньше мешать друг другу. Это требование можно опустить, если цель экономии средств является более приоритетной.
  • Материнская плата, желательно, должна быть уже с двумя видеовыходами, этим снимается необходимость в приобретении отдельной видеокарты. Но, если у вас есть желание использовать свою видеокарту и/или на материнской нет видеовыходов, то можно использовать, конечно, внешнюю.

Есть еще несколько замечаний касающихся периферии, а именно мониторов, клавиатур и мышей, и хотя на первый взгляд они несколько странноваты, их выполнение не составит большого труда и затрат, что важно для выполнения требований к решению.
  • Мониторы. При выборе мониторов следует учесть, что материнские платы с видеовыходами DVI и VGA, не поддерживают переходники DVI->VGA. Поэтому нужно убедиться, что имеющиеся мониторы и видеовыходы соответствуют друг другу.
  • Клавиатуры и мыши. Это скорее не замечание, а больше ограничение к выбору этих HID устройств. Во первых, все устройства должны быть USB. Во вторых, VID:PID одной клавиатуры не должен совпадать с VID:PID другой. Такое же условие накладывается и на мыши. Если говорить проще, модели клавиатур должны отличатся между собой и модели мышей тоже должны быть разными. Связано это ограничение с тем, что для распределения устройств между виртуальными машинами используются VID и PID, а возможность подключения одинаковых моделей не изучалась, так как выполнение этого условия не составляет большого труда.

Для примера приведу конфигурацию, которую мы взяли за стандарт для наших dualseat’ов: Intel Core i3, MB (DVI+VGA, Audio, GLan),HDD 500Gb x 2.

Итак, техническую часть пояснил и обосновал. Теперь перейду к программной начинке и принципу работы.

Подготовка


Ну что же, приступим. Для создания dualseat нам нужно подготовить несколько основных компонентов.

Платформа

Первым шагом для создания платформы для dualseat инсталируем Ubuntu Server 12.04 x64. После достаточно тривиальной установки системы доставляем пакеты, которые обеспечат функционирование остальных компонентов, и заодно некоторые полезные утилиты:
apt-get install ...
apt-get install unclutter xinput libxcursor1 mc openssh-server binutils gcc x11-xserver-utils x11vnc xinetd alsa-base alsa-utils vim nodm fluxbox tofrodos ntfsprogs
Если требуется, устанавливаем драйвера видеокарты.

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

Начнем с конфигурации nodm, который как раз предназначен для автоматического запуска X сессии, сразу во время загрузки системы:
/etc/default/nodm
/etc/default/nodm
NODM_ENABLED=true
NODM_USER=vm
NODM_XINIT=/usr/bin/xinit
NODM_XSESSION=/etc/X11/Xsession
NODM_X_OPTIONS='vt7 -nolisten tcp'
NODM_MIN_SESSION_TIME=60
Теперь настроим оконный менеджер для организации пустого рабочего пространства. Для этого устанавливаем следующие параметры в настройках fluxbox:
/home/vm/.fluxbox/init
/home/vm/.fluxbox/init
session.screen0.toolbar.visible: false
session.screen0.workspaces: 1
Операционная система подготовлена, и как сказал бы Лёлик из кинофильма «Брильянтовая рука» – «Шеф, усе готово, система грузится без шума и пыли».

Далее скачиваем с официального сайта VMWare последнюю версию VMPlayer. Установка достаточно проста, но может потребовать установку патча, непосредственно сразу после установки, если vmplayer не будет запускаться. Но, чтобы добиться максимальной отзывчивости виртуальных машин, проведем
небольшой тюнинг системы и гипервизора
/etc/vmware/config
mainMem.useNamedFile="FALSE"
tmpDirectory="/run/shm"
prefvmx.useRecommendedLockedMemSize="TRUE"
prefvmx.minVmMemPct="100"

/etc/sysctl.conf
vm.swappiness=0
vm.overcommit_memory=1
vm.dirty_background_ratio=5
vm.dirty_ratio=10
vm.dirty_expire_centisecs=1000
dev.rtc.max-user-freq=1024

/etc/fstab
Значение size зависит от количества установленной оперативной памяти, и не может быть меньше суммы выделенной обоим виртуальным машинам плюс 1 Gb. Это будет связано с тюнингом проводимым ниже.
tmpfs /run/shm tmpfs size=8G

Системное окружение

Теперь нужно подготовить системное окружение: создать пользователя и пару папок.
  • vm — это пользователь, которым будет входить nodm, и от которого будет производится запуск виртуальных машин.
  • /home/vm/user01 и /home/vm/user02 — папки для виртуальных машин пользователей. В случае, если система подготовлена с двумя жесткими дисками, второй жесткий диск следует замонтировать в одну из этих папок.

Виртуальные рабочие места

Создание виртуальных машин и установку систем оставлю вам на откуп, думаю, этот процесс знаком большинству читателей. Но несколько рекомендаций все же будут, так как целью ставится комфортная работа пользователей.
  • Виртуальные диски должны быть обязательно SCSI, независимо от того, какая система будет стоять, и ни в коем случае не следует выбирать IDE, так как вы получите очень неэффективную виртуальную дисковую подсистему.
  • Неиспользуемое оборудование (Printer, Floppy disk, Serial port и т.д) следует удалить из конфигурации виртуальной машины.
  • VMWare Tools является обязательным компонентом для эффективной работы гостевой системы.

Некоторые важные условности для скриптов, расположенных ниже:
  • Ожидается, что имена обоих vmx файлов — это workstation.vmx.
  • Имена виртуальных машин должны быть user00 и user01 соответственно.

После того как виртуальные рабочие станции подготовлены и расположены в своих местах, проведем их тюнинг, опять же выжимая максимальную производительность.
/home/vm/user00/workstation.vmx и /home/vm/user01/workstation.vmx
/home/vm/user00/workstation.vmx и /home/vm/user01/workstation.vmx
mem.ShareScanTotal=0
mem.ShareScanVM=0
mem.ShareScanThreshold=8192  # Значение зависит от количества установленной оперативной памяти
sched.mem.maxmemctl=0
sched.mem.pshare.enable = "FALSE"
mainMem.useNamedFile = "FALSE" 
MemTrimRate = "0"
MemAllowAutoScaleDown = "FALSE"

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

Конфигурация запуска системы


Для запуска dualseat используем /home/vm/.fluxbox/startup, содержимое которого, последовательно и комментируя, привожу далее (обратите внимание на настройку мониторов).
/home/vm/.fluxbox/startup
/home/vm/.fluxbox/startup
Отключаем все попытки системы «потушить» экран:
xset -dpms
xset s off
setterm -blank 0
setterm -powerdown 0

По умолчанию, система с двумя мониторами запускается в режиме clone, это когда мы видим одну и ту же картинку на обоих мониторах. Для настройки корректного отображения будем использовать утилиту xrandr (вместо конфигурации в xorg.conf).
Чтобы получить доступные разрешения для каждого монитора, используется команда xrandr -q. Нужно обратить внимание на то, что DVI выход системой показывается как HDMI.
Настройка обоих мониторов происходит в момент запуска fluxbox, для этого используются следующие строки (порядок строк важен), значения в которых, у вас конечно должны быть свои:

# Устанавливаем разрешение монитора подключенного к VGA
xrandr --output VGA1 --mode 1280x1024 
# Устанавливаем разрешение монитора подключенного к HDMI
xrandr --output HDMI1 --mode 1920x1080
	
# Располагаем HDMI пространство слева от VGA
xrandr --output HDMI1 --left-of VGA1 
# Делаем HDMI монитор основным (с которого будет начинаться нумерация)
xrandr --output HDMI1 --primary

Системный курсор нам не нужен, а сам по себе он остается всегда видимым, поэтому «тушим» его таким образом
unclutter -idle 1 -root &

Теперь запуск графической оболочки и сразу после нее запуск самих виртуальных машин
exec fluxbox &
fbpid=$!
sleep 1
{
 /home/vm/user00/start &  # Скрипт запуска VM00 
 /home/vm/user01/start &  # Скрипт запуска VM01
} &
wait $fbpid

Далее приведены скрипты запуска самих виртуальных машин, где в первую очередь проверяется, не запущена ли уже целевая машина. Сам запуск, следом, сопровождается скриптом check_shutdown, который выполнится сразу после выключения VM. Он нужен для проверки на необходимость выключения компьютера, при выключении обоих рабочих мест.
Cкрипты запуска виртуальных машин
/home/vm/user00/start
if ps ax | grep -v grep | grep -P "vmplayer.*user00" > /dev/null
then
    exit
else    
    /usr/bin/vmplayer -X /home/vm/user00/workstation.vmx && /home/vm/check_shutdown &
fi

/home/vm/user01/start
if ps ax | grep -v grep | grep -P "vmplayer.*user01" > /dev/null
then
    exit
else    
    /usr/bin/vmplayer -X /home/vm/user01/workstation.vmx && /home/vm/check_shutdown &
fi

/home/vm/check_shutdown
if ps ax | grep -v grep | grep vmplayer > /dev/null then
  exit 0
else
  sudo shutdown -h now
fi

Для выполнения команды sudo shutdown без ввода пароля, нужно добавить в файл /etc/sudoers строку:
vm ALL=NOPASSWD: /sbin/shutdown


Изоляция


Теперь приступим к изоляции ресурсов между рабочими местами.

Мониторы

Для запуска виртуальных машин, каждой на своем мониторе, используем возможности оконного менеджера fluxbox, где в файле /home/vm/.fluxbox/apps указаны правила расположения виртуальных машин в момент запуска.
/home/vm/.fluxbox/apps
/home/vm/.fluxbox/apps
# для VMPlayer user00
[app] (title=.*user00.*)
    # Монитор 2
    [Head] {2}
    # Убираем оформление
    [Deco] {NONE}
    # Запустить минимизированным 
    [Minimized] {yes}
[end]

# для VMPlayer user00
[app] (title=.*user01.*)
    # Монитор 1
    [Head] {1}
    # Убираем оформление
    [Deco] {NONE}
    # Запустить минимизированным 
    [Minimized] {yes}    
[end]

# Other applications
[app] (title=.*)	
	[Jump] {no}
#	[Workspace] {1}
	[Position] (CENTER) {0 0}
	[Layer] {12}
[end]

Обратите внимание, что VMPlayer запускается минимизированным, это сделано для того, чтобы пользователь не видел запуск оболочки VMPlayer. Но для того, чтобы этот эффект до конца сработал, нужно не забыть в настройках VMPlayer поставить галочку на опции «Enter full screen mode after powering on» или как эквивалент — в workstation.vmx установить параметр gui.viewModeAtPowerOn = "fullscreen".
Если у вас видеокарта NVidia или Radeon и вы установили драйвера, то вы можете полноценно воспользоваться функцией проброса 3D ускорителя в виртуальный видеодевайс, установив галочку в параметре «Accelerate 3D graphics». В workstation.vmx за это отвечает параметр mks.enable3d = "TRUE".

Клавиатуры и мыши

Для распределения этих HID девайсов используется возможность VMPlayer захватывать в монопольное использование USB оборудование. Перед тем, как распределять устройства, выясняем их VID и PID, воспользовавшись утилитой lsusb. После того, как выяснены все идентификаторы устройств, прописываем следующие параметры в каждом workstation.vmx.
/home/vm/user00/workstation.vmx и /home/vm/user01/workstation.vmx
/home/vm/user00/workstation.vmx и /home/vm/user01/workstation.vmx
# Общие установки
vmmouse.present = "FALSE"
usb.generic.allowHID = "TRUE"
svga.noHWCursor = "TRUE" 

# Для клавиатуры c VID=0458 и PID=010e
usb.quirks.device0 = "0x0458:0x010e allow" 
usb.autoConnect.device0 = "0x0458:0x010e" 

# Для мыши c VID=0566 и PID=3107
usb.quirks.device1 = "0x0566:0x3107 allow"
usb.autoConnect.device1 = "0x0566:0x3107"

USB

Все USB устройства можно разделить на две категории: постоянно подключенные и подключаемые во время работы.
С постоянно подключенными проблем нет, они прописываются в соответствующей workstation.vmx, по аналогии и с помощью того же параметра usb.autoConnect.deviceN и утилиты lsusb, что использовались при подключении мышки и клавиатуры.
Для подключения USB устройств во время работы есть два варианта. Первый вариант — это когда все USB устройства прокидываются только на одну машину. Для этого, в файле workstation.vmx этой машины, устанавливаем параметр usb.generic.autoconnect=TRUE, а в другой соответственно usb.generic.autoconnect = "FALSE".
Второй вариант, который позволяет распределять USB устройства во время подключения самими пользователями — это использовать технологию USB over IP. Хотя этот способ может оказаться несколько затратным, но он решает поставленную задачу. Задача решается следующим образом: на хост ставится серверная часть, которая расшаривает USB устройства, а на гостевую систему ставится клиент. К сожалению opensource проект usb/ip оказался сырой и приемлемого результата добиться не удалось. При острой необходимости можно воспользоваться коммерческими продуктами, например, мы использовали этот: USB Redirector for Linux (эта часть бесплатная) и USB Redirector Client (эта стоит денег).

Последний штрих


Для полноты решения должны работать следующие сценарии:
  1. При включении системного блока, виртуальные машины запускаются автоматически.
  2. Каждое из рабочих мест можно включать и выключать, даже если работает соседнее рабочее место.
  3. При выключении всех рабочих мест, системный блок должен выключиться.

Пункт 1 и 3 реализованы с помощью скриптов расположенных выше. Пункт два выполнен частично. При выключении одной из виртуальных машин, вторая останется работать. Но как обратно включить выключенную машину? Решается вопрос очень элегантно: для этого вешаем на кнопу Power (это та, что на системном блоке) команду запуска виртуальных машин. Для этого в файле /home/vm/.fluxbox/keys прописываем несколько строк:
/home/vm/.fluxbox/keys
/home/vm/.fluxbox/keys
124 :Exec /home/vm/user00/start & /home/vm/user01/start
133 :Exec /home/vm/user00/start & /home/vm/user01/start

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

Результат


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

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

Как это работает у нас

Решение действительно работает. Сборка dualseat'а на самом деле сведена к минимуму. После установки системы, скриптом устанавливаются дополнительные пакеты, vmplayer и копируются все упомянутые конфиги и скрипты. Виртуальные машины просто тиражируются, используя «золотой шаблон». В конце требуется небольшая доводка: установить корректные разрешения у мониторов, подключить стационарные устройства и сконфигурировать работу с USB.

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

Спасибо всем за внимание, надеюсь получилось интересно.
Tags:
Hubs:
+38
Comments39

Articles