ЗАНЯТИЕ 25. «ВИРТУАЛИЗАЦИЯ И ОБЛАКО»

Бывает, что в организации имеется система из нескольких компьютеров, которая ей фактически не нужна. Типичным приме¬ром может послужить наличие в компании почтового сервера, веб-сервера и FTP-сервера, нескольких серверов электронной торговли и других серверов. И все они запускаются на разных компьютерах в единой стойке оборудования, соединены высокоскоростной сетью, то есть, иначе говоря, составляют мультикомпьютер. Одной из причин запуска всех этих серверов на отдельных машинах может послужить то, что одна машина не может справиться с нагрузкой, а другая отличается особой надежностью: управление компании про¬сто не верит в то, что операционная система может работать без сбоев 24 часа в сутки 365 или 366 дней в году. А если каждая служба помещена на отдельный компьютер, то сбой одного из сер¬веров по крайней мере не повлияет на работу остальных серверов. Также при этом легче решаются вопросы безопасности. Даже если злоумышленник взломает веб-сервер, то одновременно с этим он не получит доступ к конфиденциальной почте — иногда такое свой¬ство называют использованием песочницы. Хотя благодаря этому достигаются изоляция и устойчивость к сбоям, такое решение явля-ется весьма дорогостоящим и трудно управляемым, поскольку в нем задействовано множество машин.
Имейте в виду, что для использования отдельных машин есть всего лишь две причины. Например, организации в повседнев¬ной работе часто зависят от более чем одной операционной си¬стемы: веб-сервер работает на Linux, почтовый сервер — на Windows, сервер электронной торговли для клиентов — на OS X, а ряд других серверов запущены под несколькими разновидностями UNIX. При всей своей работоспособности такое решение обходится недешево.
Что же делать? Возможным (и весьма популярным) реше¬нием является использование технологии виртуальных машин, ко¬торая при всей новизне и стильности звучания базируется на до¬вольно старой идее, датированной далекими 1960-ми годами. Но даже при этом способ, используемый в наши дни, конечно же, но¬вый. Основная идея заключается в том, что монитор виртуальных машин (Virtual Machine Monitor (VMM)) создает иллюзию присут-ствия нескольких (виртуальных) машин на одном и том же физиче¬ском оборудовании. VMM известен также как гипервизор. Мы уже определили разницу между гипервизором первого типа, запускае¬мым непосредственно на оборудовании, и гипервизором второго типа, который может воспользоваться всеми полезными службами и абстракциями, предлагаемыми основной операционной системой. Так или иначе, виртуализация позволяет одному компьютеру стать базой для нескольких виртуальных машин, на каждой из которых потенциально может быть запущена совершенно другая операци¬онная система. Преимуществом такого подхода является то, что авария одной виртуальной машины не приводит к аварии любой другой машины. На виртуализированной системе разные серверы могут запускаться на разных виртуальных машинах, поддерживая тем самым модель частичных отказов, характерную для мульти¬компьютеров, но при меньшей стоимости и более простом обслу¬живании. Более того, теперь на одном и том же оборудовании можно запускать несколько разных операционных систем, получая преимущества изолированности виртуальных машин при угрозе хакерских атак и другие преимущества.
Разумеется, подобное объединение серверов сродни укла¬дыванию всех яиц в одну корзину. При падении сервера, на кото¬ром запущены все эти виртуальные машины, результат будет еще катастрофичнее падения отдельного выделенного сервера. Но смысл связываться с виртуализацией заключается в том, что подав¬ляющая часть выходов служб из строя происходит не по вине обо¬рудования, а из-за недочетов в разработке, ненадежности, наличия ошибок и плохой настройки программного обеспечения, включая, и это следует особо подчеркнуть, операционные системы. При ис¬пользовании технологии виртуальных машин единственным про¬граммным обеспечением, запущенным в режиме наивысших при-вилегий, является гипервизор, у которого имеется на два порядка меньше строк кода, чем у всей операционной системы, а следова¬тельно, и на два порядка меньше потенциальных ошибок. Гиперви¬зор проще операционной системы, поскольку он занимается только одним — эмулированием нескольких копий оборудования (чаще всего с архитектурой Intel x86).
Запуск программного обеспечения кроме строгой изолиро¬ванности имеет и другие дополнительные преимущества. Одно из них заключается в меньшем числе физических машин, что позво¬ляет экономить средства на оборудовании и энергопотреблении и использовать меньшее пространство для аппаратных стоек. Для таких компаний, как Amazon или Microsoft, у которых в каждом центре обработки данных могут находиться сотни тысяч серверов, выполняющих великое множество разнообразных задач, сокраще¬ние физических потребностей в их дата-центрах выльется в гигант¬скую экономию средств. Фактически серверные компании зачастую размещают свои дата-центры в любых местах, лишь бы они были недалеко от гидроэлектростанций (и от дешевой электроэнергии). Виртуализация также содействует проверке жизнеспособности но¬вых идей. Обычно в крупных компаниях отдельные подразделения или группы занимаются проработкой интересных идей, а затем идут на затраты, приобретая сервер для их реализации. Если идея получает популярность и ей необходимы сотни или тысячи серве¬ров, дата-центр корпорации расширяется. Зачастую перемещение программного обеспечения на уже существующие машины дается нелегко, поскольку каждому приложению часто требуется другая версия операционной системы, его собственные библиотеки, кон¬фигурационный файлы и многое другое. При использовании вирту¬альных машин каждое приложение может взять с собой все свое окружение.
Еще одним преимуществом виртуальных машин является то, что установка контрольных точек и миграция этих виртуальных машин (например, для выравнивания баланса загруженности не¬скольких серверов) даются намного легче, чем миграция процессов, запущенных на обычной операционной системе. В последнем слу¬чае в таблицах операционной системы хранится изрядное количе¬ство важной информации о состоянии каждого процесса, в том числе информация, относящаяся к открытым файлам, аварийным сигналам, обработчикам сигналов и многому другому. При мигра¬ции виртуальной машины все, что должно перемещаться, касается только памяти и образов дисков, поскольку с ними перемещаются также и все таблицы операционной системы.
Еще одним примером использования виртуальных машин является запуск устаревших приложений на операционных систе¬мах (или версиях операционных систем), которые больше не под¬держиваются или не работают на существующем оборудовании. Они могут работать в то же время и на том же оборудовании, что и текущие приложения. Фактически возможность запуска в одно и то же время приложений, использующих разные операционные си¬стемы, является существенным аргументом в пользу виртуальных машин.
Еще одним важным аспектом использования виртуальных машин является разработка программного обеспечения. Програм¬мист, желающий убедиться в работоспособности своей программы под Windows 7, Windows 8, несколькими версиями Linux, FreeBSD, OpenBSD, NetBSD и OS X, а также под управлением других систем, теперь не нуждается в десятке компьютеров и в установке операци¬онных систем на все эти компьютеры. Вместо этого он просто со¬здает десять виртуальных машин на одном компьютере и устанав¬ливает на каждую из них разные операционные системы. Разуме¬ется, он может разбить жесткий диск на разделы и установить в каждый из разделов другую операционную систему, но этот подход дается намного сложнее. Во-первых, на стандартном персональном компьютере независимо от объема диска поддерживаются только четыре первичных дисковых раздела. Во-вторых, хотя в загрузоч¬ный блок можно установить программу мультизагрузки, для ра¬боты компьютера под управлением новой операционной системы его придется перезагрузить. При использовании виртуальных ма¬шин все они могут работать одновременно, поскольку на самом деле все они являются всего лишь возведенными на более высокий уровень процессами.
Возможно, наиболее важным и соответствующим времени случаем использования виртуализации является облако (cloud). Ключевая идея облака довольно проста: передать ваши потребно¬сти в вычислениях или хранении данных в высокоорганизованный дата-центр, запущенный компанией, специализирующейся на по¬добных услугах и укомплектованной специалистами в данной обла¬сти. Поскольку дата-центр обычно принадлежит кому-нибудь дру¬гому, вам, скорее всего, придется платить за использование ресур¬сов, но при этом по крайней мере не придется волноваться за физи¬ческие машины, энергопотребление, охлаждение и обслуживание. Поскольку изолированность обеспечивается виртуализацией, по¬ставщики облачных услуг могут позволить нескольким клиентам, даже конкурирующим друг с другом, пользоваться общей физиче¬ской машиной. Каждый клиент получает свой кусок пирога. Рискуя растянуть метафору облака, следует упомянуть, что на ранних эта¬пах критики утверждали, будто этот пирог находится только на не¬бесах и что настоящие организации не захотят помещать свои кон¬фиденциальные данные и вычисления на какие-то другие ресурсы. Но теперь виртуализированные машины в облаках используются несметным числом организаций для не поддающегося подсчету количества приложений, и хотя это, может быть, не все организа¬ции и не все данные, не возникает никаких сомнений, что облачные вычисления пользуются успехом.

22.1. История

Во всей этой шумихе, окружающей виртуализацию в по¬следние годы, мы иногда забываем, что по меркам Интернета вир¬туальные машины являются весьма древними устройствами. Их истоки теряются в 60-х годах прошлого столетия. В IBM проводи¬лись эксперименты даже не с одним, а с двумя разработанными независимо друг от друга гипервизорами: SIMMON и CP-40. Хотя CP-40 был исследовательским проектом, он был переработан в CP-67 и сформирован в виде программы управления для CP/CMS, опе-рационной системы виртуальных машин для IBM System/360 Model 67. Позже он был снова переработан и реализован в виде VM/370 для серии машин System/370, выпущенной в 1972 году. Линейка машин System/370 в 1990-х годах была заменена компанией IBM линейкой System/390. В основном изменилось только название, по¬скольку базовая архитектура из соображений обратной совмести¬мости осталась прежней. Разумеется, аппаратные технологии стали совершеннее и более новые машины были больше и быстрее ста¬рых, но что касается виртуализации, ничего не изменилось. В 2000 году IBM выпустила z-серии, поддерживающие 64-разрядное вир¬туальное адресное пространство при сохранении обратной совме¬стимости с System/360. Все эти системы поддерживали виртуализа¬цию на десятилетия раньше того момента, когда она приобрела по¬пулярность на машинах семейства x86.
В 1974 году двое ученых из Калифорнийского университета (Лос-Анджелес), работающих в компьютерной сфере, Геральд По¬пек (Gerald Popek) и Роберт Голдберг (Robert Goldberg), опублико¬вали основополагающую статью («Formal Requirements for Virtualizable Third Generation Architectures»), в которой дали точный перечень тех условий, которым должна отвечать компьютерная ар¬хитектура, чтобы иметь возможность эффективно поддерживать виртуализацию (Popek and Goldberg, 1974). Примечательно, что широко известная архитектура x86, которая также берет начало в 1970-х годах, десятилетиями не отвечала этим требованиям. Но это было еще не все. Практически каждая архитектура со времен уни¬версальных машин (мейнфреймов) также проваливала тест. 1970-е годы были весьма продуктивными, они увидели рождение UNIX, Ethernet, Cray-1, Microsoft и Apple, — следовательно, несмотря на то что могли бы сказать ваши родители, в 1970-е на планете гремел не только стиль диско!
Фактически настоящая революция Disco грянула в 1990-е годы, когда исследователи из Стэндфордского университета разра¬ботали новый гипервизор с таким именем и стали основателями VMware, гиганта виртуализации, предлагающего гипервизоры типа 1 и типа 2 и теперь гребущего миллиарды долларов дохода (Bugnion et al., 1997; Bugnion et al., 2012). Кстати, разница между гипервизорами типа 1 и типа 2 также пришла из 1970-х (Goldberg, 1972). VMware представила свое первое решение по виртуализации для x86 в 1999 году. Затем последовали и другие продукты: Xen, KVM, VirtualBox, Hyper-V, Parallels и многие другие. Похоже, время для виртуализации как раз подоспело, даже при том, что тео¬рию застолбили еще в 1974 году, а IBM десятилетиями продавала компьютеры, поддерживающие и активно использующие виртуали¬зацию. В 1999 году виртуализация приобрела широкую популяр¬ность, но несмотря на внезапно возросший к ней массовый интерес, новинкой она не была.

22.2. Требования, применяемые к виртуализации

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

  1. Безопасность — у гипервизора должно быть полное управле¬ние виртуализированными ресурсами.
  2. Эквивалентность — поведение программы на виртуальной машине должно быть идентичным поведению этой же про¬граммы, запущенной на реальном оборудовании.
  3. Эффективность — основная часть кода в виртуальной ма¬шине должна выполняться без вмешательства гипервизора.
    Несомненно, безопасный способ выполнения инструкций заключается в поочередном рассмотрении каждой инструкции в интерпретаторе (например, в Bochs) и в выполнении именно того, что нужно для данной инструкции. Некоторые инструкции могут быть выполнены напрямую, но их не много. Например, ин¬терпретатор может быть способен выполнить инструкцию INC (ин¬кремент) просто как есть, но инструкции, которые небезопасно вы¬полнять напрямую, должны быть эмулированы интерпретатором. Например, нельзя разрешать гостевой операционной системе бло¬кировать прерывания для всей машины или модифицировать отоб¬ражения страниц в таблицах. Нужно применить прием, заставляю-щий операционную систему, посаженную поверх гипервизора, по¬лагать, что она заблокировала прерывания или изменила отображе¬ние страниц на машине. Позже будет показано, как это делается. А сейчас хочется лишь сказать, что интерпретатор может быть без¬опасным и при тщательной реализации, возможно, даже высокока¬чественным, но производительность его может оказаться не на вы¬соте. Далее будет показано, что для того, чтобы соответствовать также критериям производительности, мониторы виртуальных ма¬шин (VMM) стараются выполнить основную часть кода непосред¬ственным образом.
    Теперь обратимся к точности. Виртуализация долгое время была проблемой для архитектуры x86 из-за дефектов в архитектуре Intel 386, которые упорно в течение 20 лет переносились на новые центральные процессоры во имя обратной совместимости. В двух словах, каждый центральный процессор с режимом ядра и пользо¬вательским режимом имеет набор инструкций, ведущих себя по-разному в зависимости от того, в каком режиме они выполняются, в режиме ядра или в пользовательском режиме. В их число входят инструкции, осуществляющие ввод-вывод, изменяющие настройки блока управления памятью (MMU) и т. д. Попек и Голдберг назвали их служебными инструкциями (sensitive instructions), или ин-струкциями, чувствительными к виртуализации. Есть также набор инструкций, которые при выполнении в пользовательском режиме вызывают системные прерывания. Попек и Голдберг назвали их привилегированными инструкциями (privileged instructions). В статье этих специалистов впервые утверждалось, что машина мо¬жет быть подвергнута виртуализации, только если служебные ин¬струкции являются поднабором привилегированных инструкций. Проще говоря, при попытке сделать в пользовательском режиме то, что вы не должны делать в этом режиме, оборудование должно вы¬звать системное прерывание. В отличие от IBM/370, обладающей эти свойством, у Intel 386 его нет. При выполнении в пользователь¬ском режиме будут проигнорированы или выполнены по-другому многие служебные инструкции 386-е машины. Например, инструк¬ция POPF заменяет регистр флагов, который изменяет бит, благо¬даря которому блокируются и разблокируются прерывания. В поль¬зовательском режиме этот бит просто не изменяется. Вследствие этого 386-е машины и их преемники не могли быть виртуализиро¬ваны, следовательно, они не могли поддерживать гипервизор напрямую.
    На самом деле ситуация была еще хуже, чем в этом кратком обзоре. Вдобавок к проблемам с инструкциями, которые, выполня¬ясь в пользовательском режиме, вызывали системные прерывания, были еще и инструкции, которые могли считывать конфиденциаль-ное состояние, не вызывая системных прерываний. Например, на процессорах x86 выпуска до 2005 года программа путем чтения селектора своего кодового сегмента могла определять, в каком ре¬жиме она выполняется, в пользовательском или в режиме ядра. Операционная система, выполнявшая такое действие и позволяв¬шая обнаруживать, что она в данный момент находится в пользова¬тельском режиме, могла на основе этой информации принимать неправильные решения.
    Эта проблема была окончательно решена, когда в начале 2005 года Intel и AMD представили виртуализацию на своих цен¬тральных процессорах (Uhlig, 2005). На центральных процессорах Intel она называлась технологией виртуализации (Virtualization Technology (VT)), а на центральных процессорах AMD она называ¬лась безопасной виртуальной машиной (Secure Virtual Machine (SVM)). Далее в общем смысле будет использоваться термин VT. Обе технологии были вдохновлены примером работы IBM VM/370, но при этом имеют от нее небольшие отличия. Основной замысел заключался в создании контейнеров, в которых могли бы запус¬каться виртуальные машины. При запуске в контейнере гостевой операционной системы она продолжает работать в нем, пока ею не будет вызвано исключение и не будет осуществлено системное прерывание в гипервизоре, например, при выполнении инструкции ввода-вывода. Набор операций, вызывающих это системное преры¬вание, контролируется битовым массивом, устанавливаемым ги¬первизором. С таким расширением появилась возможность созда¬ния классической виртуальной машины, работающей по принципу вызова системного прерывания и эмуляции.
    Вы, наверное, заметил явное противоречие в предложенном до сих пор описании. С одной стороны, было сказано, что x86-ма¬шины не могли быть виртуализированы вплоть до появления архи¬тектурного расширения, представленного в 2005 году, а с другой — было сказано, что VMware запустила свой первый гипервизор на x86 в 1999 году. Как все это вместе может быть правдой? Ответ за¬ключается в том, что гипервизоры до 2005 года фактически не за¬пускали настоящие гостевые операционные системы. Вместо этого они переписывали часть кода на лету, заменяя проблемные ин¬струкции безопасной кодовой последовательностью, эмулирующей исходную инструкцию. Предположим, к примеру, что гостевая операционная система выполняет привилегированную инструкцию ввода-вывода или модифицирует один из привилегированных управляющих регистров центрального процессора (например, ре¬гистр CR3, содержащий указатель на каталог страниц). Важно, чтобы последствия выполнения таких инструкций ограничивались данной виртуальной машиной и не оказывали влияния на другие виртуальные машины или на сам гипервизор. Таким образом, не¬безопасные инструкции ввода-вывода заменялись системным пре-рыванием, которое после проверки безопасности выполняло экви¬валентную инструкцию и возвращало результат. Поскольку проис¬ходила перезапись, этим трюком можно было воспользоваться для замены инструкций, являвшихся служебными, но не входивших в число привилегированных. Все остальные инструкции выполнялись обычным порядком. Эта технология известна как двоичная транс¬ляция.
    Переписывать абсолютно все служебные инструкции нет необходимости. В частности, пользовательские процессы на госте¬вой операционной системе могут, как правило, выполняться без модификации. Если инструкция не входит в число привилегиро-ванных, но относится к служебным и ведет себя в пользовательских процессах не так, как в процессах ядра, то все нормально. Она все равно запускается в пользовательской среде. Что же касается слу¬жебных инструкций, входящих в состав привилегированных, то можно, как обычно, прибегнуть к классической схеме с системным прерыванием и эмуляцией. Разумеется, VMM должен обеспечить получение соответствующих системных прерываний. Обычно в VMM имеется модуль, выполняемый в ядре и перенаправляющий системные прерывания к своим собственным обработчикам.
    Другая форма виртуализации известна как паравиртуали¬зация. Она сильно отличается от полной виртуализации, поскольку никогда даже не стремится представить виртуальную машину, ко¬торая бы выглядела как настоящее основное оборудование. Вместо этого она представляет машиноподобный программный интерфейс, который явно раскрывает факт наличия виртуальной среды. Например, он предлагает набор гипервызовов (hypercall), позволя¬ющих гостю отправлять явные запросы к гипервизору (во многом это похоже на то, как системный вызов предлагает службы ядра приложениям). Гостевые системы используют гипервызовы для привилегированных служебных операций, таких как обновление таблиц страниц, но поскольку они делают это явным образом во взаимодействии с гипервизором, в целом система может получаться проще и быстрее.
    Наверное, то, что в паравиртуализации нет ничего нового, уже не вызовет у вас удивления. Разработанная IBM операционная система VM уже предлагала такую возможность, правда, под дру¬гим именем, еще с 1972 года. Идея была возрождена в мониторах виртуальных машин Denali (Whitaker et al., 2002) и Xen (Barham et al., 2003). По сравнению с полной виртуализацией, недостатком паравиртуализации является то, что гостевая система должна знать о существовании API виртуальной машины. Как правило, это озна¬чает, что она должна быть специально настроена под гипервизор.
    Перед тем как еще больше углубиться в рассмотрение ги¬первизоров первого и второго типов, важно отметить, что не все технологии виртуализации пытаются обмануть гостевую систему, заставляя ее поверить в обладание всей системой. Иногда цель за-ключается в простом разрешении запуска процесса, изначально написанного для другой операционной системы и/или архитектуры. Поэтому нужно различать полную систему виртуализации и вир¬туализацию на уровне процесса. Хотя далее в главе основное вни¬мание будет уделено первой из них, практикуется также и техноло¬гия виртуализации на уровне процесса. К широко известным при¬мерам можно отнести уровень совместимости WINE, который поз¬воляет приложениям Windows запускаться на POSIX-совместимых системах, таких как Linux, BSD и OS X, и версию эмулятора QEMU на уровне процесса, которая позволяет приложениям для одной ар¬хитектуры выполняться на оборудовании с другой архитектурой.

22.3. Гипервизоры первого и второго типа

В работе Goldberg (1972) различаются два подхода к вирту¬ализации. Одна разновидность гипервизора, названная гипервизо¬ром первого типа (type 1 hypervisor), показана на рис. 84, а. Техни¬чески этот гипервизор похож на операционную систему, поскольку это единственная программа, запущенная в самом привилегирован¬ном режиме. Его работа заключается в поддержке нескольких ко¬пий имеющегося оборудования, которое называется виртуальными машинами, что похоже на выполнение процессов в обычной опера¬ционной системе.
В отличие от этого гипервизор второго типа, показанный на рис. 84, б, относится к другой разновидности программ. Это про¬грамма, которая при распределении и планировании использования ресурсов опирается, скажем, на Windows или Linux и очень похожа на обычный процесс. Разумеется, гипервизор второго типа к тому же притворяется полноценным компьютером с центральным про¬цессором и различными устройствами. Оба типа гипервизоров должны выполнять набор машинных инструкций безопасным обра¬зом. Например, операционная система, запущенная поверх гипер¬визора, может изменять и даже портить собственные таблицы стра¬ниц, но не те таблицы, которые принадлежат другим системам. Операционная система, запущенная поверх гипервизора, в обоих случаях называется гостевой операционной системой (guest operating system). В гипервизоре второго типа операционная си¬стема, которая запущена на оборудовании, называется основной операционной системой (host operating system) или хост-системой. Первым гипервизором второго типа на рынке x86 был VMware Workstation (Bugnion et al., 2012).

Рис. 84 Распо¬ложение гипер¬визоров: а — первого и б — второго типа

Многие функциональные возможности гипервизоров вто­рого типа, которые иногда называют гипервизорами, интегриро­ванными с хост-системой (hosted hypervisors), зависят от основ­ной операционной системы, например от Windows, Linux или OS X. При первом запуске они ведут себя как только что загруженный компьютер и рассчитывают найти DVD, USB-накопитель или ком­пакт-диск, содержащий операционную систему. Но в данном слу­чае приводом может быть виртуальное устройство. Например, об­раз может быть сохранен как ISO-файл на жестком диске хост-си­стемы, и гипервизор притворится, что чтение идет с надлежащего DVD-привода. Затем он устанавливает операционную систему на свой виртуальный диск (который в реальности опять является файлом Windows, Linux или OS X) путем запуска программы уста­новки, найденной на DVD. После установки гостевой операцион­ной системы на виртуальный диск ее можно будет загрузить и за­пустить.

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

Таблица 11. Примеры гипервизоров. Гипервизоры первого типа ра­ботают непосредственно на оборудовании, а гипервизоры второго типа ис­пользуют службы существующей основной операционной системы

Метод виртуализации Гипервизор
первого типа второго типа
Виртуализация без поддержки оборудова­ния ESX Server 1.0 VMware Workstation 1
Паравиртуализация Xen 1.0
Виртуализация с под­держкой оборудования vSphere, Xen, Hyper-V VMware Fusion, KVM, Parallels
Виртуализация на уровне процесса Wine

22.4. Технологии эффективной виртуализации

Способность к виртуализации и производительность явля­ются весьма важными вопросами, поэтому давайте их исследуем более подробно. Предположим, что в данный момент у нас есть ги­первизор первого типа, поддерживающий одну виртуальную ма­шину (рис. 85). Как и все другие гипервизоры первого типа, он ра­ботает непосредственно на оборудовании. Виртуальная машина запущена как пользовательский процесс в пользовательском ре­жиме, и как таковой ей нельзя выполнять служебные инструкции (в толковании Попека — Голдберга). Но на виртуальной машине ра­ботает гостевая операционная система, которая считает, что она запущена в режиме ядра (хотя, разумеется, это не так). Мы назовем это виртуальным режимом ядра (virtual kernel mode). На вирту­альной машине также запущены пользовательские процессы, кото­рые считают, что они выполняются в пользовательском режиме (и действительно находятся в этом режиме).

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

Что произойдет, когда гостевая операционная система (ко¬торая считает, что выполня ется в режиме ядра) выполняет ин¬струкцию, разрешенную, лишь когда центральный процессор ре¬ально работает в режиме ядра? Обычно на центральных процессо¬рах без VT-технологии выполнение инструкции завершается ошиб¬кой, и операционная система попадает в аварийную ситуацию. На центральных процессорах с VT-технологией при выполнении гос-тевой операционной системой служебной инструкции происходит системное прерывание с передачей управления гипервизору (см. рис. 85). Затем гипервизор может проверить инструкцию, чтобы определить, была она выдана гостевой операционной системой в виртуальной машине или же пользовательской программой на вир¬туальной машине. В первом случае он организует выполнение ин¬струкции, а в последнем — эмулирует то, что сделало бы настоя¬щее оборудование при встрече со служебной инструкцией, выпол¬няемой в пользовательском режиме.

Цена виртуализации

Можно было бы наивно полагать, что центральные процес¬соры с VT существенно превзойдут программные технологии, при¬бегающие к трансляции, но замеры дают неоднозначную картину (Adams and Agesen, 2006). Оказывается, подход, предусматриваю-щий передачу управления при системном прерывании и эмуляцию, используемый VT-оборудованием, приводит к выдаче большого количества системных прерываний, которые на современном обо¬рудовании обходятся очень дорого, поскольку разрушают кэши центрального процессора, TLB-буферы и таблицы предсказания переходов, находящиеся внутри центрального процессора. В отли¬чие от этого, когда служебные инструкции внутри выполняемого процесса заменяются вызовами процедур гипервизора, таких из¬держек от контекстного переключения не происходит. Как пока¬зали Адамс и Агесен, в зависимости от загруженности программ¬ный вариант порой превосходит аппаратный. Поэтому некоторые гипервизоры первого (и второго) типа во избежание падения произ¬водительности осуществляют двоичную трансляцию, даже если программа будет правильно выполняться и без нее.
При осуществлении двоичной трансляции сам оттранслиро¬ванный код по сравнению с исходным кодом может быть либо бо¬лее медленным, либо более быстрым в выполнении. Предположим, к примеру, что гостевая операционная система выключила аппа¬ратные прерывания, используя инструкцию CLI (clear interrupts — очистить прерывания). В зависимости от архитектуры эта инструк¬ция может выполняться очень медленно, занимая десятки тактов на конкретных центральных процессорах с глубокими конвейерами и выполнением инструкций вразброс. Теперь уже должно стать по¬нятно, что желание гостевой операционной системы заблокировать прерывания не означает, что гипервизор на самом деле должен их заблокировать и повлиять на работу всей машины. Соответственно гипервизор должен выключить их для гостевой операционной си¬стемы без реального выключения. Для этого он может отслеживать специальный флаг прерываний (Interrupt Flag (IF)) в структуре дан¬ных в виртуальном центральном процессоре, который им поддер-живается для каждой гостевой операционной системы (гарантируя тем самым, что виртуальная машина не получает никаких прерыва¬ний до тех пор, пока прерывания опять не будут включены). Каж¬дое появление CLI в гостевой операционной системе будет заме¬нено чем-нибудь вроде VirtualCPU.IF = 0, то есть весьма малоза¬тратной инструкцией перемещения, которая займет не более трех тактов. Следовательно, оттранслированный код будет выполнен быстрее. Тем не менее при использовании современного VT-обору¬дования аппаратное решение превосходит по эффективности про¬граммное.
В то же время если гостевая операционная система моди¬фицирует свои таблицы страниц, это обходится очень дорого. Про¬блема в том, что каждая гостевая операционная система на вирту¬альной машине полагает, что имеет дело со своей «собствен¬ной»машиной и может свободно отображать любую виртуальную страницу на любую физическую страницу в памяти. Но если одна виртуальная машина хочет использовать физическую страницу, которая уже используется другой виртуальной машиной (или ги¬первизором), кто-то должен ее выделить. Неудивительно, что возня с несколькими уровнями таблиц страниц обходится недешево.

22.5. Виртуализация памяти

До сих пор рассматривался вопрос о том, как виртуализиро¬вать центральный процессор. Но в компьютерной системе содер¬жится не только процессор. Имеются также память и устройства ввода-вывода. Они также должны быть виртуализированы. Давайте посмотрим, как это делается.
Практически все современные операционные системы под¬держивают виртуальную память, и в основном это выражается в отображении страниц в виртуальном адресном пространстве на страницы в физической памяти. Это отображение определяется многоуровневыми таблицами страниц. Обычно отображение при¬водится в действие установкой операционной системой управляю¬щего регистра в центральном процессоре, указывающего на таб¬лицу страниц верхнего уровня. Виртуализация сильно усложняет управление памятью. Фактически прежде чем все получилось, про¬изводителями оборудования были предприняты две попытки.
Предположим, к примеру, что виртуальная машина запу¬щена и установленная на ней гостевая операционная система ре¬шила отобразить свои виртуальные страницы 7, 4 и 3 на физические страницы 10, 11 и 12 соответственно. Она строит таблицы страниц, в которых содержится это отображение, и загружает аппаратный регистр для указания на таблицу страниц верхнего уровня. Эта ин¬струкция является служебной. На центральном процессоре с VT-технологией произойдет системное прерывание. С помощью дина¬мической трансляции будет выдан вызов процедуры гипервизора. На паравиртуализированной операционной системе будет сгенери¬рован гипервызов. Чтобы не усложнять задачу, давайте предполо¬жим, что системное прерывание привело к передаче управления в гипервизор первого типа, но задача точно та же для всех трех вари¬антов.
Что теперь делает гипервизор? Одно из решений заключа¬ется в фактическом выделении физических страниц 10, 11 и 12 этой виртуальной машине и настройке текущей таблицы страниц на отображение виртуальных страниц 7, 4 и 3 виртуальной машины на их использование. Пока все в порядке.
Теперь предположим, что вторая виртуальная машина за¬пускается, отображает свои виртуальные страницы 4, 5 и 6 на фи¬зические страницы 10, 11 и 12 и загружает регистр управления ука¬зателем на свою таблицу страниц. Гипервизор перехватывает си¬стемное прерывание, но что он должен делать? Он не может ис¬пользовать это отображение, потому что физические страницы 10, 11 и 12 уже используются. Он может найти свободные страницы, скажем, 20, 21 и 22, и воспользоваться ими, но сначала должен со¬здать новую таблицу страниц, отображающую виртуальные стра¬ницы 4, 5 и 6 виртуальной машины 2 на страницы 20, 21 и 22. Если будет запущена еще одна виртуальная машина, которая попытается использовать физические страницы 10, 11 и 12, придется создавать отображение и для них. В общем, для каждой виртуальной машины гипервизору нужно создавать теневую таблицу страниц (shadow page table), отображающую виртуальные страницы, используемые виртуальной машиной, на реальные страницы, предоставляемые гипервизором.
Хуже того, при каждом изменении гостевой операционной системой своих таблиц страниц гипервизор должен также вносить изменения в теневую таблицу страниц. Например, если гостевая операционная система заново отобразит виртуальную страницу 7 на то, что ей видится как физическая страница 200 (вместо страницы 10), гипервизор должен знать об этом изменении. Беда в том, что гостевая операционная система может вносить изменения в свои таблицы страниц просто путем записи в память. Служебные опера¬ции для этого не требуются, следовательно, гипервизор даже не знает об изменениях и, конечно же, не может обновить теневые таблицы страниц, используемые фактическим оборудованием.
Возможное (но не вполне изящное) решение заключается в том, чтобы гипервизор отслеживал, в какой странице в памяти гос¬тевой операционной системы содержится таблица страниц верхнего уровня. Эту информацию он может получить при первой попытке гостевой операционной системы загрузить аппаратный регистр, указывающий на эту таблицу, потому что эта инструкция является служебной и вызывает перехватываемое системное прерывание. В этот момент гипервизор может создать теневую таблицу страниц, а также сделать отметку, что таблица страниц верхнего уровня и те таблицы страниц, на которые она указывает, предназначены только для чтения. Последующие попытки со стороны гостевой операци-онной системы внести изменения в любую из этих таблиц вызовут ошибку отсутствия страницы, передав таким образом управление гипервизору, который может проанализировать поток инструкций, определяя, что именно пытается сделать гостевая операционная система, и соответствующим образом обновить теневые таблицы страниц. Решение не самое хорошее, но в принципе работоспособ¬ное.
Еще одно, также не очень изящное решение заключается в прямо противоположных действиях. В этом случае гипервизор про¬сто позволяет гостевой операционной системе добавить новое отображение к ее таблицам страниц, как она того пожелает. Как только это происходит, в теневых таблицах страниц ничего не ме¬няется. Фактически гипервизор даже ничего не знает об этом. Но как только гостевая операционная система пытается обратиться к любой из новых страниц, происходит ошибка отсутствия страницы и управление переходит к гипервизору. Он изучает таблицы стра¬ниц гостевой операционной системы с целью выявления отображе¬ния, которое ему следует добавить, и если таковое имеется, добав¬ляет его и заново выполняет инструкцию, на которой произошел сбой. А что происходит, когда гостевая операционная система уда¬ляет отображение из своих таблиц страниц? Понятно, что гиперви¬зор не вправе ожидать возникновения ошибки отсутствия стра¬ницы, потому что ее не будет. Удаление отображения из таблицы страниц случается в виде инструкции INVLPG (которая в действи¬тельности предназначена для аннулирования TLB-записи). Следо¬вательно, гипервизор перехватывает эту инструкцию и удаляет отображение и из теневой таблицы страниц. Это решение также не самое лучшее, но оно работает.
Обе технологии становятся причиной множества ошибок отсутствия страницы, а такие ошибки обходятся дорого. Обычно мы различаем «нормальные» ошибки отсутствия страницы, вызы¬ваемые гостевой программой, обращающейся к странице, выгру¬женной из оперативной памяти, и ошибки отсутствия страницы, связанные с обеспечением синхронизации теневых таблиц страниц и таблиц страниц гостевой операционной системы. Первые назы¬ваются ошибками отсутствия страницы, вызванными гостевой операционной системой (guest-induced page faults), и поскольку они перехватываются гипервизором, то должны быть снова вве¬дены в гостевую операционную систему. А это все обходится недешево. Последние называются ошибками отсутствия стра¬ницы, вызванными гипервизором (hypervisor-induced page faults), и обрабатываются путем обновления теневых таблиц страниц.
Ошибки отсутствия страницы всегда дорого обходятся, но особенно явно это проявляется в виртуализированной среде, по¬скольку они приводят к так называемым выходам из виртуальной машины (VM exit), то есть к ситуации, в которой управление воз-вращается гипервизору. Рассмотрим, что нужно сделать централь¬ному процессору для такого VM-выхода. Сначала он записывает причину VM-выхода, чтобы гипервизор знал, чтоделать. Он также записывает адрес гостевой инструкции, ставшей причиной вы¬хода.Затем осуществляется переключение контекста, которое включает в себя сохранение всех регистров. Затем он загружает состояние процессора гипервизора. И только потом гипервизор может приступить к обработке ошибки отсутствия страницы, начало которой было таким дорогостоящим. И когда наконец-то все будет сделано, процессор должен выполнить все шаги в обратном порядке. Процесс может занять десятки тысяч или даже более так¬тов. Неудивительно, что специалисты стараются извернуться так, чтобы сократить количество выходов.
В паравиртуализированной операционной системе ситуация другая. Здесь эта система в роли гостя знает, что когда она завер¬шит изменение таблицы страниц какого-нибудь процесса, ей следо¬вало бы информировать гипервизор. Следовательно, сначала она полностью изменяет таблицу страниц, а затем осуществляет вызов гипервизора, сообщая ему о новой таблице страниц. Таким обра¬зом, вместо ошибки защиты при каждом обновлении таблицы стра¬ниц осуществляется один гипервызов, когда все уже будет обнов¬лено, что, несомненно, более эффективный способ проделывать дела.

Аппаратная поддержка вложенных таблиц страниц

Высокая стоимость обработки теневых таблиц страниц за¬ставила разработчиков микросхем добавить аппаратную поддержку для вложенных таблиц страниц. Термин вложенные таблицы страниц (nested page tables) использовался компанией AMD. А Intel называет их расширенными таблицами страниц (Extended Page Tables (EPT)). Они похожи друг на друга и нацелены на уда¬ление основной части издержек путем полностью аппаратной до¬полнительной манипуляции с таблицами страниц, и все это без ка¬ких-либо системных прерываний. Интересно, что первое виртуали¬зационное расширение в процессорах x86 компании Intel вообще не включало поддержки виртуализации памяти. Хотя процессоры с VT-расширениями позволили избавиться от многих узких мест, связанных с виртуализацией центрального процессора, ковыряние в таблицах страниц обходилось дороже, чем когда-либо. У AMD и Intel ушло несколько лет на то, чтобы произвести оборудование для эффективной виртуализации памяти.
Вспомним, что даже без виртуализации операционная си¬стема поддерживает отображение виртуальных страниц на физиче¬скую страницу. Оборудование «обходит» таблицы страниц в поис¬ках физического адреса, соответствующего виртуальному адресу. Добавление дополнительных виртуальных машин приводит просто к добавлению дополнительного отображения. В качестве примера представим, что нам нужно преобразовать виртуальный адрес Linux-процесса на гипервизоре первого типа вроде Xen или VMware ESX-сервера в физический адрес. В добавление к госте¬вым виртуальным адресам (guest virtual addresses) у нас теперь есть гостевые физические адреса (guest physical addresses) и, соот¬ветственно, основные физические адреса (host physical addresses), которые иногда называют машинными физическими адресами (machine physical addresses). Мы видели, что без EPT гипервизор отвечал за поддержку теневых таблиц страниц явным образом. С использованием EPT гипервизор по-прежнему имеет дополнитель¬ный набор таблиц страниц, но теперь центральный процессор спо¬собен обрабатывать основную часть промежуточных уровней также и в оборудовании. В нашем примере сначала оборудование обходит обычные таблицы страниц, чтобы преобразовать гостевой вирту¬альный адрес в гостевой физический адрес, точно так же, как он делал бы это без виртуализации. Разница в том, что он также обхо¬дит расширенные (или вложенные) таблицы страниц, чтобы найти основной физический адрес без вмешательства программного обес¬печения, и ему нужно делать это при каждом обращении к госте¬вому физическому адресу. Преобразование показано на рис. 86.

Рис. 86. Расширенные (вложенные) таблицы страниц, включая обращение к каждому уровню гостевых таблиц страниц, подвергаются обходу при каждом обращении к гостевой физической странице

К сожалению, оборудованию может понадобиться более ча¬стый обход вложенных таблиц страниц, чем вы можете себе пред¬ставить. Давайте предположим, что гостевой виртуальный адрес не был кэширован и требует полного поиска в таблицах страниц. Каж¬дый уровень в страничной иерархии подвергается поиску во вло¬женных таблицах страниц. Иными словами, количество ссылок на память возрастает в соответствии с глубиной иерархии в квадра¬тичной зависимости. Но даже при этом EPT существенно сокра¬щает количество VM-выходов. Гипервизорам больше не нужно по¬мечать гостевую таблицу страниц предназначенной только для чте¬ния, и они могут устраниться от обработки теневых таблиц стра¬ниц. Что еще лучше, при переключении виртуальных машин гипер¬визор просто изменяет это отображение точно так же, как операци¬онная система изменяет отображение при переключении процессов.

Возвращение памяти

Когда все эти виртуальные машины находятся на одном и том же физическом оборудовании, у всех есть собственные стра¬ницы памяти и все они считают себя царями горы, все превосходно, но до тех пор, пока не понадобится вернуть память назад. Особую важность это приобретает в случае перерасхода (overcommitment) памяти, когда гипервизор симулирует, что общий объем памяти для всех виртуальных машин в целом превышает общий объем физиче¬ской памяти, имеющийся в системе. В общем, это неплохая затея, поскольку она позволяет гипервизору одновременно разрешать за¬пуск все большего и большего количества полноценных виртуаль¬ных машин. Например, на машине с 32 Гбайт памяти можно запу¬стить три виртуальные машины, каждая из которых будет полагать, что у нее 16 Гбайт памяти. Разумеется, столько машин с такой па¬мятью там не поместится. Но, возможно, трем машинам в действи¬тельности одновременно не понадобится максимальный объем фи¬зической памяти. Или, возможно, они будут совместно использо¬вать страницы, имеющие одно и то же содержимое (например, ядро Linux) в различных виртуальных машинах и при этом будет прово¬диться оптимизация, известная как дедупликация (deduplication). В таком случае три виртуальные машины используют в общем объем памяти, в три раза меньший 16 Гбайт. Дедупликация будет рас¬смотрена чуть позже, а сейчас главное заключается в том, что ка¬жущееся на данный момент хорошее распределение при изменении рабочей нагрузки может оказаться плохим. Вполне возможно, вир¬туальной машине 1 понадобится больше памяти, в то время как виртуальная машина 2 могла бы работать с меньшим количеством страниц. В таком случае было бы хорошо, чтобы гипервизор смог передать ресурсы от одной виртуальной машины к другой и прине¬сти пользу всей системе. Вопрос в том, как можно безопасно за¬брать страницы памяти, если эта память уже отдана виртуальной машине?
В принципе, можно воспользоваться еще одним уровнем страничной организации. В случае нехватки памяти гипервизор выгрузит несколько страниц виртуальных машин точно так же, как операционная система может выгрузить несколько страниц прило¬жения. Недостаток такого подхода заключается в том, что это дол¬жен сделать гипервизор, но он не имеет понятия о том, какие из страниц представляют для гостевой операционной системы наибольшую ценность. Это очень похоже на выгрузку неподходя¬щих страниц. Если для выгрузки будут выбраны верные страницы (то есть те, которые также были бы выбраны гостевой операцион¬ной системой), то впереди будет ждать еще немало проблем. Пред-положим, к примеру, что гипервизор выгрузил страницу P. Чуть позже гостевая операционная система также решает выгрузить эту страницу на диск. К сожалению, у гипервизора и у гостевой опера¬ционной системы разные пространства свопинга. Иными словами, гипервизор должен сначала вернуть содержимое первой страницы обратно в память только для того, чтобы посмотреть, как гостевая операционная система тут же снова запишет ее на диск. Получается не очень-то эффективно.
Обычное решение заключается в использовании приема, из¬вестного как раздувание (ballooning), при котором небольшой раз¬дуваемый модуль загружается в каждую виртуальную машину в качестве псевдодрайвера устройства, общающегося с гипервизо¬ром. Раздуваемый модуль может вздуваться по запросу гиперви¬зора путем выделения все большего и большего количества невы¬гружаемых страниц и сдуваться путем освобождения этих страниц. При вздутии такого модуля дефицит памяти в гостевой операцион¬ной системе растет, и она будет реагировать выгрузкой тех страниц, которые считает наименее ценными, что, собственно, нам и было нужно. И наоборот, как только такой модуль сдувается, у гостевой системы появляется больше памяти для распределения. Иными словами, гипервизор наводит операционную систему на принятие трудных для нее решений. В политике такой прием называется пе¬рекладыванием ответственности.

22.6 Виртуализация ввода-вывода

После рассмотрения виртуализации и памяти настал черед рассмотрения виртуализации ввода-вывода. Обычно гостевая опе¬рационная система при запуске начинает исследовать оборудование с целью определения типов подключенных устройств ввода-вы-вода. Эти исследования будут вызывать системные прерывания с передачей управления гипервизору. А что должен сделать гиперви¬зор? Он может послать в ответ отчет о тех дисках, принтерах и т. д., которые действительно входят в состав оборудования. Затем госте-вая операционная система загружает драйверы для этих устройств и пытается ими воспользоваться. Когда драйверы устройств пыта¬ются осуществить настоящий ввод-вывод, они считываются в аппа¬ратные регистры устройства и ведут в них запись. Инструкции для выполнения этих действий являются служебными и приводят к пе¬редаче управления гипервизору, который затем может по мере надобности копировать необходимые значения в аппаратные реги¬стры и обратно.
Но здесь у нас также имеется проблема. Каждая гостевая система может полагать, что она владеет целым разделом диска, и виртуальных машин может быть намного больше (несколько со¬тен), чем существующих разделов диска. Обычное решение для ги¬первизора заключается в создании файла или области на реальном диске для каждого физического диска виртуальной машины. По¬скольку гостевая операционная система пытается управлять дис¬ком, имеющимся у реального оборудования (и понятным гиперви¬зору), гипервизор может преобразовать номер блока, к которому идет обращение, в смещение в файле или в области диска, исполь¬зуемого в качестве накопителя, и выполнить ввод-вывод.
Возможно также, что диск, используемый гостевой опера¬ционной системой, будет отличаться от реального диска. Например, если реальный диск относится к дискам нового, высокопроизводи¬тельного типа (или является RAID-массивом) с новым интерфей¬сом, гипервизор может информировать гостевую операционную систему, что у него имеется обычный старый IDE-диск, и позволить гостевой операционной системе установить драйвер IDE-диска. Ко¬гда этот драйвер выдает команды управления IDE-диском, гиперви¬зор преобразует их в команды управления новым диском. Эта стра¬тегия может использоваться для обновления оборудования без из¬менения программного обеспечения. Фактически такая способность виртуальных машин переназначать аппаратные устройства была одной из причин приобретения популярности VM/370: компании хотели покупать новое и более быстродействующее оборудование, но не хотели вносить изменения в свое программное обеспечение. Технология виртуальных машин предоставляет такую возмож¬ность.
Еще одна интересная тенденция, связанная с вводом-выво¬дом, заключается в том, что гипервизор может сыграть роль вирту¬ального коммутатора. В этом случае у каждой виртуальной ма¬шины имеется MAC-адрес и гипервизор переключает фреймы от одной виртуальной машины к другой точно так же, как это делал бы Ethernet-коммутатор. Виртуальные коммутаторы имеют ряд преимуществ. Например, их очень просто переконфигурировать. Также можно расширить коммутатор, придав ему дополнительные функциональные возможности, например, для обеспечения допол¬нительной безопасности.

Блоки управления памятью при вводе-выводе

Еще одной проблемой, которая так или иначе должна быть решена, является применение прямого доступа к памяти, DMA, ко¬торый использует абсолютные адреса памяти. Наверное, для вас не будет неожиданностью, что гипервизор должен здесь вмешаться и переназначить адреса до запуска DMA. Но на оборудовании уже есть блок управления памятью при вводе-выводе (I/O MMU), ко¬торый виртуализирует ввод-вывод таким же образом, как MMU виртуализирует память. I/O MMU существует в различных видах и формах для множества архитектур процессоров. Даже если мы ограничимся семейством x86, то у Intel и у AMD есть немного от¬личающиеся друг от друга технологии. Но замысел при этом ис¬пользуется один и тот же. Это оборудование устраняет проблему DMA.
Как и обычные MMU-блоки, I/O MMU использует таблицы страниц для отображения адреса памяти, которым желает восполь¬зоваться устройство (адрес устройства), на физический адрес. В виртуальной среде гипервизор может настроить таблицы страниц таким образом, что устройство, выполняющее DMA, не станет за¬бираться в память, не принадлежащую виртуальной машине, от имени которой оно работает.
I/O MMU-блоки при работе с устройством в виртуализиро¬ванном мире предлагают различные преимущества. Прямая пере¬дача устройства (device pass through) позволяет физическому устройству быть напрямую назначенным конкретной виртуальной машине. В общем, было бы идеально, если бы адресное простран¬ство устройства совпадало с гостевым физическим адресным про¬странством. Но это вряд ли может произойти, пока у вас не будет I/O MMU. Блок управления памятью позволяет адресам пройти яв¬ное переназначение, и тогда как устройство, так и виртуальная ма¬шина будут пребывать в абсолютном неведении о производимом в аппаратных недрах преобразовании адресов.
Изоляция устройств (device isolation) гарантирует, что устройство, назначенное виртуальной машине, может напрямую обращаться к этой виртуальной машине, не подвергая опасности неприкосновенность других гостевых операционных систем. Иными словами, I/O MMU предотвращает неконтролируемый DMA-трафик точно так же, как обычный MMU предотвращает не¬контролируемое обращение к памяти из процессов. В обоих слу¬чаях обращение к неотображенным страницам влечет за собой сбой.
Но, к сожалению, на DMA и адресах история ввода-вывода не заканчивается. Для полноты картины нам нужно также виртуа¬лизировать прерывания, чтобы прерывания, выданные устрой¬ством, попадали на нужную виртуальную машину, имея правиль¬ный номер. В связи с этим современные блоки I/O MMU поддержи¬вают переназначение прерываний (interrupt remapping). Предполо¬жим, устройство отправило сообщение, оповещающее о прерыва¬нии с номером 1. Сначала это сообщение попадает в I/O MMU, чтобы преобразоваться в новое сообщение, предназначенное для центрального процессора, на котором в данный момент работает виртуальная машина, да еще и с номером вектора, ожидаемого этой виртуальной машиной (например, 66), будет использована таблица переназначения прерываний.
И наконец, наличие I/O MMU также помогает 32-разрядным устройствам иметь доступ к памяти, превышающей порог в 4 Гбайт. Обычно такие устройства (например, DMA) не могут обра¬щаться к адресам за пределами 4 Гбайт, но I/O MMU может легко переназначить нижние адреса устройства на любые адреса в физи¬ческом более обширном адресном пространстве.

Домены устройств

Еще один подход к обработке ввода-вывода заключается в выделении одной из виртуальных машин для запуска стандартной операционной системы и воспроизведении на ней всех вызовов ввода-вывода других виртуальных машин. Этот подход проявляет свои лучшие качества при использовании паравиртуализации, при этом команда, выдаваемая гипервизору, фактически сообщает о том, что нужно гостевой операционной системе (например, считать с диска 1 блок 1403), и заменяет собой серию команд, записывае¬мых в регистры устройства, которая заставляет гипервизор высту¬пать в роли Шерлока Холмса и выяснять, попытка какого именно действия предпринимается. Xen использует этот подход для ввода-вывода с использованием осуществляющей этот ввод-вывод вирту¬альной машины, которая получает имя нулевого домена (domain 0).
Виртуализация ввода-вывода относится к области, в кото¬рой гипервизоры второго типа получают практическое преимуще¬ство над гипервизорами первого типа: основная операционная си¬стема содержит драйверы устройств для всего разнообразия устройств ввода-вывода, подключенных к компьютеру. Когда при¬кладная программа пытается обратиться к неизвестному устройству ввода-вывода, оттранслированный код, чтобы выполнить свою ра¬боту, может вызвать существующий драйвер устройства. При нали¬чии гипервизора первого типа он должен либо содержать сам драй¬вер, либо вызывать драйвер в нулевом домене, что похоже на дей¬ствия основной операционной системы. По мере становления тех¬нологии виртуальных машин оборудование, скорее всего, позволит прикладным программам обращаться к оборудованию напрямую безопасным образом, а это будет означать, что драйверы устройств смогут быть непосредственно связаны с кодом приложения или по¬мещены в отдельные серверы, работающие в пользовательском ре¬жиме (как в MINIX3), устраняя, таким образом, проблему.

Виртуализация ввода-вывода в отдельно взятом физическом устройстве

Непосредственное назначение устройства виртуальной ма¬шине плохо масштабируется. Этим способом с четырьмя физиче¬скими сетями можно поддерживать не более четырех виртуальных машин. Для восьми виртуальных машин нужны восемь сетевых карт, а при запуске 128 виртуальных машин ваш компьютер в спле¬тении всех эти сетевых кабелей вряд ли отыщется.
Организовать программным способом совместное исполь¬зование устройств несколькими гипервизорами возможно, но зача¬стую не оптимально, потому что уровень эмуляции (или домен устройства) вклинивается между оборудованием, драйверами и гостевыми операционными системами. Эмулируемое устройство зачастую не реализует все расширенные функции, поддерживаемые оборудованием. В идеале технология виртуализации должна была бы предложить эквивалент устройства, переходя без каких-либо издержек от отдельно взятого устройства к нескольким гипервизо¬рам. Виртуализация отдельно взятого устройства, вводящая каж¬дую виртуальную машину в заблуждение, что у нее имеется ис¬ключительный доступ к его собственному устройству, существенно облегчается, если оборудование проделает эту виртуализацию за вас. На PCIe такое действие называется виртуализацией ввода-вы¬вода в отдельно взятом физическом устройстве.
Виртуализация ввода-вывода в отдельно взятом физиче¬ском устройстве (Single root I/O virtualization (SR-IOV)) позволяет обойти привлечение гипервизора к обмену данными между драйве¬ром и устройством. Устройства, поддерживающие SR-IOV, предо-ставляют независимое пространство памяти, прерывания и DMA-потоки каждой использующей их виртуальной машине (Intel, 2011). Устройства показываются как несколько отдельных устройств, каждое из которых может быть сконфигурировано отдельной вир-туальной машиной. Например, у каждого устройства будут отдель¬ный регистр базового адреса и отдельное адресное пространство. Виртуальная машина отображает одну из этих областей памяти (используемую, к примеру, для конфигурации устройства) на свое адресное пространство.
SR-IOV предоставляет доступ к устройству в двух раз¬новидностях: физических функциях (Physical Functions (PF)) и виртуальных функциях (Virtual Functions (VF)). Физиче¬ские функции являются полноценными PCIe-функциями и позволяют устройству конфигурироваться любым способом, какой администратор сочтет нужным. Гостевым операцион¬ным системам физические функции недоступны. Виртуаль¬ные функции представляют собой облегченные PCIe-функ¬ции, не предлагающие подобных вариантов конфигурирова¬ния. Они идеально подходят для виртуальных машин. В це¬лом технология SR-IOV позволяет устройствам виртуализи¬роваться в сотнях (или около того) виртуальных функций, ко¬торые создают у виртуальных машин уверенность в том, что они являются единственными владельцами устройства. Например, если взять сетевой интерфейс с технологией SR-IOV, виртуальная машина может управлять своей виртуаль¬ной сетевой картой, как будто она является физической. К тому же у многих современных сетевых карт имеются от¬дельные (кольцевые) буферы для отправки и получения дан¬ных, выделенные этим виртуальным машинам. Например, се¬тевые карты Intel серии I350 имеют восемь очередей на от¬правку и восемь очередей на прием.

22.7. Виртуальные устройства

Виртуальные машины предлагают интересное решение проблемы, которая уже давно беспокоит пользователей, особенно тех, кто пользуется программными средствами с открытым кодом: как устанавливать новые прикладные программы. Проблема в том, что многие приложения зависят от множества других приложений и библиотек, которые, в свою очередь, зависят от целого ряда дру¬гих программных пакетов, и т. д. Более того, могут существовать зависимости от конкретных версий компиляторов, языков написа¬ния сценариев и операционных систем.
Теперь, когда появилась возможность использования вирту¬альных машин, разработчики программного обеспечения могут по¬дойти к конструированию виртуальной машины с особой тщатель¬ностью, загрузив в нее требуемую операционную систему, компи-ляторы, библиотеки и код приложения, и зафиксировать весь гото¬вый к запуску блок. Этот образ виртуальной машины затем может быть помещен на компакт-диск или на веб-сайт, чтобы клиенты могли его установить или загрузить. Такой подход означает, что в зависимостях должен разбираться только разработчик программ¬ного обеспечения. Клиенты получают полный работоспособный пакет, совершенно независимый от той операционной системы, под которой они работают, и от того, какие другие программы, пакеты и библиотеки они установили. Такие «упакованные» виртуальные машины часто называют виртуальными устройствами (virtual appliances). К примеру, у компании Amazon есть облако EC2, где находится множество упакованных виртуальных устройств, до¬ступных клиентам компании и предлагаемых в качестве удобных программных служб (Software as a Service — программное обеспе¬чение в виде службы).

22.8 Виртуальные машины на мультиядерных центральных процессорах

Комбинация виртуальных машин и мультиядерных цен¬тральных процессоров создает совершенно новый мир, в котором количество доступных центральных процессоров может регулиро¬ваться программным способом. Если есть, скажем, четыре ядра и на каждом из них, к примеру, может быть запущено до восьми вирту¬альных машин, один центральный процессор (настольного компью¬тера) может быть, если нужно, сконфигурирован как мультиком¬пьютер с 32 узлами. Но он также может иметь и меньше централь¬ных процессоров в зависимости от программного обеспечения. Ни¬когда ранее разработчику прикладных программ не предоставля¬лась возможность сначала выбрать, сколько центральных процес¬соров ему нужно, а затем соответствующим образом написать про-грамму. Это, несомненно, новый этап в вычислениях.
Кроме того, виртуальные машины могут совместно исполь¬зовать память. В случае возможности такого использования типич¬ным примером может послужить отдельный сервер, на котором запущены сразу несколько экземпляров одной и той же операцион¬ной системы. Нужно лишь отобразить физические страницы на ад¬ресные пространства нескольких виртуальных машин. Совместное использование уже доступно в решениях дедупликации, которая является именно тем, о чем вы подумали, — технологией, позволя-ющей избежать двойного хранения одних и тех же данных. Она до¬вольно часто встречается в системах хранения данных, но теперь также появляется и в виртуализации. В Disco она была известна как прямое общее использование страниц (transparent page sharing), требующее модификации гостевой операционной системы, а в VMware — как общее использование страниц на основе содер¬жимого (contentbased page sharing), не требующее никаких моди-фикаций. В общем, технология базируется на сканировании памяти каждой виртуальной машины хоста и хэшировании страниц па¬мяти. Если какие-то страницы выдают одинаковый хэш, система должна сначала проверить их реальную идентичность и при нали¬чии таковой дедуплицировать эти страницы, создавая одну стра¬ницу с данным содержимым и две ссылки на нее. Поскольку гипер¬визор управляет вложенными (или теневыми) таблицами страниц, это отображение не вызывает вопросов. Разумеется, когда любая из гостевых операционных систем модифицирует общую страницу, другой виртуальной машине (или машинам) эти изменения будут не видны. Секрет заключается в использовании режима копирова¬ния при записи (copy on write), таким образом, модифицированная страница будет закрытой страницей той системы, которая в нее вела запись.
Если виртуальные машины могут совместно использовать память, тот компьютер, на котором они установлены, становится виртуальным мультипроцессором. Поскольку все ядра в мульти¬ядерном кристалле совместно используют одну и ту же оператив¬ную память, один кристалл с четырьмя ядрами может без труда быть сконфигурирован как мультипроцессор с 32 узлами или, если это нужно, как мультикомпьютер с 32 узлами.
Комбинация мультиядерных кристаллов, виртуальных ма¬шин, гипервизора и микроядер собирается радикально изменить представление людей о компьютерных системах. Имеющееся в настоящее время программное обеспечение не может реализовать замысел определения программным путем общей картины количе¬ства необходимых центральных процессоров, их желаемой принад¬лежности к мультикомпьютеру или мультипроцессору, а также ми¬нимально необходимого количества ядер того или иного типа. Ре¬шение этих вопросов — за будущим программным обеспечением.

22.9. Облака

В резком взлете облачных вычислений технология виртуа¬лизации играет решающую роль. Существует множество облаков. Некоторые из них относятся к публичным и доступны любому, кто согласен платить за использование ресурсов, другие же являются закрытыми облаками организаций. Также разные облака предла¬гают разные услуги. Некоторые из них дают своим пользователям доступ к физическому оборудованию, но большинство виртуализи¬руют свою среду. Некоторые предлагают просто машины, как вир¬туальные, так и физические, и больше ничего, а некоторые — гото¬вое к использованию и способное к объединению весьма интерес¬ными способами программное обеспечение или платформы, облег¬чающие своим пользователям разработку новых служб. Постав¬щики облачных услуг обычно предлагают различные категории ресурсов, таких как «большие машины», «малые машины» и т. д.
При всех разговорах об облаках, похоже, мало кто с уверен¬ностью может сказать, что они на самом деле собой представляют. Национальный институт стандартов и технологий (США), являясь источником, к которому всегда можно прибегнуть, перечислил пять основных характеристик:

  1. Самообслуживание по требованию (On-demand self-ser¬vice). Пользователи должны иметь возможность получать ресурсы автоматически, без человеческого участия.
  2. Широкий доступ по сети (Broad network access). Все эти ресурсы должны быть доступны по сети посредством стандартных механизмов, чтобы ими могли воспользоваться гетерогенные устройства.
  3. Объединение ресурсов в пул (Resource pooling). Компью¬терные ресурсы, принадлежащие поставщику, должны быть объ¬единены в пул для обслуживания нескольких пользователей с воз¬можностью динамического назначения и освобождения ресурсов. Пользователи обычно не знают точного местонахождения «своих» ресурсов и даже того, в какой стране они расположены.
  4. Быстродействующая эластичность (Rapid elasticity). Должна быть предоставлена возможность эластичного получения и освобождения ресурсов, может быть, даже в автоматическом ре¬жиме, чтобы происходило незамедлительное масштабирование в соответствии с потребностями пользователей.
  5. Учтенные услуги (Measured service). Поставщик должен вести учет потребленных ресурсов тем способом, который соответ¬ствует типу заранее оговоренных облачных услуг.

Облака в качестве услуги

Рассмотрим облака, сконцентрировавшись на виртуализа¬ции и операционных системах. Особенно подробно будут рассмот¬рены те облака, которые предлагают непосредственный доступ к виртуальной машине, которой пользователь может воспользоваться любым подходящим для него способом. Следовательно, одно и то же облако может запускать разные операционные системы, воз¬можно, на одном и том же оборудовании. В понятиях облака это называется инфраструктурой в качестве услуги (Infrastructure As A Service (IAAS)) в противоположность платформе в качестве услуги (Platform As A Service (PAAS)), когда предоставляется среда, вклю¬чающая такие компоненты, как конкретная операционная система, база данных, веб-сервер и т. д., программного обеспечения в каче¬стве услуги (Software As A Service (SAAS)), когда предоставляется доступ к конкретному программному продукту, например Microsoft Office 365 или Google Apps, и многим другим типам облаков в ка¬честве услуг. Одним из примеров IAAS-облака является Amazon EC2, основанное на гипервизоре Xen и насчитывающее сотни тысяч физических машин. При условии наличия средств можно получить сколько угодно вычислительных мощностей.
Облака могут изменять способ производимых компаниями вычислений. В целом, объединение компьютерных ресурсов в не¬большом количестве мест (с удобным расположением возле элек¬тростанций и там, где дешевле можно будет охлаждать оборудова-ние) позволяет сэкономить средства при масштабировании. При¬влечение внешних ресурсов к обработке информации означает, что вам не нужно особо волноваться об управлении вашей IT-инфра¬структурой, резервном копировании, обслуживании, амортизации, масштабировании, надежности, производительности и, возможно, безопасности. Все это делается в одном месте, и, если предполо¬жить высокую компетентность поставщика облачных услуг, дела¬ется качественно. В связи с этим можно подумать, что теперь IT- менеджеры стали намного счастливее, чем 10 лет назад. Но наряду с исчезновением этих тревог появились новые. Можно ли действи¬тельно доверять своему поставщику облачных услуг безопасное хранение ваших конфиденциальных данных? Будет ли конкурент при работе на той же инфраструктуре иметь возможность выводить информацию, которую желательно сохранять в закрытом виде? Ка¬кой закон (или законы) применим к вашим данным (например, если поставщик облачных услуг находится в США, то распространяется ли на ваши данные «Патриотический акт», даже если ваша компа¬ния находится в Европе)? Если все ваши данные хранятся в облаке X, сможете ли вы извлечь их оттуда или же вы будете привязаны к этому облаку и его поставщику навсегда (это называется привязкой к поставщику (vendor lock-in)?

Миграция виртуальных машин

Технология виртуализации позволяет не только создавать IAAS-облака для одновременного запуска на одном и том же обо¬рудовании нескольких разных операционных систем, но и искусно управлять ими. О возможности выделения большего количества ресурсов, чем их фактически имеется, особенно в сочетании с де¬дупликацией, мы уже говорили. Теперь давайте рассмотрим другие проблемы управления: что, если машине понадобится обслужива¬ние (или даже замена), а на ней запущено множество важных ма¬шин? Наверное, клиенты не обрадуются, если их системы утратят работоспособность по причине того, что поставщик облачных услуг хочет заменить дисковый привод.
Гипервизоры разобщают виртуальную машину и физиче¬ское оборудование. Иными словами, для виртуальной машины на самом деле неважно, на какой машине она работает, той или этой. Следовательно, можно просто остановить все виртуальные машины и снова запустить их на совершенно новой машине. Но в результате этого получится весьма существенный простой. Задача состоит в том, чтобы переместить виртуальную машину с оборудования, нуждающегося в обслуживании, на новую машину вообще без остановки.
Немного более приемлемым подходом может быть не оста¬новка виртуальной машины, а ее приостановка. Во время паузы мы как можно быстрее копируем страницы памяти, используемые вир¬туальной машиной, на новое оборудование, проводим корректное конфигурирование в новом гипервизоре, а затем возобновляем ра¬боту виртуальной машины. Кроме памяти требуется перенести подключения к устройству хранения данных и к сети, но если ма¬шины рядом, это можно сделать относительно быстро. Для начала можно сделать файловую систему на основе сети (подобно сетевой файловой системе — NFS), чтобы было все равно, на каком обору¬довании работает ваша виртуальная машина, на серверной стойке 1 или 3. Также на новое место может быть просто переключен IP-ад¬рес. И все-таки придется приостановить работу машины на вполне заметный период времени. Возможно, на это уйдет меньше вре¬мени, чем вы ожидали, но все же его невозможно будет не заме¬тить.
Вместо этого современные решения виртуализации предла¬гают так называемую живую миграцию (live migration). Иными словами, перемещение виртуальной машины происходит без пре¬кращения ее работы. Например, в этих решениях используется тех-нология, подобная миграции памяти с предварительным копиро¬ванием (pre-copy memory migration). Это означает, что страницы памяти копируются в то время, когда машина все еще обрабатывает запросы. Большинство страниц памяти не подвергается интенсив¬ной записи, следовательно, их копирование безопасно. Следует помнить, что виртуальная машина все еще работает, поэтому стра¬ница может быть изменена после того, как уже скопирована. При изменении страниц памяти мы должны гарантировать копирование в место назначения самой последней их версии, поэтому помечаем такие страницы как измененные. Позже они будут скопированы заново. Когда скопировано большинство страниц памяти, мы оста¬емся с небольшим количеством измененных страниц. Теперь дела¬ется очень короткая пауза на копирование оставшихся страниц, и работа виртуальной машины возобновляется на новом месте. Хотя без паузы здесь все же не обходится, она настолько коротка, что это обычно не оказывает никакого влияния на приложения. Ситуация, когда простой не заметен, называется незаметной живой мигра¬цией (seamless live migration).

Оставить комментарий

avatar
  Подписаться  
Уведомление о