Itt jársz most: Kezdőlap > Alkalmazásfejlesztés > Bemutatkozik a Domino Deployment Orchestration Service

Szűrő megjelenítése

Bemutatkozik a Domino Deployment Orchestration Service

Mindenképpen érdemes azzal kezdenem cikkemet, hogy egyáltalán mi a Domino (és miért pont Domino a neve). A Domino egy "deployment orchestrator", egy olyan alkalmazás, amely képes kezelni a szerveren futó alkalmazások telepítését és azok "életciklus" műveleteit, tehát indítását, leállítását, stb. Számos ilyen alkalmazás és komplett, a Dominonál jóval fejlettebb környezet létezik, például a CloudForge vagy a Kubernetes, de még bőven sorolhatnám. Azonban, mint a Leaflet fejlesztése során minden más tekintetben, itt is az egyszerűségre és az éppen szükséges minimumra koncentráltam, annak érdekében, hogy egy a Leaflethez hasonló pici projekt üzemeltetéséhez ne kelljen VPS-ek tucatjait üzemeltetni, és főképp, ne maga az infrastruktúra miatt.

A Domino egyetlen pici, REST API-jal vezérelhető, Node.JS-ben írt alkalmazás - a neve is innen és a fenti kritériumokból ered egyébként, egy szójáték a Deployment Orchestration for Minor Infrastuctures, powered by Node.JS kifejezésből. (Egy vicces anekdota a Domino nevét illetően: a fejlesztése elején egy apró hiba miatt a Domino leállítása magával vonta az általa kezelt alkalmazások leállását is. Így egyfajta dominó-effektussal a teljes infrastruktúra leállt, mikor a Domino leállt - ez természetesen azóta ki van javítva. :) ) Az egyszerűség és a biztonságosabb üzemeltetés miatt a konfigurációja statikus, az API csak a telepítési és életciklus műveleteket támogatja, viszont az JWT tokennel védett (egyelőre egyetlen "admin" szintű felhasználó állítható be, de ezen később változtatni szeretnék). A REST API miatt könnyen integrálható távoli rendszerekkel, így például a Leaflet esetében a deploymenteket a CircleCI-ról indítom, de készült hozzá egy CLI eszköz is, mellyel parancssorból vezérelhető. Természetesen a REST API másféle integrációt is lehetővé tenne, így például egy komplett UI-jal is kiegészíthető lenne.

Mit tud pontosan a Domino? - Egy példa a használatára

Tehát ahogy azt már említettem, a Domino képes kezelni a szerveren futó vagy futtatandó alkalmazások telepítését és életciklusát. Jelenleg kétféle forrással tud dolgozni a Domino, az egyik (mondhatni a legacy mód) közvetlenül tud kezelni futtatható binárisokat, például .jar file-okat, ez esetben akár a hozzájuk rendelt runtime-ot is beállíthatjuk, kiválaszthatjuk (például regisztrálhatunk JDK 8-at, mellette JDK 11-et, majd beállíthatjuk, melyik alkalmazást melyikkel indítsa stb.) Bár ez a mód még mindig szerves része a Dominonak és a dokumentáció is részletezi a használatát jelenleg is (a dokumentáció egyébként readme.md formában elérhető a cikk végén linkelt repositoryban), személy szerint én az újabb módszert javaslom a használatára. A Domino 1.2.0 verziójában ugyanis Docker támogatás került implementálásra, így lényegében Docker image-ekkel illetve a Docker Engine-nel is tud dolgozni a Domino. A Docker - annak aki még nem ismerné - egy kiváló eszköz alkalmazásaink izolált környezetben való futtatására, mivel lényegében egy virtuális gépbe csomagolva fut az alkalmazásunk, így nem kell "szennyeznünk" a szervert a különféle runtime-okkal, mivel azok az alkalmazással összecsomagolva futnak, szintén a számukra kijelölt izolált környezetben.

Hogy egy példán keresztül is demonstráljam a Domino használatát, vegyük azt alapul, hogy az említett Docker környezet már telepítve van a szerverre és az alkalmazásunk már el van csomagolva egy Docker image-be. Ebben az esetben a Domino telepítése, kezdeti konfigurációja és elindítása után (később erre még részleteiben visszatérünk), az alkalmazásunkat először is regisztrálnunk kell a Domino konfigurációjában. Ehhez majd szükségünk lesz az image-et biztosító Docker Registry címére, az image nevére, és néhány olyan konfigurációs beállításra, melyre a Dockernek egyébként is szüksége volna, úgy mint a container által kinyitott portok, környezeti változók, volume-ok, stb. (Még néhány további paraméter beállítására is van lehetőség, de a Domino integrálva csak a legszükségesebb, általánosan használt paramétereket ismeri, szignifikánsan testreszabott konfiguráció beállítása a Docker Engine API által elvárt run request pontos felépítésével lehetséges). Opcionálisan beállítható továbbá health-check, ami ha engedélyezve van, automatikusan lefut az alkalmazás indítása után, illetve néhány alap információ is beállítható, mint az alkalmazás teljes neve, ami aztán szintén lekérhető a Domino API-án keresztül. A regisztráció után szükséges a Domino újraindítása, hogy a beállítások aktualizálódjanak.

A beállítás után az API-ra küldött utasításokkal tudjuk végrehajtani a telepítést és az indítást. A telepítéshez egy PUT requestet kell küldenünk a /lifecycle/{app}/deploy vagy a /lifecycle/{app}/deploy/{version} útvonalra, ahol az {app} az alkalmazás regisztrált neve, a {version} pedig a telepíteni kívánt verzió. Ez utóbbi paramétert elhagyva a Domino a forrás tárolóban (ez esetben a Docker Registry-ben) levő legutóbbi verziót használja majd (Docker esetében a latest tag-gel ellátott image-et fogja használni). Az alkalmazás indításához küldjünk egy PUT requestet a /lifecycle/{app}/start endpointra, és várjuk meg a válaszát. Amennyiben health-check konfigurációt is beállítottunk, az indítás a health-check endpoint meghívásával végződik, és csak sikeres (HTTP 200 OK) válasz esetén zárul sikerrel a parancs futása. A leállításhoz egy DELETE requestre lesz szükségünk, melyet a /lifecycle/{app}/stop endpointra küldünk.

Fontos megjegyezni, hogy az API használata csak érvényes JWT tokennel lehetséges. A Domino konfigurációjában be kellett állítsunk egy adminisztrátor felhasználót - ezzel a felhasználóval tudunk "bejelentkezni" és egy tokent igényelni a /claim-token endpointra küldött POST request használatával. A generált tokent aztán minden requestben mellékelni kell az Authorization headerben, Bearer típusú tokenként.

Hogyan lehet telepíteni?

A Domino telepítése jelenleg két módon lehetséges. Mindkét módszer részletesen le van írva a Domino dokumentációjában és bár a második módszert a dokumentáció még mindig "kísérleti módszerként" emlegeti, mégis inkább azt javasolnám, mivel sokkal egyszerűbb. Összefoglalva, a Domino el van csomagolva egy Linux operációs rendszereken futtatható binárisba, ami letölthető a Domino repositoryjának Releases részlegében (a .tar.gz csomagot kell letöltenünk). Kicsomagolás után kezdhetjük is a Domino konfigurálását - a csomag több file-t is tartalmaz, a két .node kiterjesztésű file-t mindenképp tartsuk a domino bináris mellett, mivel azokra szüksége van futás közben. Ha a konfigurálással is megvagyunk, az indításához még meg kell adnunk két környezeti változót:

  • A NODE_CONFIG_DIR határozza meg, hol találja majd a Domino a saját konfigurációs beállításait (ez a file hivatkozza a regisztrációkat tartalmazó konfigurációs file-t is);
  • Illetve a NODE_ENV paraméterrel állíthatjuk be a saját futási környezetét (ha a környezet neve production akkor egy production.yml file-t fog keresni a korábban megadott NODE_CONFIG_DIR útvonalon).

Számos konfigurációs paraméter rendelkezik beállított alapértelmezett értékkel, de azokkal nem fog helyesen futni a Domino - a beállítási opciókról a dokumentáció tartalmaz részletes információkat, de egy példát láthatunk majd a cikk következő bekezdésében. Egyébként tervben van a Domino Dockeresítése, így a fenti telepítési procedúra remélhetőleg még egyszerűbb lesz - valószínűleg a hivatalos Docker Hub-ról is elérhető lesz a Domino.

Hogyan lehet konfigurálni?

Domino konfiguráció

A repositoryban a config/default.yml file tartalmaz egy alap konfigurációt, ami tökéletes kiindulásnak - ezt ajánlott lemásolni magunknak, és azt használni a továbbiakban. A minimálisan szükséges felülbírált konfiguráció nagyjából a következő:

  • domino.system.registrations-path: Ez a paraméter határozza meg, hol keresse a Domino az alkalmazás regisztrációkat. Alapértelmezetten a Domino saját futási mappája alatt létrehozott config mappa lesz a forrás, azon belül is a domino-registrations.yml nevű file.
  • domino.system.logging.tlp-logging: A már korábban emlegetett TLP log processor alkalmazással való integrálás alapértelmezetten be van kapcsolva, de nem szükséges használni, így ha nem rendelkezünk ezzel az alkalmazással, állítsuk ezt az értéket false-ra.
  • domino.server.host és domino.server.port: Az alapértelmezett request figyelési cím és port. Változtatása igazából csak a szerverkörnyezet függvényében indokolt, például ha az alapértelmezett port már foglalt.
  • domino.storage.enable-upload: Kizárólag Docker alapú használat esetén ezt nyugodtan le lehet tiltani, illetve abban az esetben is, ha filerendszer forrást használunk, de a binárisok más módon vannak a szerverre másolva. Ez az opció engedélyezett állapotban egy feltöltési endpointot regisztrál, amin keresztül a file-ok beküldhetőek a Dominonak.
  • domino.auth paraméterek: Az adminisztrátor felhasználó illetve a token aláíráshoz használt kulcs beállítása lehetséges is. Ezek talán a legfontosabb beállítások, mivel rosszul beállítva ezeket szignifikáns biztonsági kockázatnak tehetjük ki szerverünket! A itt megadott jelszót egyébként előzetesen BCrypt titkosítással kell kezelnünk, erre segítséget nyújt a már korábban említett és a cikk végén linkelt Domino CLI.
  • docker.servers: Több Docker Registry szervert is regisztrálhatunk itt, ahonnan majd a Docker image-ek letölthetőek. Amennyiben nem használunk Docker forrást, a listából töröljük a példát, ellenkező esetben adjuk meg a Registry szerver címét, illetve privát Registry esetén a hozzáféréshez szükséges felhasználónevet és jelszót.

Alkalmazás regisztráció

Ha a Domino saját konfigurációjával végeztünk, hozzáláthatunk az alkalmazásaink regisztrációjához. Az egyszerűség és érthetőség kedvéért egy példán keresztül fogom bemutatni, hogyan kell elvégezni a regisztrációt. Fontos megjegyezni, hogy a már említett Domino CLI is tud segíteni az alábbi konfiguráció létrehozásában, amolyan "varázsló" formájában - érdemes arra is ránézni.

Tegyük fel, az alkalmazásunkat "myservice" néven szeretnénk regisztrálni. Ebben az esetben hozzuk létre a következő bejegyzést a regisztrációs file-ban:

domino:
  registrations:
    - myservice:
        # ...

A továbbiakban ezzel a névvel kell majd hivatkoznunk ezt az alkalmazást, tehát ha például el akarjuk indítani az alkalmazást, azt egy PUT /lifecycle/myservice/start requesttel tehetjük meg.

A konfigurációt két kötelező és két opcionális szekcióval kell folytatnunk. Az első kötelező szekció a forrás beállítása. Docker forrást fogunk használni, az image a myregistry.dev.local Docker Registry szerveren található és myservice_docker a neve. A konfiguráció a következőképp fog kinézni:

domino:
  registrations:
    - myservice:
        source: 
          type: DOCKER
          home: myregistry.dev.local
          resource: myservice_docker

Ezután be kell állítanunk a futtatási paramétereket. A containert myservice_instance1 néven akarjuk futtatni, a belső 8080-as portját a 9080-as külső portra kötjük, kap egy csak olvasható külső konfigurációs file-t, és egy másik útvonalat, ahova írni is tud, illetve kap továbbá egy környezeti változót, amin a környezete nevét kapja meg. Beállítjuk továbbá, hogy automatikusan induljon újra, ha leállna, kivéve ha az szándékos leállítás volt.

domino:
  registrations:
    - myservice:
        # ...
        execution:
          command-name: myservice_instance1
          # Ez jelzi a Dominonak, hogy "docker run" utasítással fogjuk indítani a containert, 
          # egyelőre csak ez támogatott.
          via: STANDARD
          args:
            ports:
              9080: 8080
            environment:
              APP_ENVIRONMENT: production
            volumes:
              "/host/config/myservice.yml": "/container/config/myservice.yml:ro"
              "/host/workdir": "/container/workdir"
            restart-policy: unless-stopped

Ezzel alapvetően már készen áll az alkalmazásunk az indításra. További két opcionális paraméter csoportunk van még azonban, az elsőt mindenképp tudom javasolni beállítani, ami a health-check. Tegyük fel, az alkalmazásunk a /health endpointon biztosít health-check lehetőséget, és a Domino ezt localhoston is meg tudja hívni. Az első próbálkozással 10 másodpercet várunk majd (mert tudjuk, hogy nagyjából 7-8 másodperc az alkalmazásunk indulása), de ha ez mégis sikertelen volna (a válaszra 2 másodpercet várunk), akkor megpróbáljuk még kétszer.

domino:
  registrations:
    - myservice:
        # ...
        health-check:
          enabled: true
          delay: 10 seconds
          timeout: 2 seconds
          max-attempts: 3
          endpoint: http://localhost:9080/health

Végül beállíthatjuk, hogy milyen információkat közöljön magáról az alkalmazás a Domino GET /lifecycle/myservice/info endpointján keresztül. Ehhez adjuk meg az alkalmazás azon endpointját, ahol le tudjuk kérdezni a számunkra érdekes információkat, ez most az alkalmazás /info endpointja lesz, illetve beállítjuk, hogy az azon visszaadott JSON válaszból mikre vagyunk kíváncsi, és azok hogyan jelenjenek majd meg a Domino válaszában.

domino:
  registrations:
    - myservice:
        # ...
        info:
          enabled: true
          endpoint: http://localhost:9080/info
          field-mapping:
            # JSON-path kifejezésekkel nyerjük ki az app.name 
            # és a build.version értékeket a válaszból
            name: $.app.name
            version: $.build.version

Ezzel végeztünk is a beállításokkal. Mentsük a konfigurációs file-t, indítsuk újra a Domino-t és adjuk ki a deploy-start utasításokat az alkalmazás indításához.

Tervek a Domino továbbfejlesztését illetően

Számtalan jelenleg még megvalósítatlan terv porosodik a Domino project backlogjában, melyek közül mindenképp kiemelendő a Domino Dockeresítése (tehát maga a Domino becsomagolása és használata Docker image-ként), illetve további források támogatása, mint például a Docker Composer, Kubernetes, stb. Egyelőre azt sem támogatja, hogy több példányt futtassunk ugyanabból az alkalmazásból, bár ez a konfiguráció megváltoztatásával és több Domino példány telepítésével megoldható jelenleg is - egy kényelmesebb megoldás persze jobb lenne rá. A háttérben már jó ideje dolgozok a Leaflet egy nagyobb átalakításán, többek között OAuth alapú biztonsági réteget is kapni fog a rendszer, ezzel is szeretném majd előbb-utóbb integrálni a Domino-t. Illetve az operációs rendszer függés csökkentése is fontos szempont lenne, mivel jelenleg kizárólag Linux rendszereken képes működni.

Szóval határozottan lenne még mit fejleszteni rajta, de már jelenleg is tökéletesen kiszolgálja mindazokat a szükségleteket, amiket a Leaflet stack üzemeltetése igényel. Az előzetes konfigurációt követően könnyen használható alkalmazás, a regisztrációk bővítése egyszerű és gyors, integrációja külső CI rendszerekkel percek alatt elvégezhető - legalábbis véleményem szerint, de szívesen hallanám a Ti visszajelzéseiteket, illetve további fejlesztési javaslaitokat is. :)

Domino repository a GitHub-on

Domino CLI repository a GitHub-on

Kommentek
Hozzászólok

Még senki nem szólt hozzá ehhez a bejegyzéshez.