
Abbiamo già parlato di , che consente di sviluppare applicazioni distribuite e confezionarle. Ciò che resta è solo imparare a distribuire queste applicazioni e gestirle. Non preoccuparti, abbiamo pensato a tutto! Abbiamo raccolto insieme tutte le best practices per lavorare con Tarantool Cartridge e scritto , che installerà il pacchetto sui server, avvierà le istanze, le unirà in un cluster, configurerà l'autenticazione, bootstrapperà vshard, attiverà il failover automatico e aggiornerà la configurazione del cluster.
Interessa? Allora ti invitiamo a proseguire, ti racconteremo tutto.
Iniziamo con un esempio
Esamineremo solo una parte delle funzionalità del nostro ruolo. Puoi sempre trovare una descrizione completa di tutte le sue capacità e dei parametri di ingresso in . Ma è meglio provare una volta che vedere cento volte, quindi distribuiamo una piccola applicazione.
Tarantool Cartridge ha un per creare una piccola applicazione Cartridge, che memorizza informazioni sui clienti della banca e sui loro conti, e fornisce anche un'API per gestire i dati tramite HTTP. Per fare ciò, nell'applicazione vengono descritte due possibili ruoli: api e storage, che possono essere assegnati alle istanze.
Cartridge non fornisce indicazioni su come avviare processi, ma semplicemente offre la possibilità di configurare gli istanti già avviati. Il resto deve essere fatto dall'utente: creare file di configurazione, avviare i servizi e impostare la topologia. Ma non ci occuperemo di tutto questo, Ansible lo farà per noi.
Dalla teoria alla pratica
Quindi, deployiamo la nostra applicazione su due macchine virtuali e configuriamo una semplice topologia:
- ReplicaSet
app-1avrà il compito di implementare il ruoloapi, che include il ruolovshard-router. Qui ci sarà solo un'istanza. - ReplicaSet
storage-1implementa il ruolostorage(e contemporaneamentevshard-storage), aggiungeremo due istanze da macchine diverse.

Per avviare l'esempio avremo bisogno di e (versione 2.8 o superiore).
Il ruolo si trova in . Questo è un repository che consente di condividere il proprio lavoro e utilizzare ruoli già pronti.
Cloniamo il repository con l'esempio:
$ git clone https://github.com/dokshina/deploy-tarantool-cartridge-app.git
$ cd deploy-tarantool-cartridge-app && git checkout 1.0.0Avviamo le macchine virtuali:
$ vagrant upInstalliamo il ruolo Ansible Tarantool Cartridge:
$ ansible-galaxy install tarantool.cartridge,1.0.1Eseguiamo il ruolo installato:
$ ansible-playbook -i hosts.yml playbook.ymlStiamo aspettando la fine dell'esecuzione del playbook, passiamo a e godiamoci il risultato:

Possiamo iniziare a trasferire i dati. È fantastico, vero?
Ora vediamo come lavorare con questo e aggiungiamo un altro replica set nella topologia.
Iniziamo a capire
Quindi, cosa è successo?
Abbiamo avviato due macchine virtuali e lanciato un playbook ansible che ha configurato il nostro cluster. Diamo un'occhiata al contenuto del file playbook.yml:
---
- name: Distribuisci la mia app Tarantool Cartridge
hosts: all
become: true
become_user: root
tasks:
- name: Importa il ruolo Tarantool Cartridge
import_role:
name: tarantool.cartridgeQui non sta succedendo nulla di interessante, lanciamo il ruolo ansible chiamato tarantool.cartridge.
Tutto ciò che è importante (ossia, la configurazione del cluster) si trova nel -file hosts.yml:
---
all:
vars:
# variabili comuni del cluster
cartridge_app_name: getting-started-app
cartridge_package_path: ./getting-started-app-1.0.0-0.rpm # percorso del pacchetto
cartridge_cluster_cookie: app-default-cookie # cookie del cluster
# opzioni ssh comuni
ansible_ssh_private_key_file: ~/vagrant.d/insecure_private_key
ansible_ssh_common_args: '-o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
# ISTANZE
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:
# GRUPPARE LE ISTANZE PER MACCHINE
host1:
vars:
# opzioni di connessione della prima macchina
ansible_host: 172.19.0.2
ansible_user: vagrant
hosts: # istanze da avviare sulla prima macchina
storage-1:
host2:
vars:
# opzioni di connessione della seconda macchina
ansible_host: 172.19.0.3
ansible_user: vagrant
hosts: # istanze da avviare sulla seconda macchina
app-1:
storage-1-replica:
# GRUPPARE LE ISTANZE PER SET DI REPLICA
replicaset_app_1:
vars: # configurazione del set di replica
replicaset_alias: app-1
failover_priority:
- app-1 # leader
roles:
- 'api'
hosts: # istanze del set di replica
app-1:
replicaset_storage_1:
vars: # configurazione del set di replica
replicaset_alias: storage-1
weight: 3
failover_priority:
- storage-1 # leader
- storage-1-replica
roles:
- 'storage'
hosts: # istanze del set di replica
storage-1:
storage-1-replica:Tutto ciò che dobbiamo fare è imparare a gestire le istanze e i replica set, modificando il contenuto di questo file. In seguito, aggiungeremo nuove sezioni. Per non confonderci su dove aggiungerle, puoi dare un'occhiata alla versione finale di questo file, hosts.updated.yml, che si trova nel repository di esempio.
Gestione delle istanze
In termini di Ansible, ogni istanza è un host (non confondere con un server fisico), cioè un nodo dell'infrastruttura che Ansible gestirà. Per ogni host possiamo specificare le impostazioni di connessione (come ansible_host e ansible_user), così come la configurazione dell'istanza. La descrizione delle istanze è nella sezione hosts.
Esaminiamo la configurazione dell'istanza storage-1:
all:
vars:
...
# ISTANZE
hosts:
storage-1:
config:
advertise_uri: '172.19.0.2:3301'
http_port: 8181
...Nella variabile config abbiamo specificato i parametri dell'istanza — advertise URI e HTTP port.
Sotto ci sono i parametri delle istanze app-1 e storage-1-replica.
Dobbiamo fornire ad Ansible i parametri di connessione per ogni istanza. Sembra logico raggruppare le istanze in base alle macchine virtuali. A tal fine, le istanze sono state raggruppate in host1 e host2, e in ogni gruppo, nella sezione vars , sono indicate le valori ansible_host e ansible_user per una singola macchina virtuale. E nella sezione hosts — hosts (o istanze) che appartengono a questo gruppo:
all:
vars:
...
hosts:
...
children:
# GRUPPA ISTANZE PER MACCHINE
host1:
vars:
# opzioni di connessione della prima macchina
ansible_host: 172.19.0.2
ansible_user: vagrant
hosts: # istanze da avviare sulla prima macchina
storage-1:
host2:
vars:
# opzioni di connessione della seconda macchina
ansible_host: 172.19.0.3
ansible_user: vagrant
hosts: # istanze da avviare sulla seconda macchina
app-1:
storage-1-replica:Iniziamo a modificare hosts.yml. Aggiungeremo altre due istanze, storage-2-replica sul primo virtuale e storage-2 sul secondo:
all:
vars:
...
# ISTANZE
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:
# GRUPPA ISTANZE PER MACCHINE
host1:
vars:
...
hosts: # istanze da avviare sulla prima macchina
storage-1:
storage-2-replica: # <==
host2:
vars:
...
hosts: # istanze da avviare sulla seconda macchina
app-1:
storage-1-replica:
storage-2: # <==
...Eseguiamo l'ansible-playbook:
$ ansible-playbook -i hosts.yml
--limit storage-2,storage-2-replica
playbook.ymlFai attenzione all'opzione --limit. Poiché ogni istanza del cluster è un host in termini di Ansible, possiamo specificare esplicitamente quali istanze devono essere configurate durante l'esecuzione del playbook.
Accediamo di nuovo all'interfaccia Web e osserviamo i nostri nuovi istanze:

Non ci fermeremo qui e impareremo a gestire la topologia.
Gestione della topologia
Uniremo i nostri nuovi istanze in un replicaset storage-2. Aggiungeremo un nuovo gruppo replicaset_storage_2 e descriveremo nelle sue variabili i parametri del replicaset, analogamente a replicaset_storage_1. Nella sezione hosts indicheremo quali istanze faranno parte di questo gruppo (cioè il nostro replicaset):
---
all:
vars:
...
hosts:
...
children:
...
# GRUPPARE LE ISTANZE PER REPLICA SET
...
replicaset_storage_2: # <==
vars: # configurazione del replicaset
replicaset_alias: storage-2
weight: 2
failover_priority:
- storage-2
- storage-2-replica
roles:
- 'storage'
hosts: # istanze del replicaset
storage-2:
storage-2-replica:Riavviamo il playbook:
$ ansible-playbook -i hosts.yml
--limit replicaset_storage_2
--tags cartridge-replicasets
playbook.ymlNel parametro --limit questa volta abbiamo passato il nome del gruppo che corrisponde al nostro replicaset.
Consideriamo l'opzione tags.
Il nostro ruolo esegue sequenzialmente varie attività contrassegnate dai seguenti tag:
cartridge-instances: gestione delle istanze (configurazione, connessione a membership);cartridge-replicasets: gestione della topologia (gestione dei replicaset e rimozione irreversibile (expel) delle istanze dal cluster);cartridge-config: gestione degli altri parametri del cluster (bootstrapping vshard, modalità di failover automatico, parametri di autorizzazione e configurazione dell'applicazione).
Possiamo specificare esplicitamente quale parte del lavoro vogliamo svolgere, in tal modo il ruolo salterà l'esecuzione delle altre attività. Nel nostro caso vogliamo lavorare solo con la topologia, quindi abbiamo specificato cartridge-replicasets.
Valutiamo il risultato dei nostri sforzi. Troviamo un nuovo replicaset su .

Evviva!
Sperimentate con la modifica della configurazione degli istanze e dei replicaset e osservate come cambia la topologia del cluster. Potete provare vari scenari operativi, come ad esempio, o aumento memtx_memory. Il ruolo cercherà di farlo senza riavviare l'istanza, al fine di ridurre il possibile downtime della vostra applicazione.
Non dimenticate di eseguire vagrant halt, per fermare le macchine virtuali quando avete finito di lavorarci.
E cosa c'è sotto il cofano?
Qui parlerò più in dettaglio di cosa è successo sotto il cofano del ruolo ansible durante i nostri esperimenti.
Analizziamo passo dopo passo il deployment dell'applicazione Cartridge.
Installazione del pacchetto e avvio delle istanze
Prima di tutto, è necessario consegnare il pacchetto al server e installarlo. Ora il ruolo è in grado di lavorare con pacchetti RPM e DEB.
Poi avviamo gli istanze. Qui è tutto molto semplice: ogni istanza è un systemd-servizio. Lo spiego con un esempio:
$ systemctl start myapp@storage-1Questo comando avvierà l'istanza storage-1 applicativi myapp. L'istanza avviata cercherà il suo in /etc/tarantool/conf.d/. I log dell'istanza possono essere visualizzati utilizzando journald.
Il file di unità /etc/systemd/system/myapp@.sevice per il servizio systemd sarà consegnato insieme al pacchetto.
Ansible ha moduli incorporati per l'installazione di pacchetti e la gestione dei servizi systemd, quindi non abbiamo inventato nulla di nuovo.
Configurazione della topologia del cluster
Qui inizia la parte più interessante. Concordate che sarebbe strano preoccuparsi di un ruolo ansible speciale per l'installazione di pacchetti e l'avvio di systemd-servizi.
È possibile configurare il cluster manualmente:
- Prima opzione: apriamo l'interfaccia Web e facciamo clic sui pulsanti. Per avviare temporaneamente più istanze, andrà benissimo.
- Seconda opzione: è possibile utilizzare l'API GraphQl. Qui è possibile automatizzare qualcosa, ad esempio scrivere uno script in Python.
- La terza opzione (per i più coraggiosi): accediamo al server e ci colleghiamo a una delle istanze utilizzando
tarantoolctl connecte facciamo tutte le manipolazioni necessarie con il modulo Luacartridge.
L'obiettivo principale della nostra invenzione è svolgere per voi questa parte di lavoro, la più complessa.
Ansible consente di scrivere il proprio modulo e utilizzarlo in un ruolo. Il nostro ruolo utilizza questi moduli per gestire i vari componenti del cluster.
Come funziona? Descrivi lo stato desiderato del cluster in una configurazione dichiarativa, e il ruolo fornisce a ciascun modulo la sua sezione di configurazione. Il modulo riceve lo stato attuale del cluster e lo confronta con ciò che è stato fornito. Successivamente, tramite il socket di un'istanza, viene eseguito il codice che riporta il cluster allo stato desiderato.
Risultati
Oggi abbiamo parlato e dimostrato come distribuire la vostra applicazione su Tarantool Cartridge e configurare una semplice topologia. Per questo abbiamo utilizzato Ansible, uno strumento potente che si distingue per la sua facilità d'uso e consente di configurare simultaneamente numerosi nodi dell'infrastruttura (nel nostro caso, le istanze del cluster).
In precedenza abbiamo esaminato uno dei tanti modi per descrivere la configurazione del cluster utilizzando Ansible. Una volta che sarai pronto a procedere, scopri per scrivere playbook. Potresti trovare più facile gestire la topologia tramite group_vars e host_vars.
Presto parleremo di come espellere istanze dalla topologia, avviare vshard, gestire la modalità di failover automatico, configurare l'autenticazione e patchare la configurazione del cluster. Nel frattempo, puoi studiare e sperimentare con la modifica dei parametri del cluster.
Se qualcosa non funziona, assicurati di il problema. Risolveremo tutto rapidamente!
Fonte: habr.com
