Современный мир IT — это мир облачных технологий и виртуализации. Это мир, в котором виртуализация уже стала такой же обычной вещью, как HTTP-сервер и окно графического интерфейса. Она используется для всего, начиная от запуска серверов и заканчивая тестированием приложений. И кажется странным, что мы до сих пор не имеем специальной ОС для виртуальных машин. Или все-таки имеем?
Введение
Говоря о виртуальных машинах и окружениях, мы всегда подразумеваем два объекта взаимодействия: это хост-система со встроенным гипервизором и гостевая система, которая запускается в виртуальном окружении и использует ресурсы и драйверы хост-системы для своей работы. На рынке присутствует большое количество специальных серверных редакций ОС для развертывания облаков, однако практически не существует аналогичных решений для запуска внутри виртуальной машины. Обычно мы просто скачиваем образы все тех же стандартных дистрибутивов Linux, Windows и FreeBSD, запускаем их в виртуалке, а дальше поднимаем сервер либо выполняем другую работу.
Такое положение вещей кажется вполне нормальным и рациональным, пока мы не задумываемся о полном разделении сервисов между разными виртуальными машинами. Не так давно я писал о запуске сервера LAMP в конфигурации с полным разделением всех компонентов между разными виртуальными машинами: веб-сервер в одном виртуальном окружении, MySQL — в другом, Memcached — в третьем и так далее. Для простоты в каждом виртуальном окружении я использовал копию установки Debian с разной конфигурацией и установленными пакетами, однако, если вдуматься, это очень сложная и неэффективная конфигурация.
В случае запуска каждого сервиса в обособленной виртуальной машине возможности полноценной ОС оказываются избыточны: развитая файловая система не нужна, разделение времени в большинстве случаев тоже, многопользовательский режим не нужен, разделение процессов между режимом ядра и пользовательским бессмысленно, драйверы ни к чему, множество внутренних прослоек и дополнительных компонентов не нужны. Все это лишь замедляет ОС, делает ее слишком сложной и уязвимой.
Здесь скорее подошел бы этакий MS-DOS XXI века, очень простая однозадачная система, которая в силу своей примитивности сможет исполнять код приложения максимально быстро, расходуя при этом минимум памяти. И такая ОС есть — это OSv, созданная исключительно для работы в виртуальных окружениях.
OSv
OSv была написана с нуля специально для работы в условиях виртуальных окружений и существенно отличается от традиционных операционных систем общего назначения. В целом в ОС реализовано четыре простых идеи:
- Одна память на всех. В OSv нет разделения памяти как между ядром и приложениями, так и между самими приложениями. Вся оперативная память — это одна большая страница, доступная для записи, чтения и исполнения всем, включая пользовательские процессы и процессы ядра. И те и другие здесь всего лишь нити, а понятия «режим ядра» и «пользовательский режим» вообще не существуют.
- Максимально простой дизайн. Являясь операционной системой для виртуальных окружений, OSv не включает в себя драйверов и многочисленных прослоек, предназначенных для упрощения переноса ОС на другие архитектуры.
- Автоматическая конфигурация. В системе нет ни одного конфигурационного файла. После запуска она просто работает.
- Интегрированная Java-машина. OSv ориентирована в первую очередь на запуск Java-приложений, но может быть использована и для запуска серверов на Си (требуется портирование), а также на таких языках, как Ruby (jRuby), Python (Jython) и JavaScript (Rhino, Nashorn).
В сущности, OSv — это даже не операционная система в обычном понимании, а своего рода прослойка для запуска софта поверх гипервизора, некий фреймворк с собственным высокоуровневым API. Причем фреймворк очень тонкий и лишенный многих усложнений традиционных ОС. В частности, память тут одна на всех, а «кольца защиты» процессора не задействованы. Поэтому система не нуждается в переключении контекста и сброса кеша, когда переходит от выполнения кода процесса к коду ядра, и существенно экономит на этом процессорные ресурсы. Та же идея позволяет приложениям обращаться к любым внутренним структурам и функциям ядра с целью более эффективного использования ресурсов ОС.
![OSv против систем общего назначения](https://xakep.ru/wp-content/uploads/2014/08/osv-vs-any.jpg)
![](https://xakep.ru/wp-content/uploads/2013/12/cover-3-215x280.png)
Хакер #179. Интернет вещей — новый вектор атак
OSv предназначена для запуска одного приложения, поэтому не имеет проблем с безопасностью даже несмотря на общую для всех память и отсутствие идеи прав пользователей. Она становится как бы оболочкой для запуска приложения, поэтому взлом или ошибки приложения, которые автоматически приведут к взлому или падению всей ОС, для нее не является проблемой. Система стартует за полсекунды, поэтому в случае чего достаточно сделать откат и перезапустить окружение.
Если речь идет о запуске масштабных Java-серверов, обслуживающих множество приложений, то здесь за защиту памяти отвечает сама виртуальная машина Java, так же как это сделано, например, в jOS или Inferno: на уровне железа одна память на всех, но виртуальная машина (Java) реализует собственную программную систему защиты.
OSv не нужна?
Опытный админ наверняка скажет, что OSv не нужна, так как она создает слишком много нагромождений (ОС -> гипервизор -> специальная ОС для гипервизора -> Java-машина -> приложение) и является усложнением идей OpenVZ и LXC, которые ко всему прочему еще и предоставляют полноценное Linux-окружение, вместо POSIX-совместимого огрызка. Однако у разработчиков ОС на это есть простой ответ.
OSv, по их мнению (я говорил, что она написана ведущими разработчиками гипервизора KVM Ави Кивити и Дор Лаор?), — это такой ответ на сложившуюся ситуацию и ничего больше. Это ОС для Amazon или ему подобных PaaS-сервисов, которые работают под управлением Xen и KVM и вообще не предоставляют окружения на базе виртуализации уровня ОС. Кроме того, OpenVZ и LXC гораздо более сложны, чем сама OSv и гипервизор, будь то KVM и Xen, а также более уязвимы для взлома.
OSv интегрирована с Java-машиной, поэтому в ней эффективно реализованы некоторые внутренние механизмы последней, включая переписанный сборщик мусора, использующий в своей работе возможности современных процессоров (в частности, механизм трекинга записей в память), и эффективная система управления памятью, которая не требует лишнего копирования буферов между ядром и приложением.
Кроме Java, в OSv реализован совместимый со стандартом POSIX API, который позволяет легко портировать для нее большинство UNIX-софта, написанного без использования специфичных для Linux или FreeBSD интерфейсов. От никсов системе также досталась файловая система ZFS (исходники взяты из FreeBSD, как и сетевой стек), ее выбор обусловлен ориентацией на приложения вроде Tomcat, Jboss и Hadoop, которым по определению необходим мощный виртуальный сервер с большим количеством дисковой памяти и функциональностью, которую дает развитая ФС.
![Стандартная облачная конфигурация](https://xakep.ru/wp-content/uploads/2014/08/pie.jpg)
В общем и целом OSv — это фреймворк или прослойка со встроенной файловой системой ZFS, виртуальной машиной Java, POSIX API и сетевым стеком, назначение которой — запуск приложения с максимальной изоляцией, обеспечиваемой гипервизором.
![Облачная конфигурация с использованием OSv](https://xakep.ru/wp-content/uploads/2014/08/pie2.jpg)
Пробуем
OSv — это открытый софт, распространяемый под лицензией BSD, поэтому его можно форкнуть из GitHub-репозитория и собрать самому либо воспользоваться специально подготовленным демо-образом, который можно запустить под управлением KVM. Кроме того, авторы подготовили инструкцию по запуску OSv в облаке Амазона.
На момент написания этих строк для загрузки была доступна pre-alpha версия OSv 0.02, запакованная в стандартный для QEMU/KVM qcow2-образ размером чуть меньше 200 Мб. Помимо самой операционной системы, образ также содержал OpenJDK 1.7.0 (в сущности, он и занимал большую часть образа), шелл CRaSH (www.crashub.org), написанный на том же Java, SSH-сервер, несколько тестовых приложений, а также зачатки удаленной веб-консоли, написанной на JavaScript. Какой-либо надежды испытать все это для запуска серьезного софта не было, но попробовать запустить ОС и поиграться с шеллом стоило.
Для этого был скачан тот самый образ и заранее подготовлен виртуальный мост:
$ sudo brctl addbr virbr0
$ sudo brctl addbr eth0
$ sudo ifconfig virbr0 up
Далее был написан скрипт, который должен был автоматически подключать виртуальное окружение к мосту.
#!/bin/sh
echo SCRIPT, $1
brctl addif virbr0 $1
ifconfig $1 up
Ну и наконец, скрипт для запуска самой ОС:
#!/bin/sh
sudo qemu-system-x86_64 -vnc :1 \
-gdb tcp::1234,server,nowait -m 2G -smp 2 \
-chardev stdio,mux=on,id=stdio \
-mon chardev=stdio,mode=readline,default \
-device isa-serial,chardev=stdio \
-drive file=osv-v0.02.qcow2,if=virtio,cache=unsafe \
-netdev tap,id=hn0,script=qemu-ifup.sh,vhost=on \
-device virtio-net-pci,netdev=hn0,id=nic1 \
-enable-kvm -cpu host,+x2apic
По сути, это аналог скрипта из исходников OSv, который создает виртуальное окружение с 2 Гб памяти, двумя виртуальными процессорами и консолью. Дальше оставалось только запустить скрипт, и спустя одну секунду появился шелл.
Это тот самый CRaSH. Какими-то серьезными особенностями, кроме возможности скриптинга на Clojure, он не отличается и включает в себя несколько стандартных UNIX-команд (cat, cd, ls, pwd, sleep, sort) и специфичных Java-инструментов. Содержимое файловой системы также очень скудно: каталоги /dev (реализация devfs из FreeBSD), /etc, /tools, /usr/lib (минимальный набор библиотек, необходимых для запуска Java-машины) и /java, содержащий Java-компоненты и стандартную библиотеку классов. Сама машина Java располагается в разделяемой библиотеке /java.so (которую лучше назвать модулем ядра, хотя границы между этими понятиями в OSv стерты).
В комплекте есть веб-сервер и удаленная консоль управления, которые можно запустить так (порт 8080):
> java -jar /usr/mgmt/web-1.0.0.jar app prod
С его помощью можно выполнять мониторинг ОС, а также загружать Java-приложения. Кроме него, для удаленного управления OSv можно использовать REST API либо тот же shell, доступный по SSH. Никакого механизма обновления не предусмотрено, сами разработчики заявляют, что в будущем для этого достаточно будет просто загрузить новый образ OSv, однако, как будет выполняться сохранение существующей конфигурации, пока непонятно.
![Работа мастера на сервисе Amazon EC2](https://xakep.ru/wp-content/uploads/2014/08/amazon.jpg)
Производительность
Само собой, верить утверждениям разработчиков о производительности ОС на основе одних только данных об архитектуре нельзя. Даже такие вполне очевидные в плане увеличения производительности идеи, как «работа приложений в режиме ядра», так или иначе требуют подтверждения. С другой стороны, провести замеры производительности ОС, которая не имеет ни документации, ни даже законченного вида, очень проблематично. Поэтому придется опять же обратиться к данным самих разработчиков, которые провели бенчмарки своей же ОС (ну да, ну да).
В качестве инструментов они использовали SPECjvm2008 для тестирования Java-приложений и memaslap для тестирования производительности Memcached 1.4.15 в стандартной конфигурации. В качестве хоста выступал Intel Haswell i7-4770 с 16 Гб оперативной памяти и 64-битной Fedora 19 с установленным QEMU 1.4.2 и ядром Linux 3.10.5. В сравнении участвовали OSv версии 0.01 и 64-битная Fedora 18 с ядром Linux 3.9.9. Обе работали внутри одноядерной виртуальной машины с 3 Гб памяти и OpenJDK 1.7.0. Измерялась сетевая производительность и производительность ввода-вывода, а вот cpu intensive тесты проведены не были то ли в силу их провальности, то ли по причине молодости OSv, над оптимизацией которой пока практически не работали (это официальная причина).
Ознакомиться с результатами тестов можно на странице или в приведенной в статье таблице. Здесь изложу лишь выводы. Суммарный прирост производительности Java-приложений составил меньше двух процентов, что сами разработчики объяснили использованием стандартной OpenJDK, так как оптимизированная для OSv Java-машина еще не была готова. А вот тест Memcached благодаря модели «одна память на всех», которая позволяет избежать лишних копирований буферов и переключений контекста, получился более наглядным. Memcached, запущенный в OSv, смог обслужить 286 550 запросов в секунду на канале 10 Гб, тогда как Linux-версия только 205 199 (разница составляет ~40%).
В общем-то, прирост налицо, однако было бы интересно посмотреть на результат работы Memcached, скомпилированного в виде Linux-модуля например. Другими словами, воссоздать условия запуска работы OSv внутри другой ОС.
![SPECjvm2008: OSv против Linux](https://xakep.ru/wp-content/uploads/2014/08/bench.jpg)
NetBSD и Xen
Показательно, что практически одновременно с анонсом OSv разработчики NetBSD представили собственную идею подобной простой операционной системы для виртуальных окружений (goo.gl/wQcvdn). В отличие от программистов OSv, они не стали создавать систему с нуля, а воспользовались своими более ранними наработками, в частности идеей так называемого RUMP-ядра, не привязанного к железу.
Напомню, что несколько лет назад ребятам из проекта NetBSD, одержимым идеей создать самую портируемую ОС всех времен, пришла в голову мысль сделать на основе ядра NetBSD этакое мини-ядро, которое можно было бы запускать как обычный процесс в любой POSIX-совместимой ОС. Они взяли существующее ядро, вырезали из него драйверы, файловые системы, сетевой стек, механизм разделения памяти, планировщик процессов и вообще все, что только можно, а затем сделали так, чтобы ядро можно было запускать как обычный пользовательский процесс. В результате получилось минимальное ядро NetBSD, которое предоставляло API для драйверов, POSIX API и прочее (то есть лишь высокоуровневые абстракции, этакий слой совместимости).
Разработка получила имя RUMP (Runnable Userspace Meta-Programs — «работающие в пространстве пользователя метапрограммы») и позволила реализовать разные интересные вещи, такие, например, как запуск драйверов в пространстве пользователя (RUMP с интегрированным драйвером), запуск частей NetBSD в Linux (оформленное в виде Linux-модуля RUMP-ядро плюс нужные компоненты) или порт NetBSD в браузер (переписанное на JavaScript RUMP-ядро + автоматически конвертированные в тот же JS драйвера и другие компоненты ОС).
![Что такое RUMP-ядро](https://xakep.ru/wp-content/uploads/2014/08/rump.jpg)
В рамках данной статьи RUMP-ядро интересно тем, что с его помощью разработчикам удалось реализовать схожую с OSv идею в виде побочного эффекта. Портировав RUMP-ядро на гипервизор Xen, они получили этакую мини-ОС, способную запускать NetBSD-приложения в пространстве ядра, но при этом лишенную всего остального балласта. По сути, такой же фреймворк с POSIX API, как и OSv, но гораздо более гибкий в плане возможности формирования ядер с разной «начинкой».
![](/wp-content/themes/engine/img/info-icon.jpg)
INFO
На момент публикации статьи доступны порты приложений Memcached, Redis, nginx и MongoDB.
Как и стандартное ядро NetBSD, RUMP-ядро можно скомпилировать, включив в него нужные компоненты, которые будут необходимы приложению. Нужен сетевой стек — правим конфиг и получаем его, не нужна файловая система — ОK, обойдемся tmpfs... В качестве примера разработчики подготовили образы с включенными в ядро библиотеками libc и libm для запуска стандартного POSIX-софта, а также образ с интегрированным интерпретатором Lua. Так же в ядро можно интегрировать виртуальную машину Java или интерпретатор Python, получив что-то вроде «Python поверх Xen/KVM».
Пока все эти разработки носят экспериментальный характер и не предназначены для повседневного использования, а в качестве гипервизора поддерживается только Xen, ну или ядро Linux, или браузер, если, конечно, тебя не смущает именование их гипервизорами.
Песчинки истории
Фактически идеи, которые легли в основу OSv, родились задолго до начала эры облачных вычислений. Впервые они были реализованы еще в шестидесятых годах в мейнфрейме IBM System/360 — он был снабжен программным гипервизором, поверх которого могли работать множественные инстанции простой однозадачной операционной системы CMS (изначально эта связка называлась CP/CMS, а в настоящее время носит имя z/VM).
Еще один пример более ранней реализации идей OSv — это Maxine Virtual Machine, а точнее, редакция этой Java-машины для запуска поверх железа.
Выводы
OSv и «RUMP поверх Xen» во многом олицетворяют естественное развитие технологий, которое идет по кочкам, ямам и технологическому мусору, накопившемуся за последние 50 лет развития IT. Это не самые красивые технологии, и, если мыслить, отбросив весь балласт давно отживших, но продолжающих занимать важное место идей, мы могли бы придумать нечто гораздо более правильное и современное, что-то вроде z/VM или пресловутой JavaOS. Но с действительностью приходится считаться, и в таких условиях проекты вроде OSv являются правильным шагом вперед.