Разве не было бы круто использовать операционную систему как обычную зависимость приложения, которую вы можете просто 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 может (и, вероятно, собирается) измениться. Также не готов к производственному использованию.
О, если вы хотите взломать какие-то довольно низкоуровневые вещи, мы приветствуем ваши взносы :)