Lako i neprimjetno deployamo aplikacije na Tarantool Cartridge (dio 1)

Lako i neprimjetno deployamo aplikacije na Tarantool Cartridge (dio 1)

Već smo spomenuli Tarantool Cartridge, koji omogućuje razvoj distribuiranih aplikacija i njihovo pakiranje. Ostalo je samo da naučite kako implementirati te aplikacije i upravljati njima. Ne brinite, sve smo predvidjeli! Okupili smo najbolje prakse za rad s Tarantool Cartridge i napisali ansible-rolu, koja će rasporediti paket na servere, pokrenuti instance, povezati ih u klaster, postaviti autorizaciju, konfigurisati vshard, uključiti automatski failover i propisati klaster konfiguraciju.

Zanima vas? Onda vas pozivam ispod, sve ćemo objasniti i pokazati.

Počnimo s primjerom

Razmotrit ćemo samo dio funkcionalnosti naše role. Potpuni opis svih mogućnosti i ulaznih parametara uvijek možete pronaći u dokumentaciju. No bolje je jednom probati nego sto puta vidjeti, pa hajde da implementiramo malu aplikaciju.

Tarantool Cartridge ima tutorial za izradu male Cartridge-aplikacije koja pohranjuje informacije o klijentima banke i njihovim računima, kao i pruža API za upravljanje podacima putem HTTP-a. Za to se u aplikaciji opisuju dvije moguće uloge: api i storage, koje se mogu dodijeliti instancama.

Sam Cartridge ne govori ništa o tome kako pokretati procese, već samo pruža mogućnost za konfiguraciju već pokrenutih instanci. Ostalo korisnik mora učiniti sam: rasporediti konfiguracijske datoteke, pokrenuti servise i postaviti topologiju. No, nećemo se time zamarati, to će za nas učiniti Ansible.

Od riječi do djela

Dakle, implementirat ćemo našu aplikaciju na dva virtualna računala i postaviti jednostavnu topologiju:

  • Replikaset app-1 će realizirati ulogu api, koja uključuje ulogu vshard-router. Ovdje će biti samo jedna instanca.
  • Replikaset storage-1 realizuje ulogu storage (i istovremeno vshard-storage), ovdje ćemo dodati dvije instance s različitih mašina.

Lako i neprimjetno deployamo aplikacije na Tarantool Cartridge (dio 1)

Za pokretanje primjera potrebni su nam Vagrant i Ansible (verzije 2.8 ili starije).

Sama uloga nalazi se u Ansible Galaxy. To je skladište koje omogućuje dijeljenje svojih radova i korištenje gotovih uloga.

Klonićemo repozitorij s primjerom:

$ git clone https://github.com/dokshina/deploy-tarantool-cartridge-app.git
$ cd deploy-tarantool-cartridge-app && git checkout 1.0.0

Pokrećemo virtualke:

$ vagrant up

Instaliramo ansible-rolu Tarantool Cartridge:

$ ansible-galaxy install tarantool.cartridge,1.0.1

Pokrećemo instaliranu ulogu:

$ ansible-playbook -i hosts.yml playbook.yml

Čekamo završetak izvršavanja playbook-a, prelazimo na http://localhost:8181/admin/cluster/dashboard i uživamo u rezultatu:

Lako i neprimjetno deployamo aplikacije na Tarantool Cartridge (dio 1)

Možemo unijeti podatke. Sjajno, zar ne?

Sada hajde da istražimo kako to raditi i dodajmo još jedan replicaset u topologiju.

Počnimo sa razumevanjem

Dakle, šta se zapravo desilo?

Pokrenuli smo dve virtuelne mašine i izvršili ansible playbook, koji je konfigurisao naš klaster. Pogledajmo sadržaj datoteke playbook.yml:

---
- name: Deploy my Tarantool Cartridge app
  hosts: all
  become: true
  become_user: root
  tasks:
  - name: Import Tarantool Cartridge role
    import_role:
      name: tarantool.cartridge

Ovde se ništa posebno ne dešava, pokrećemo ansible ulogu koja se zove tarantool.cartridge.

Sve što je važno (a to je konfiguracija klastera) nalazi se u inventory-datoteci hosts.yml:

---
all:
  vars:
    # common cluster variables
    cartridge_app_name: getting-started-app
    cartridge_package_path: ./getting-started-app-1.0.0-0.rpm  # path to package

    cartridge_cluster_cookie: app-default-cookie  # cluster cookie

    # common ssh options
    ansible_ssh_private_key_file: ~/.vagrant.d/insecure_private_key
    ansible_ssh_common_args: '-o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'

  # INSTANCES
  hosts:
    storage-1:
      config:
        advertise_uri: '172.19.0.2:3301'
        http_port: 8181

    app-1:
      config:
        advertise_uri: '172.19.0.3:3301'
        http_port: 8182

    storage-1-replica:
      config:
        advertise_uri: '172.19.0.3:3302'
        http_port: 8183

  children:
    # GROUP INSTANCES BY MACHINES
    host1:
      vars:
        # first machine connection options
        ansible_host: 172.19.0.2
        ansible_user: vagrant

      hosts:  # instances to be started on the first machine
        storage-1:

    host2:
      vars:
        # second machine connection options
        ansible_host: 172.19.0.3
        ansible_user: vagrant

      hosts:  # instances to be started on the second machine
        app-1:
        storage-1-replica:

    # GROUP INSTANCES BY REPLICA SETS
    replicaset_app_1:
      vars:  # replica set configuration
        replicaset_alias: app-1
        failover_priority:
          - app-1  # leader
        roles:
          - 'api'

      hosts:  # replica set instances
        app-1:

    replicaset_storage_1:
      vars:  # replica set configuration
        replicaset_alias: storage-1
        weight: 3
        failover_priority:
          - storage-1  # leader
          - storage-1-replica
        roles:
          - 'storage'

      hosts:   # replica set instances
        storage-1:
        storage-1-replica:

Sve što nam treba je da naučimo upravljati instancama i replicasetima, menjajući sadržaj ove datoteke. U nastavku ćemo dodavati nove odeljke. Da se ne bismo zbunili gde ih dodavati, možete pogledati konačnu verziju ove datoteke, hosts.updated.yml, koja se nalazi u repozitoriju sa primerom.

Upravljanje instancama

U terminima Ansible, svaki instanc je host (ne miješati s fizičkim serverom), tj. čvor infrastrukture kojim će Ansible upravljati. Za svaki host možemo odrediti parametre veze (kao što su ansible_host i ansible_user), kao i konfiguraciju instanca. Opis instanca nalazi se u odjeljku hosts.

Pogledajmo konfiguraciju instance storage-1:

all:
  vars:
    ...

  # INSTANCI
  hosts:
    storage-1:
      config:
        advertise_uri: '172.19.0.2:3301'
        http_port: 8181

  ...

U varijabli config odredili smo parametre instance — advertise URI i HTTP port.
Ispod se nalaze parametri instanci app-1 i storage-1-replica.

Moramo obavijestiti Ansible o parametrima veze za svaku instancu. Čini se logičnim grupirati instance prema virtualnim strojevima. U tu svrhu, instance su grupirane u grupe host1 i host2, a u svakoj grupi u odjeljku vars navedene su vrijednosti ansible_host i ansible_user za jednu virtualku. A u odjeljku hosts — hostovi (tj. instance) koji su članovi ove grupe:

all:
  vars:
    ...
  hosts:
    ...
  children:
    # GRUPIRAJ INSTANCI PO STROJEVIMA
    host1:
      vars:
        # opcije veze za prvu mašinu
        ansible_host: 172.19.0.2
        ansible_user: vagrant
       hosts:  # instance koje će se pokrenuti na prvoj mašini
        storage-1:

     host2:
      vars:
        # opcije veze za drugu mašinu
        ansible_host: 172.19.0.3
        ansible_user: vagrant
       hosts:  # instance koje će se pokrenuti na drugoj mašini
        app-1:
        storage-1-replica:

Počinjemo s izmjenama hosts.yml. Dodajmo još dvije instance, storage-2-replica na prvoj virtualki i storage-2 na drugoj:

all:
  vars:
    ...

  # INSTANCI
  hosts:
    ...
    storage-2:  # <==
      config:
        advertise_uri: '172.19.0.3:3303'
        http_port: 8184

    storage-2-replica:  # <==
      config:
        advertise_uri: '172.19.0.2:3302'
        http_port: 8185

  children:
    # GRUPIRAJ INSTANCI PO STROJEVIMA
    host1:
      vars:
        ...
      hosts:  # instance koje će se pokrenuti na prvoj mašini
        storage-1:
        storage-2-replica:  # <==

    host2:
      vars:
        ...
      hosts:  # instance koje će se pokrenuti na drugoj mašini
        app-1:
        storage-1-replica:
        storage-2:  # <==
  ...

Pokrećemo ansible playbook:

$ ansible-playbook -i hosts.yml 
                   --limit storage-2,storage-2-replica 
                   playbook.yml

Obratite pažnju na opciju --limit. Budući da je svaka instanca klastera host u terminima Ansible, možemo izričito odrediti koje instance trebaju biti konfigurirane prilikom izvođenja playbooka.

Ponovo ulazimo u Web UI http://localhost:8181/admin/cluster/dashboard i promatramo naše nove instance:

Lako i neprimjetno deployamo aplikacije na Tarantool Cartridge (dio 1)

Nećemo stati na postignutom i ovladat ćemo upravljanjem topologijom.

Upravljenje topologijom

Spojit ćemo naše nove instance u replikacijski set storage-2. Dodajmo novu grupu replicaset_storage_2 i opisat ćemo u njenim varijablama parametre replikacijskog seta po analogiji s replicaset_storage_1. U odjeljku hosts navest ćemo koje će instance biti uključene u ovu grupu (tj. naš replikacijski set):

---
all:
  vars:
    ...
  hosts:
    ...
  children:
    ...
    # GRUPOVANJE INSTANCA PREMA REPLIKACIJSKIM SETOVIMA
    ...
    replicaset_storage_2:  # <==
      vars:  # konfiguracija replikacijskog seta
        replicaset_alias: storage-2
        weight: 2
        failover_priority:
          - storage-2
          - storage-2-replica
        roles:
          - 'storage'

      hosts:   # instance replikacijskog seta
        storage-2:
        storage-2-replica:

Ponovno pokrećemo playbook:

$ ansible-playbook -i hosts.yml 
                   --limit replicaset_storage_2 
                   --tags cartridge-replicasets 
                   playbook.yml

U parametru --limit ovoga puta prenijeli smo ime grupe koja odgovara našem replikacijskom setu.

Razmotrimo opciju tags.

Naša uloga postupno izvršava različite zadatke koji su označeni sljedećim oznakama:

  • cartridge-instances: upravljanje instancama (konfiguracija, povezivanje s članstvom);
  • cartridge-replicasets: upravljanje topologijom (upravljanje replikacijskim skupovima i nepopravljivo uklanjanje (expel) instanci iz klastera);
  • cartridge-config: upravljanje ostalim parametrima klastera (vshard bootstrapping, način automatskog failover-a, parametri autorizacije i konfiguracija aplikacije).

Možemo izričito navesti koju dio posla želimo obaviti, tada će uloga preskočiti izvršenje preostalih zadataka. U našem slučaju želimo raditi samo s topologijom, stoga smo naveli cartridge-replicasets.

Ocijenimo rezultat naših napora. Pronalazimo novi replikacijski set na http://localhost:8181/admin/cluster/dashboard.

Lako i neprimjetno deployamo aplikacije na Tarantool Cartridge (dio 1)

Ura!

Istražujte promjene konfiguracije instanci i replikacijskih setova i promatrajte kako se topologija klastera mijenja. Možete isprobati različite operativne scenarije, na primjer, rolling update ili povećanje memtx_memory. Uloga će pokušati to učiniti bez ponovnog pokretanja instance, kako bi smanjila moguće vrijeme zastoja vaše aplikacije.

Ne zaboravite pokrenuti vagrant halt, kako biste zaustavili virtualne mašine kada završite s njima.

A što je ispod haube?

Ovde ću detaljnije opisati što se događa ispod haube ansible-rolije tokom naših eksperimenata.

Razmotrimo korake implementacije Cartridge-aplikacije.

Instalacija paketa i pokretanje instanci

Prvo je potrebno dostaviti paket na server i instalirati ga. Sada uloga može raditi s RPM- i DEB-paketima.

Zatim pokrećemo instance. Sve je vrlo jednostavno: svaka instanca je zaseban systemd-servis. Objašnjavam na primjeru:

$ systemctl start myapp@storage-1

Ova komanda će pokrenuti instancu storage-1 aplikacije myapp. Pokrenuta instanca će tražiti svoju konfiguraciju u /etc/tarantool/conf.d/. Zapisnici instance mogu se pregledati pomoću journald.

Jedinični datoteka /etc/systemd/system/myapp@.sevice za systemd uslugu bit će dostavljen zajedno s paketom.

Ansible sadrži ugrađene module za instalaciju paketa i upravljanje systemd uslugama, ovdje nismo smislili ništa novo.

Postavljanje topologije klastera

A ovdje počinje najzanimljivije. Slažete se, bilo bi čudno zamarati se posebnim ansible-rolom za instalaciju paketa i pokretanje systemd-usluga.

Klaster se može postaviti ručno:

  • Prva opcija: otvaramo Web UI i pritiskamo gumbe. Za jednokratno pokretanje nekoliko instanci, to je sasvim dovoljno.
  • Druga opcija: možemo iskoristiti GraphQl API. Ovdje već možemo automatizirati nešto, na primjer, napisati skriptu na Pythonu.
  • Treća opcija (za duhovno jake): ulazimo na poslužitelj, povezujemo se s jednom od instanci pomoću tarantoolctl connect i izvršavamo sve potrebne manipulacije s Lua modulom cartridge.

Glavni cilj našeg izuma je obaviti upravo ovaj, najteži dio posla umjesto vas.

Ansible omogućuje da napišete svoj modul i koristite ga u roli. Naša uloga koristi takve module za upravljanje različitim komponentama klastera.

Kako to radi? Opisujete poželjno stanje klastera u deklarativnoj konfiguraciji, a uloga daje svakom modulu njegovu sekciju konfiguracije. Modul dobiva trenutno stanje klastera i uspoređuje ga s onim što je primio. Zatim kroz socket jedne od instanci pokreće se kod koji dovodi klaster u željeno stanje.

Zaključci

Danas smo objasnili i pokazali kako implementirati vašu aplikaciju na Tarantool Cartridge i postaviti jednostavnu topologiju. U tu svrhu koristili smo Ansible — moćan alat koji se odlikuje jednostavnošću upotrebe i omogućuje istovremeno postavljanje mnogih čvorova infrastrukture (u našem slučaju to su instance klastera).

Gore smo se bavili jednim od mnogih načina opisivanja konfiguracije klastera pomoću Ansibla. Čim shvatite da ste spremni ići dalje, proučite najbolje prakse za pisanje playbooka. Možda će vam biti zgodnije upravljati topologijom pomoću group_vars i host_vars.

Uskoro ćemo objasniti kako trajno ukloniti (expel) instance iz topologije, bootstrapovati vshard, upravljati režimom automatskog failover-a, podešavati autorizaciju i patchovati konfiguraciju klastera. A do tada, možete samostalno istraživati dokumentaciju i eksperimentirati s promjenom parametara klastera.

Ako nešto ne radi, obavezno javite nam o problemu. Brzo ćemo sve riješiti!

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster