
Am vorbit deja despre , care permite dezvoltarea aplicațiilor distribuite și ambalarea acestora. Rămâne doar să învățăm să desfășurăm aceste aplicații și să le gestionăm. Nu vă faceți griji, am prevăzut totul! Am adunat cele mai bune practici pentru lucrul cu Tarantool Cartridge și am scris , care va desfășura pachetul pe servere, va porni instanțele, le va aduna într-un cluster, va configura autorizarea, va efectua bootstrap-ul vshard, va activa failover-ul automat și va aplica patch-uri pe configurația clusterului.
Interesant? Atunci vă invităm să citiți mai departe, totul vă vom explica și arăta.
Haideți să începem cu un exemplu
Vom examina doar o parte din funcționalitatea rolului nostru. O descriere completă a tuturor capacităților și parametrilor de intrare o puteți găsi întotdeauna în . Dar este mai bine să încerci o dată decât să vezi de o sută de ori, așa că să desfășurăm o mică aplicație.
Tarantool Cartridge are creația unei mici aplicații Cartridge, care stochează informații despre clienții băncii și conturile lor, precum și oferă un API pentru gestionarea datelor prin HTTP. Pentru aceasta, aplicația descrie două roluri posibile: api și storage, care pot fi atribuite instanțelor.
Cartridge-ul în sine nu oferă informații despre cum să se pornească procesele, ci doar posibilitatea de configurare a instanțelor deja pornite. Restul trebuie să fie realizat de utilizator: distribuirea fișierelor de configurare, pornirea serviciilor și configurarea topologiei. Dar nu ne vom ocupa de toate acestea, Ansible va face acest lucru pentru noi.
De la vorbe la fapte
Așadar, să desfășurăm aplicația noastră pe două mașini virtuale și să configurăm o topologie simplă:
- Replica set
app-1va implementa rolulapi, care include rolulvshard-router. Aici va exista doar o instanță. - Replica set
storage-1implementează rolulstorage(și simultanvshard-storage), vom adăuga două instanțe de pe mașini diferite.

Pentru a lansa exemplul avem nevoie de și (versiunea 2.8 sau mai veche).
Rolul se află în . Acesta este un depozit care permite partajarea realizărilor proprii și utilizarea rolurilor gata existente.
Vom clona repository-ul cu exemplul:
$ git clone https://github.com/dokshina/deploy-tarantool-cartridge-app.git
$ cd deploy-tarantool-cartridge-app && git checkout 1.0.0Pornim mașinile virtuale:
$ vagrant upInstalăm rolul ansible Tarantool Cartridge:
$ ansible-galaxy install tarantool.cartridge,1.0.1Rulăm rolul instalat:
$ ansible-playbook -i hosts.yml playbook.ymlAșteptăm finalizarea execuției playbook-ului, trecem la și ne bucurăm de rezultat:

Este posibil să încărcăm date. Grozav, nu-i așa?
Acum să vedem cum funcționează și să adăugăm un alt replicaset în topologie.
Începem să investigăm
Deci, ce s-a întâmplat?
Am ridicat două mașini virtuale și am rulat un playbook ansible care a configurat clusterul nostru. Să aruncăm o privire asupra conținutului fișierului 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.cartridgeAici nu se întâmplă nimic interesant, rulăm rolul ansible care se numește tarantool.cartridge.
Toate detaliile importante (adică, configurația clusterului) se află în -fișierul 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:Tot ce ne trebuie este să învățăm să gestionăm instanțele și replicaset-urile, modificând conținutul acestui fișier. Mai departe, vom adăuga noi secțiuni în el. Pentru a nu ne încurca, putem verifica versiunea finală a acestui fișier, hosts.updated.yml, care se află în depozitul cu exemplul.
Gestionarea instanțelor
În termenii Ansible, fiecare instanță este un gazdă (nu trebuie confundat cu un server fizic), adică un nod al infrastructurii pe care Ansible o va gestiona. Pentru fiecare gazdă, putem specifica parametrii de conectare (cum ar fi ansible_host și ansible_user), precum și configurația instanței. Descrierea instanțelor se află în secțiunea gazde.
Să examinăm configurația instanței storage-1:
all:
vars:
...
# INSTANȚE
hosts:
storage-1:
config:
advertise_uri: '172.19.0.2:3301'
http_port: 8181
...În variabila config am specificat parametrii instanței — advertise URI și HTTP port.
Mai jos se află parametrii instanțelor app-1 și storage-1-replica.
Trebuie să informăm Ansible despre parametrii de conectare pentru fiecare instanță. Pare logic să grupăm instanțele în funcție de mașinile virtuale. Pentru aceasta, instanțele sunt grupate în host1 și host2, iar în fiecare grup în secțiunea vars sunt specificate valorile ansible_host și ansible_user pentru o singură mașină virtuală. Iar în secțiunea gazde — gazdelor (care sunt instanțele), care fac parte din acest grup:
all:
vars:
...
hosts:
...
children:
# GRUPAREA INSTANȚELOR DUPĂ MAȘINI
host1:
vars:
# opțiuni de conectare pentru prima mașină
ansible_host: 172.19.0.2
ansible_user: vagrant
hosts: # instanțele care vor fi pornite pe prima mașină
storage-1:
host2:
vars:
# opțiuni de conectare pentru a doua mașină
ansible_host: 172.19.0.3
ansible_user: vagrant
hosts: # instanțele care vor fi pornite pe a doua mașină
app-1:
storage-1-replica:Începem să modificăm hosts.yml. Vom adăuga încă două instanțe, storage-2-replica pe prima mașină virtuală și storage-2 pe a doua:
all:
vars:
...
# INSTANȚE
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:
# GRUPAREA INSTANȚELOR DUPĂ MAȘINI
host1:
vars:
...
hosts: # instanțele care vor fi pornite pe prima mașină
storage-1:
storage-2-replica: # <==
host2:
vars:
...
hosts: # instanțele care vor fi pornite pe a doua mașină
app-1:
storage-1-replica:
storage-2: # <==
...Executăm ansible-playbook:
$ ansible-playbook -i hosts.yml
--limit storage-2,storage-2-replica
playbook.ymlAtenție la opțiunea --limit. Deoarece fiecare instanță din cluster este o gazdă în termenii Ansible, putem specifica în mod explicit care instanțe trebuie configurate atunci când rulăm playbook-ul.
Ne întoarcem la Web UI și observăm noile noastre instanțe:

Nu ne vom opri aici și vom învăța să gestionăm topologia.
Gestionarea topologiei
Să unim noile noastre instanțe într-un replicaset storage-2. Vom adăuga un nou grup replicaset_storage_2 și vom descrie în variabilele sale parametrii replicaset-ului în mod similar cu replicaset_storage_1. În secțiunea gazde să indicăm ce instanțe vor face parte din acest grup (adică replica noastră):
---
all:
vars:
...
hosts:
...
children:
...
# GRUPEAZĂ INSTANȚELE DUPĂ REPLICASETS
...
replicaset_storage_2: # <==
vars: # configurația replicaset-ului
replicaset_alias: storage-2
weight: 2
failover_priority:
- storage-2
- storage-2-replica
roles:
- 'storage'
hosts: # instanțele replicaset-ului
storage-2:
storage-2-replica:Reluăm playbook-ul:
$ ansible-playbook -i hosts.yml
--limit replicaset_storage_2
--tags cartridge-replicasets
playbook.ymlÎn parametru --limit am transmis de data aceasta numele grupului care corespunde replicaset-ului nostru.
Să examinăm opțiunea tags.
Rolul nostru execută în mod consecutiv diverse sarcini, marcate cu următoarele tag-uri:
cartridge-instances: gestionarea instanțelor (configurare, conectare la membership);cartridge-replicasets: gestionarea topologiei (gestionarea replicaset-urilor și ștergerea irevocabilă (expel) a instanțelor din cluster);cartridge-config: gestionarea celorlalte parametrii ai cluster-ului (vshard bootstrapping, mod automatic de failover, parametrii de autorizare și configurația aplicației).
Putem specifica în mod explicit ce parte a muncii dorim să facem, atunci rolul va sări peste executarea celorlalte sarcini. În cazul nostru, dorim să lucrăm doar cu topologia, așa că am specificat cartridge-replicasets.
Să evaluăm rezultatul eforturilor noastre. Găsim noul replicaset pe .

Ura!
Experimentați cu modificarea configurației instanțelor și replicaset-urilor și observați cum se schimbă topologia cluster-ului. Puteți testa diferite scenarii de exploatare, de exemplu, sau creșterea memtx_memory. Rolul va încerca să facă acest lucru fără a reporni instanța, pentru a reduce downtime-ul posibil al aplicației dumneavoastră.
Nu uitați să rulați vagrant halt, pentru a opri mașinile virtuale, când ați terminat de lucrat cu ele.
Și ce se află sub capotă?
Aici voi explica mai în detaliu ce s-a întâmplat sub capota rolului ansible în timpul experimentelor noastre.
Să analizăm pas cu pas implementarea aplicației Cartridge.
Instalarea pachetului și pornirea instanțelor
Mai întâi trebuie să livrăm pachetul pe server și să-l instalăm. Acum rolul poate lucra cu pachete RPM și DEB.
Apoi, pornim instanțele. Aici totul este foarte simplu: fiecare instanță este un serviciu separat. Vă explic prin exemplu: systemd$ systemctl start myapp@storage-1
Această comandă va porni instanțaaplicației storage-1 myapp . Instanța pornită va căuta configurarea sa. în /etc/tarantool/conf.d/. Jurnalele instanței pot fi vizualizate folosind journald.
Fișierul unității /etc/systemd/system/myapp@.sevice pentru serviciul systemd va fi livrat împreună cu pachetul.
Ansible are module încorporate pentru instalarea pachetelor și gestionarea serviciilor systemd, aici nu am inventat nimic nou.
Configurarea topologiei clusterei
Aici începe partea cea mai interesantă. Să fim de acord, ar fi ciudat să ne complicăm cu un rol ansible special pentru instalarea pachetelor și pornirea systemd-serviciilor.
Clusterul poate fi configurat manual:
- Prima opțiune: deschidem interfața Web și apăsăm pe butoane. Pentru un start unic al mai multor instanțe, este destul de decent.
- A doua opțiune: putem folosi GraphQl API. Aici deja putem automatiza ceva, de exemplu, să scriem un script în Python.
- A treia opțiune (pentru cei puternici): ne conectăm la server, ne conectăm la una dintre instanțe folosind
tarantoolctl connectși efectuăm toate manevrele necesare cu modulul Luacartridge.
Principala noastră sarcină este să facem pentru voi exact această parte, cea mai complicată a muncii.
Ansible permite scrierea propriului modul și utilizarea acestuia în rol. Rolul nostru folosește astfel de module pentru a gestiona diferitele componente ale clusterei.
Cum funcționează? Descrieți starea dorită a clusterei într-o configurație declarativă, iar rolul trimite fiecărui modul secțiunea sa de configurare. Modulul primește starea curentă a clusterei și o compară cu ceea ce a fost furnizat. Apoi, prin socketul uneia dintre instanțe, se lansează codul care ajustează clusterul la starea dorită.
Concluzii
Astăzi am prezentat și am demonstrat cum să desfășurați aplicația dvs. pe Tarantool Cartridge și să configurați o topologie simplă. Pentru asta am folosit Ansible - un instrument puternic, care se distinge prin ușurința în utilizare și permite configurarea simultană a multor noduri ale infrastructurii (în cazul nostru, instanțele clusterei).
Mai sus am analizat una dintre numeroasele modalități de a descrie configurația clusterei folosind Ansible. Odată ce înțelegeți că sunteți pregătiți să mergeți mai departe, explorați pentru scrierea playbook-urilor. Poate că vă va fi mai convenabil să gestionați topologia folosind group_vars și host_vars.
În curând, vă vom arăta cum să eliminați definitiv instanțele din topologie, să bootstrapați vshard, să gestionați modul de failover automat, să configurați autorizarea și să aplicați patch-uri la configurația clusterului. Până atunci, puteți să studiați și să experimentați cu modificarea parametrilor clusterului.
Dacă ceva nu funcționează, vă rugăm să despre problemă. Vom rezolva rapid totul!
Sursa: habr.com
