Статьи

Инструмент развертывания приложений с открытым исходным кодом JVM: Capsule

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

В то время как приложения JVM требуют очень мало от своей среды — только JVM и ядро ​​- что удивительно, хорошего универсального инструмента / механизма развертывания для приложений JVM до сих пор не было. Полноценные JAR-файлы не всегда работают, и даже когда они работают, им могут потребоваться скрипты для конкретной платформы. В последнее время некоторые использовали Docker для развертывания приложений Java, но Docker плохо подходит для этой задачи: одна из его основных целей — обеспечить общую переносимость приложений — то, что уже есть в приложениях JVM, — и поэтому требует загрузки, развертывания и управления Разнообразие образов ОС и репозиториев. Как инструмент, не зависящий от времени выполнения, Docker также не может использовать сильные стороны JVM.

Сегодня, после года взросления, мы рады объявить о выпуске Capsule 1.0 , простого, надежного и гибкого инструмента развертывания для приложений JVM. Capsule учитывает уникальные преимущества и требования приложений JVM, и мы считаем, что это одновременно и самый простой, и самый мощный способ развертывания приложения JVM, будь то настольное приложение, микросервис или сложное веб-приложение. Capsule хорошо работает не только для приложений Java, но и для всех языков JVM, от Jruby, Jython и Groovy, до Kotlin, Clojure и Scala, до Frege и OCaml-Java. Если вы пишете программы для JVM, попробуйте Capsule.

Один из способов думать о капсуле — это толстый JAR на стероидах (который также позволяет использовать нативные библиотеки и никогда не мешать вашим зависимостям) и декларативный скрипт запуска, объединенный в один; еще один, чтобы увидеть, что это как время развертывания аналог вашего инструмента сборки. Так же, как инструмент сборки управляет вашей сборкой, Capsule управляет всем, от сборки до запуска вашего приложения.

Мы разработали капсулу с учетом следующих принципов:

  • Упаковка должна быть небольшой, портативной и удобной . Capsule упаковывает любое приложение JVM — независимо от того, насколько оно сложное, независимо от того, из каких файлов JAR оно состоит, или исходных файлов на языках сценариев, или нативных библиотек — как один исполняемый файл JAR, называемый капсулой, который работает на всех платформах. Капсула может напрямую содержать все зависимости приложения или просто объявлять некоторые или все из них, которые будут загружены при запуске. Это толстый JAR, который всегда работает. Если вы предпочитаете, сами капсулы также могут быть помещены в репозитории Maven и загружены оттуда при запуске.
  • Установка должна оказывать минимальное влияние на хост-систему и при необходимости поддерживать обновления. Капсула устанавливается сама при первом запуске, создавая файлы во временном каталоге, которые могут быть удалены пользователем в любое время без каких-либо негативных последствий. Капсула также может при желании искать обновления — либо для приложения, либо для его зависимостей — и загружать их при запуске. Эти зависимости — это могут быть языковые среды выполнения или веб-контейнеры — могут быть общими для других капсул.
    • Запуск должен быть детерминированным, но гибким, возможно безопасным и необязательно ограниченным. Запуск капсулы не требует запуска сценариев. Капсула ищет запрошенную версию JVM, устанавливает classpath и необходимые агенты и устанавливает флаги JVM. Капсулы также могут создавать свой собственный контейнер при запуске — для ограничения использования ресурсов или для использования хорошо известных портов без вмешательства других программ — и поскольку приложения JVM могут работать в непривилегированных контейнерах, эти контейнеры безопасны. В качестве альтернативы, безопасность может быть обеспечена через собственный механизм безопасности JVM. Кроме того, для капсул требуется только ядро ​​и JVM — даже не оболочка — поэтому они могут работать на микроядрах JVM, таких как OSv. Все эти функции полностью программируемы и компонуются с помощью капсулкомпоненты, которые настраивают поведение капсулы.
    • Не изобретайте новые инструменты и новые стандарты, когда уже будут существующие. Капсула написана на Java и может быть расширена на Java. Он уважает экосистему JVM, не изобретает колесо и использует существующие инструменты и стандарты. Капсула упакована в исполняемый JAR и хранит все метаданные в виде простых атрибутов JAR-манифеста; при необходимости он загружается — полностью или частично — из репозиториев Maven и создается с использованием популярных инструментов сборки JVM, таких как Maven, Gradle или Leiningen. Сама капсула является простой зависимостью Maven, как и все плагины инструментов сборки. Нет необходимости устанавливать новые инструменты.

    Капсула Магия с Каплетами

    Capsule предоставляет все эти функции, оставаясь при этом простым, с помощью caplets , которые являются модулями, которые настраивают поведение капсулы. Каплеты могут быть встроены в капсулу или упакованы отдельно и использоваться в командной строке для переноса и изменения поведения существующей капсулы.

    Первым каплетом Capsule был Maven , который позволяет вам объявлять некоторые или все зависимости вашего приложения в атрибутах манифеста, а не встраивать их в JAR-капсулу. Хотя это может быть необязательным для многих приложений, вот два примера его использования, которые демонстрируют потенциал Capsule.

    Первый пример простой Hello World сервлет. При сборке он создает стандартный файл WAR, который можно развернуть в любом контейнере сервлета. При ближайшем рассмотрении выясняется, что WAR немного особенная. Его содержимое:

    247     META-INF/MANIFEST.MF
    1124    WEB-INF/classes/co/paralleluniverse/examples/HelloWorldServlet.class
    653     WEB-INF/web.xml
    161596  Capsule.class
    1467463 capsule-maven-1.0.jar
    

    Как вы можете видеть, WAR содержит Capsuleкласс, который означает его капсулу, а также встроенный JAR, capsule-maven-1.0.jarкоторый является Maven caplet. Манифест JAR выглядит так:

    Manifest-Version: 1.0
    Main-Class: Capsule
    Premain-Class: Capsule
    Caplets: co.paralleluniverse:capsule-maven:1.0
    Application: org.eclipse.jetty:jetty-runner:9.3.3.v20150827
    Allow-Snapshots: true
    Min-Java-Version: 1.7.0
    Args: $CAPSULE_JAR
    

    Если вместо развертывания WAR в контейнере сервлета вы выполняете его напрямую java -jar build/libs/capsule-runnable-war.war(или даже просто, ./capsule-runnable-war.warесли капсула сделана «действительно исполняемой» — см. Инструкции в пользовательской документации), она автоматически загрузит Jetty и использует ее для запуска сервлет. Артефакт Jetty будет кэшироваться и передаваться другим каплетам, которые его используют.

    Другой пример использует JavaScript и проект Avatar, который реализует Node.js в JVM. JAR-капсула содержит только исходный код JavaScript, Capsuleкласс и каплет Maven:

        608 META-INF/MANIFEST.MF
     161596 Capsule.class
    1467463 capsule-maven-1.0.jar
        266 app.js
    

    Когда капсула запускается, среда выполнения Аватара, включая нативные библиотеки, характерные для локальной ОС, будет загружаться из репозитория Maven, кэшироваться локально и передаваться другим капсулам Аватара.

    Другие каплеты включают каплет демона , который запускает капсулу как демон Unix или Windows, безопасный каплет , который запускает капсулу в изолированной программной среде Java (определенной в соответствии с определенной политикой безопасности), каплет рабочего стола , который превращает капсулу, содержащую графический интерфейс пользователя. приложение в нативный (включая иконку!) исполняемый файл для Windows, Mac или Linux, каплет контейнера , который запускает капсулу внутри контейнера и еще пару.

    Легкие контейнеры для капсул

    Контейнеры являются эффективным способом для песочницы приложений, а также для оптимизации развертывания и консолидации серверов, поэтому они являются полезным инструментом разработки и обеспечения безопасности независимо от программного стека. Однако, поскольку приложения JVM предъявляют минимальные требования к среде (то есть ядро ​​и JVM) и, как правило, являются переносимыми, использование контейнерного решения, такого как Docker, является пустой тратой времени, пространства и удобства. С другой стороны, защитная крышка создает легкий контейнер для капсулы, не требуя создания больших изображений.

    Например, мы можем легко запустить веб-приложение quasar-stocks в контейнере с помощью простого сетевого моста:

    java -jar capsule-shield-0.1.0.jar quasar-stocks-thin.jar
    

    Затем мы можем легко получить IP-адрес контейнера, в котором запущено приложение:

    lxc-attach -P ~/.capsule/apps/quasarstocks.Application_0.1.0-SNAPSHOT/capsule-shield/ -n lxc -- /sbin/ifconfig
    

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

    Что теперь?

    Отправляйся в капсулу.io и начинай выпускать капсулы!

    1. Они требуют затенения, чтобы избежать коллизий, и часто даже этого недостаточно, и они не поддерживают собственные библиотеки.
    2. Для них может потребоваться выполнение непортативных сценариев запуска оболочкой ОС для выбора правильной версии JRE, настройки пути к классам, агентов и параметров JVM.
    3. Конечно, все платформы, которые поддерживают JVM, и необходимые сценарии и собственные артефакты, которые могли быть включены.
    4. Помимо потенциально более длительного времени запуска, например, из-за повторной загрузки зависимостей.
    5. Защитная капсула использует LXC для помещения капсулы в контейнер.