Разве не было бы круто использовать операционную систему как обычную зависимость приложения, которую вы можете просто require ()?

Как это возможно?

Если вы следите за новостями об облачных вычислениях и операционных системах, возможно, вы слышали о библиотечных операционных системах или уникальных ядрах. Да, звучит как единороги, но на самом деле это особые операционные системы, упакованные в библиотеки, от которых могут зависеть приложения. Это в значительной степени позволяет объединить ОС прямо в приложение и создать автономный образ, который можно развернуть в облаке.

На эту тему есть отличная статья, в которой подробно описываются одноядерные ядра, а также реализация MirageOS (Анил Мадхавапедди и
Дэвид Дж. Скотт).

Почему?

Идея состоит в том, что вместо установки полнофункциональной ОС, такой как Ubuntu, и последующего развертывания серверных приложений, которые должны работать поверх нее, можно было бы скомпилировать чрезвычайно маленький и специализированный образ, включающий весь код приложения и только минимальный набор компонентов ОС, необходимых для данной облачной службы. Например, нет необходимости включать всевозможные драйверы для различного физического оборудования, компиляторов и основных утилит или даже оболочки.

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

А поскольку весь код, включая ОС, объединен в образ, можно избежать случайных поломок на производственных серверах из-за изменений внешних зависимостей (например, обновлений библиотек ОС).

Существует довольно много библиотечных ОС или реализаций unikernel, каждая из которых поддерживает какую-либо среду приложений. Некоторые системы предоставляют полный UNIX-подобный API и могут запускать любые скомпилированные приложения, аналогичные универсальным ОС. Но есть такие, которые ориентированы на конкретную языковую среду. Например, MirageOS основан на среде выполнения OCaml и языке.

Специфичные для языка системы интересны тем, что им не обязательно поддерживать весь интерфейс POSIX, потоки и вытесняющую многозадачность, их можно оптимизировать для своего языка и предоставлять пользователям простой в использовании языковой API. Например, MirageOS полностью управляется событиями и не реализует потоки.

ОС JavaScript?

runtime.js - это операционная система библиотеки или реализация unikernel на основе виртуальной машины JavaScript. В чем-то он похож на MirageOS. runtime.js ориентирован на предоставление платформы для языка JavaScript, и в будущем планируется интегрировать WebAssembly (WASM). Он построен на движке JavaScript V8, который используется в Chrome и Node.js.

Система управляется событиями и не имеет процессов или потоков, виртуальная машина JavaScript работает в режиме ядра ЦП с полным доступом к оборудованию (в большинстве случаев виртуализированным поставщиком облачных услуг). Он разработан для облака, и QEMU / KVM - единственный поддерживаемый гипервизор на данный момент.

Насколько легко им пользоваться?

Простейший пример приложения «Hello World» выглядит так:

Чтобы связать его и запустить локально в QEMU, требуется несколько команд. QEMU - эмулятор и виртуализатор машины, аналогичный VirtualBox. runtimeify - это инструмент, основанный на Browserify, который создает образы RAM-диска из кода JavaScript. runtime-qemu - это оболочка для QEMU, которая также может загружать и запускать предварительно созданные двоичные файлы runtime.js.

Если все в порядке, он должен запустить QEMU и выдать следующий результат:

Потрясающие! Мы создали наш первый образ unikernel, который на самом деле представляет собой два файла: образ виртуального диска initrd с кодом JavaScript и предварительно скомпилированный двоичный файл runtime.js. При необходимости два полученных файла можно объединить в один ISO-образ. Его размер меньше 10 мегабайт (двигатель V8 довольно большой, он составляет не менее 8 мегабайт).

HTTP-сервер?

Облачная программа Hello World не очень интересна и полезна, давайте построим веб-сервер. Я собираюсь использовать портативную HTTP-библиотеку JavaScript eshttp (примечание: она находится на ранней стадии разработки и может работать нестабильно):

Затем установите зависимости, скомпилируйте и запустите:

npm install runtimejs eshttp
runtimeify ./runtime-http-server.js -o initrd
runtime-qemu ./initrd

Теперь должна быть возможность свернуть наш сервер, работающий в QEMU (runtime-qemu по умолчанию настраивает переадресацию порта для порта 9000):

$ curl localhost:9000
Hello World!

Довольно круто! У нас есть очень маленький и автономный образ ОС веб-сервера, который мы можем запускать локально или размещать где-нибудь в облаке. Он также неизменен и не требует установки или настройки. В результате сервер не использует диск и полностью не имеет состояния между перезагрузками. И он загружается менее чем за секунду под KVM!

Это также решает проблему локальной разработки, потому что вы можете запустить тот же образ локально в QEMU, что и в производственной среде. Образ также включает в себя упакованную версию ОС, поэтому возможные патчи runtime.js можно очень легко протестировать локально!

Дайте мне знать, если вы думаете, что это интересная идея. Вы бы использовали что-то подобное для своих облачных сервисов? Напишите мне в Твиттере @iefserge или #runtimejs. Это мой первый пост, но в будущем я хотел бы больше писать в блоге о runtime.js!

Примеры клонирования на GitHub

Привет, мир: https://github.com/runtimejs/helloworld

Веб-сервер: https://github.com/runtimejs/example-web-server

Ссылки и информация

runtime.js - это проект с открытым исходным кодом, размещенный на GitHub https://github.com/runtimejs/runtime

Некоторые поддерживаемые документы API доступны в Wiki https://github.com/runtimejs/runtime/wiki/API-docs

Базовая библиотека runtime.js на npm https://www.npmjs.com/package/runtimejs

Проект находится в разработке, и API может (и, вероятно, собирается) измениться. Также не готов к производственному использованию.

О, если вы хотите взломать какие-то довольно низкоуровневые вещи, мы приветствуем ваши взносы :)