⚠️ Обращайте внимание на даты.
Этот блог больше не ведётся с 17 января 2023, и на тот момент с написания этой страницы (14.10.2014) прошло 8 лет.
Железо всё ширится, растёт и крепнет. Диапазон доступного на рынке железа нынче широк настолько, что стало возможно на одном компьютере запускать сразу несколько систем. На первый взгляд, это форменное безумие, но напрягшись, можно придумать несколько интересных способов использовать это. Скажем, вы можете разрабатывать что-то для сетей, и собрать маленькую сеть на одном своём компьютере, “для опытов”. И я сейчас говорю не о поднятии клиентов и серверов на разных портах, нет, это скучно… мы поговорим о виртуальных машинах. И не только.
О чём вообще речь?
Что вообще такое виртуальная машина? Как обычно, буду выражаться простым языком – это программа (а точнее, целый пакет), который создаёт и запускает у вас на компьютере машину, резервирующую часть аппаратных ресурсов для поддержки “нового компьютера”. То есть, если вам нужен ещё один компьютер, вы можете запустить его прямо на том, что у вас уже есть, создав для него иллюзию того, что он работает на собственном железе (хотя на самом деле он будет использовать кусочек вашего имеющегося компьютера). Достаточно новые компьютеры даже способны при этом не тормозить. Но тут речь уже, конечно, не о т. н. “игровых системах”, для виртуальных машин требуется немного другого типа производительность.
Но зачем?
Отличный вопрос!.. Хм… У вас ни разу не возникало желания:
- Обзавестись хотя бы старинным (по мощи железа) компьютером, чтобы проверить, насколько печально ваше поделие работает в ограниченных условиях?
- Запустить какую-то “левую” программу, о которой вы не знаете ничего, но не хотите жертвовать собственной системой (в худшем случае)?
- Пощупать другую операционную систему, не покидая той, в которой вы сейчас?
Для всех этих случаев виртуальные машины отлично выполняют свою задачу. Но есть и другие, менее очевидные способы применения.
Рабочая машинка
К примеру, гипотетически (возможно, и фактически), вы разработчик. И ваша рабочая машина довольно сложно устроена – в ней стоит много программ, библиотек, средств сборки, конфигураций и настроенная среда разработки. И случается напасть – вам необходимо срочно перейти на другой компьютер. Если такое случается изредка, то обычно не слишком проблемно развернуть эту же среду на другом компьютере. Часть файлов скопировать, часть воссоздать, а часть и вовсе обновить (быть может, пришло время обновить операционку?). Но если такое может понадобиться делать часто (у вас несколько компьютеров в разных местах?) разумно задуматься о том, как пользоваться одной и той же (не такой же, а той же) средой с любой точки. Хороший выход из такой ситуации – виртуальная машина.
Вопрос только в том, где её разместить. Можно таскать на собственной флэшке… но так вы скоро останетесь без флэшки, они не приспособлены для запуска с них ОС, быстро от этого изнашиваются и помирают. Не всё потеряно, вы можете сделать это на внешнем жёстком диске (которые гораздо лучше переносят такие нагрузки) и таскать его с собой. А ещё можно разместить машинку где-то на сервере, и заходить на неё с помощью программ удалённого доступа, вроде VNC, RDP, SSH (мало ли?) или TeamViewer (самый простой и сомнительный вариант). Тогда для доступа к своей среде вам понадобится только интернет… и не факт, что вы этого хотите.
Рабочее окружение
С учётом вышесказанного, можно увидеть ещё один способ применения виртуальных машин – среды, заточенные под конкретные проекты. Где настроен полный программный пакет для работы над каким-то продуктом. Зачем? Зависимости: используемые библиотеки, средства разработки, сборки и поддержки. Они часто бывают разных версий: какие-то старше, какие-то новее, и разные версии частенько требуют разных. Разбираться с ними на одной системе… можно, но довольно часто это существенно тратит время.
Это поняли, к примеру, разработчики Laravel, подготовив специальную виртуальную машину, где есть почти всё, что может понадобиться для запуска мощного приложения на этом фреймворке. Достаточно свежий PHP, его ускоренная реализация HHVM, базы данных, вебсерверы и ещё сколько-то интересностей. Это всё предназначено для того, чтобы не пришлось ставить весь этот комплект на собственную ОС, что существенно захламит и переменные среды, и реестр, и файловую систему, и некоторые сетевые порты… Вспомним также о том, что машина будет работать на разных ОС со всем, что в ней установлено, поскольку у виртуальной машины ОС своя. Удобно, верно?
Производительность
…сильно зависит от того, чем вы собрались нагрузить виртуальную машину, и насколько новый у вас компьютер. Скажем, процессору неплохо бы поддерживать VT-x (если Intel) или AMD-V (AMD, очевидно). Если у вас есть это – скорее всего, остальное тоже. Если VirtualBox (вы же его щупаете?) сказал, что не нашёл этих фич – это не означает, что у вас их нет. Они могут быть выключены в BIOS. Для тех, кто шарит: также возможно, что их захватил другой гипервизор. К примеру, Hyper-V, который мне довелось попробовать. Увидев этот факт, я просто снёс Hyper-V. Безжалостно.
Оперативной памяти хорошо бы иметь побольше. 3 Гб у меня на ноутбуке было вполне достаточно для работы в хост-системе при одной запущенной виртуальной машине (ей был отведён 1 Гб). И оставался запас. Но две таких уже смогут существенно замедлить систему, особенно если вы хорошо нагрузили хост. Хост… ах, чёрт.
На минуточку отвлечёмся на термины, а то я уже вовсю ими пользуюсь. Машины и ОС в области виртуализации делятся на хост (host
) и гостей (guests
). Гость – виртуальная машина. Хост – то, на чём она запущена. Программа, которая позволяет так делать, зовётся гипервизор. Кажется, из самого важного это всё.
С чего начать?
Создать её, если ваша система достаточно новая, легко: вы скачиваете некий программный пакет (я предпочитаю VirtualBox
), запускаете мастер создания новой машины, выделяете ей виртуальный жёсткий диск (у вас он будет выглядеть, как файл, но изнутри – как диск), сколько-то процессорных ядер и кусок оперативной памяти (если ваша система это умеет). И вам достанется новенький компьютер с абсолютно чистым жёстким диском. Вам останется только поставить внутрь операционную систему (можно с iso
-образа, подключив его в виртуальный дисковод), после чего машину можно использовать для собственных нужд.
…не только виртуальные машины?
Виртуализация – вообще довольно обширная тема. Описанное выше предназначено для эмуляции целого компьютера путём имитации железок, из которых он состоит. Но это не всегда требуется, если это явно не указано в задаче. Что же ещё бывает? Скажем, в случаях, когда нужно поднять под одной ОС ещё одну систему такого же типа (скажем, Linux под Linux), могут существовать… хитрости. Их, впрочем, необходимо искать в каждом конкретном случае.
Знакомьтесь, Docker. Использует ядро операционной системы, чтобы создать… контейнер… слишком много терминов! Но что поделать, Docker не является гипервизором в полном смысле этого слова, а “системы” в нём не являются полноценными виртуальными машинами. Чем же Docker является… “суперклеем” для целого ряда фич, которые уже существуют и известны.
Ядро Linux способно поддерживать в некотором отдельном своём кусочке (“пространстве имён”) отдельную работающую систему, управляемую с основной системы. Почему речь не идёт о гипервизорах? Потому что используется то же самое железо, никакой эмуляции и связанных с этим потерь производительности. Используется тот же самый диск (не виртуальный, хотя это спорно), то же сетевое соединение (можно, необязательно), та же оперативная память (она не резервируется на весь доступный объём). Давайте посмотрим на практический пример.
Есть такой бесплатный сервер для системы контроля версий git
, называется GitLab. Что вам понадобится на вашей системе, чтобы его запустить?
- Ruby и большой комплект библиотек для него, в котором могут быть вариации:
- Rails
- Thin (вебсервер)
- Весь список
- Хранилище Redis
- База данных PostgreSQL (или MySQL?)
Вдобавок, вам понадобится настроить для него пользователей, сервер, указать порт… посмотрите любое руководство по установке. Мельком. Чтобы качественно развернуть его, требуется время и неплохой экземпляр головы.
Чтобы развернуть GitLab (в момент написания статьи), Docker сделает примерно следующее, если вы предварительно для него ничего не подготовили:
- Скачает облегчённый образ Ubuntu (только набор программ первой необходимости, поэтому сильно облегчённый)
- Дополнит образ килограммом системных библиотек, новым Ruby и файлами GitLab
- Поищет на предмет сервера БД, ничего не найдёт и начнёт запускать отдельный контейнер с PostgreSQL
- Поищет Redis, не найдёт, запустит отдельный контейнер с ним
- Запустится
Но… это плохо. А установка “по-нормальному” уже ненамного сложнее обычной установки на свежую ОС. Но всё равно лучше по той причине, что на одной машине это можно будет провернуть несколько раз.
В чём дело? В том, что контейнеры надо разделять. Когда речь идёт о стороннем приложении, вам неплохо бы его иногда обновлять. И при обновлении сервера базы данных вы… потеряете всю информацию в ней! …если не указали при запуске контейнера, что файлы с данными нужно хранить в некой папке хоста, а не прямо в контейнере. Эта штука развилась в специальную разновидность контейнеров — дисковые. Дисковый контейнер не запускается, он состоит только из “дискового тома”, который прицепляется к нужным вам контейнерам. Он может быть легко приклеен к другому контейнеру или к новой версии старого (удобство!).
Как это всё работает внутри? Красиво! Странно, но красиво. Контейнеры запускаются из образов. Файловые системы образов состоят из отдельных слоёв. Чтобы составить всю файловую систему, необходимы все её слои, каждый в одном экземпляре. Интересно то, что наличие в двух образах одинаковых слоёв не требует наличия двух копий этих слоёв. Эта слоистая структура выстроена на AuFS, аналогичная штука используется на live-флэшках с линуксом: есть основной образ дистрибутива, а ваши изменения пишутся в отдельный слой поверх него, никак с основным образом не взаимодействуя. Идею развили дальше! Остальные компоненты не столь элегантно-интересны: LinuX Containers для разделения систем, cgroups
для разделения ресурсов хоста; в них идейной ценности не настолько много, но без них проект бы был неосуществим.
Есть ли аналоги образов и алгоритмов их сборки для виртуальных машин и возможны ли вообще? Возможны и есть.
Vagrant
“Бродяга”, готовый существовать в любых условиях. В сущности, это надстройка над гипервизором (по умолчанию – опять Virtualbox
), просто лучше приспособлена для автоматического разворачивания того, что требуется. Из нескольких файлов настроек собирается виртуальная машина. Где бы вы её ни собирали, вы всегда получите одну и ту же виртуальную среду. Разве что со временем используемые из сети файлы могут измениться на более свежие (это хорошо) или пропасть (это плохо, но случается обычно с очень старыми образами).
Для чего это надо? Посмотрите выше – мы получаем заведомо известную среду, совместимую с тем, что необходимо использовать. Я выше упоминал Laravel и их Homestead – вот пример среды, собираемой Vagrant.
Что в “Бродяге” хорошего? Это виртуальная машина. Изолированная эмуляцией железа, и потому ограниченная ресурсами намертво, вашему компьютеру она ничего слишком плохого сделать не может. Что плохого? То же, что и во всех виртуальных машинах: эмуляция железа ест ресурсы. 100%-ной скорости, которую вы видите на хост-системе, в виртуальной среде вы можете не получить, а оперативной памяти всегда будет зарезервирован максимум, доступный машине, чтобы она имела к ней монопольный доступ (по задумке, всё же хост по-прежнему всегда прав).
Полная изоляция?
Может ли вложенная система отличить, работает ли она в настоящем окружении, или виртуальном? Может, если против этого не предприняты меры. Зачем это сделано? Чтобы виртуальными машинами было удобнее пользоваться. У этого есть, конечно, и неприятные последствия.
Если вы уже попробовали работать с виртуальными машинами, то знаете, что обычно она запускается в собственном окне, в котором эмулируется дисплей, а также в которое передаются все события вашей мыши и клавиатуры (кроме одной клавиши, обычно правого Ctrl, чтобы вы не остались без управления). И вы, наверное, заметили, что гостевая система ведёт себя с вашими устройствами ввода не совсем… обычно. Она пытается сотрудничать с хостом. Интеграция указателя мыши, например, позволяет гостевой ОС улавливать, когда указатель мыши на хосте проносится над её окном, и сдвигать на соответствующее место свой указатель мыши. Я излагаю несколько упрощённо, это всего лишь пример.
Реализовано это при помощи “гипервызовов”. Странный термин? Разверну его: это “системные вызовы к гипервизору”. Аналог: системные вызовы в пределах одной ОС и её процессов; здесь это гипервизор с виртуальными машинами.
У этого есть и проблемы, конечно. Один из способов применения виртуализации — обнаружение вредоносного ПО. Запускаем в ненужной системе, смотрим на последствия. Так вот, продвинутые варианты способны обнаруживать гипервизоры и отладчики над системой, что сводит на нет всю идею. Скучные варианты впрочем, это поймает.
Пробуйте!