Implantando aplicativos no Tarantool Cartridge de forma fácil e descontraída (parte 1)

Implantando aplicativos no Tarantool Cartridge de forma fácil e descontraída (parte 1)

Já falamos sobre Tarantool Cartridge, que permite desenvolver aplicativos distribuídos e empacotá-los. Agora, só falta uma coisa: aprender a implantar esses aplicativos e gerenciá-los. Não se preocupe, nós previmos tudo! Reunimos todas as melhores práticas para trabalhar com Tarantool Cartridge e escrevemos um papel ansible, que irá distribuir o pacote nos servidores, iniciar as instâncias, agrupá-las em um cluster, configurar a autorização, inicializar vshard, ativar a recuperação automática e atualizar a configuração do cluster.

Interessado? Então, venha conosco, contaremos e mostraremos tudo.

Começaremos com um exemplo

Vamos considerar apenas uma parte da funcionalidade do nosso papel. A descrição completa de todas as suas capacidades e parâmetros de entrada está sempre disponível em documentação. Mas é melhor experimentar uma vez do que ver cem vezes, então vamos implantar um pequeno aplicativo.

O Tarantool Cartridge possui tutorial para criar um pequeno aplicativo Cartridge que armazena informações sobre clientes de um banco e suas contas, além de fornecer uma API para gerenciar dados via HTTP. Para isso, no aplicativo são descritas duas funções possíveis: api e storage, que podem ser atribuídas às instâncias.

O próprio Cartridge não diz nada sobre como iniciar processos, apenas fornece a capacidade de configurar instâncias já em execução. O restante o usuário deve fazer por conta própria: distribuir arquivos de configuração, iniciar serviços e configurar a topologia. Mas não vamos nos preocupar com isso, o Ansible fará isso por nós.

Vamos ao trabalho

Vamos implantar nosso aplicativo em duas máquinas virtuais e configurar uma topologia simples:

  • Replicaset app-1 realizará o papel api, que inclui o papel vshard-router. Aqui haverá apenas uma instância.
  • O replicaset storage-1 implementa o papel storage (e simultaneamente vshard-storage), aqui adicionaremos duas instâncias de máquinas diferentes.

Implantando aplicativos no Tarantool Cartridge de forma fácil e descontraída (parte 1)

Para executar o exemplo, precisaremos de Vagrant e Ansible (versões 2.8 ou superiores).

O papel em si está em Ansible Galaxy. É um repositório que permite compartilhar seus desenvolvimentos e usar papéis prontos.

Vamos clonar o repositório do exemplo:

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

Subindo as máquinas virtuais:

$ vagrant up

Instalando o papel ansible do Tarantool Cartridge:

$ ansible-galaxy install tarantool.cartridge,1.0.1

Executando o papel instalado:

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

Aguardando a conclusão da execução do playbook, vamos para http://localhost:8181/admin/cluster/dashboard e aproveitamos o resultado:

Implantando aplicativos no Tarantool Cartridge de forma fácil e descontraída (parte 1)

Podemos enviar dados. Legal, né?

Agora vamos entender como trabalhar com isso e, ao mesmo tempo, adicionar mais um replicaset à topologia.

Vamos começar a entender

Então, o que aconteceu?

Subimos duas máquinas virtuais e executamos um playbook do Ansible que configurou nosso cluster. Vamos dar uma olhada no conteúdo do arquivo 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

Nada interessante acontece aqui, estamos executando uma role do Ansible chamada tarantool.cartridge.

Tudo que é importante (ou seja, a configuração do cluster) está no inventory-arquivo 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:
    # GRUPAR INSTÂNCIAS POR MÁQUINAS
    host1:
      vars:
        # opções de conexão da primeira máquina
        ansible_host: 172.19.0.2
        ansible_user: vagrant

      hosts:  # instâncias a serem iniciadas na primeira máquina
        storage-1:

    host2:
      vars:
        # opções de conexão da segunda máquina
        ansible_host: 172.19.0.3
        ansible_user: vagrant

      hosts:  # instâncias a serem iniciadas na segunda máquina
        app-1:
        storage-1-replica:

    # GRUPAR INSTÂNCIAS POR REPLICA SETS
    replicaset_app_1:
      vars:  # configuração do replicaset
        replicaset_alias: app-1
        failover_priority:
          - app-1  # líder
        roles:
          - 'api'

      hosts:  # instâncias do replicaset
        app-1:

    replicaset_storage_1:
      vars:  # configuração do replicaset
        replicaset_alias: storage-1
        weight: 3
        failover_priority:
          - storage-1  # líder
          - storage-1-replica
        roles:
          - 'storage'

      hosts:   # instâncias do replicaset
        storage-1:
        storage-1-replica:

Tudo que precisamos é aprender a gerenciar instâncias e replicaset, alterando o conteúdo deste arquivo. A seguir, vamos adicionar novas seções a ele. Para não se perder, você pode dar uma olhada na versão final deste arquivo, hosts.updated.yml, que está no repositório de exemplo.

Gerenciamento de instâncias

Em termos do Ansible, cada instância é um host (não confundir com um servidor físico), ou seja, um nó de infraestrutura que o Ansible irá gerenciar. Para cada host, podemos especificar os parâmetros de conexão (como ansible_host e ansible_user), e também a configuração da instância. A descrição das instâncias está na seção hosts.

Vamos considerar a configuração da instância storage-1:

todos:
  vars:
    ...

  # INSTÂNCIAS
  hosts:
    storage-1:
      config:
        advertise_uri: '172.19.0.2:3301'
        http_port: 8181

  ...

Na variável config especificamos os parâmetros da instância — URI de anúncio e Porta HTTP.
Abaixo estão os parâmetros das instâncias app-1 e storage-1-replica.

Precisamos informar ao Ansible os parâmetros de conexão para cada instância. Faz sentido agrupar as instâncias em grupos de máquinas virtuais. Para isso, as instâncias foram unidas em grupos host1 e host2, e em cada grupo na seção vars estão especificados os valores ansible_host e ansible_user para uma máquina virtual. E na seção hosts — hosts (que são as instâncias) que pertencem a este grupo:

todos:
  vars:
    ...
  hosts:
    ...
  crianças:
    # AGRUPAR INSTÂNCIAS POR MÁQUINAS
    host1:
      vars:
        # opções de conexão da primeira máquina
        ansible_host: 172.19.0.2
        ansible_user: vagrant
       hosts:  # instâncias a serem iniciadas na primeira máquina
        storage-1:

     host2:
      vars:
        # opções de conexão da segunda máquina
        ansible_host: 172.19.0.3
        ansible_user: vagrant
       hosts:  # instâncias a serem iniciadas na segunda máquina
        app-1:
        storage-1-replica:

Começamos a modificar hosts.yml. Vamos adicionar mais duas instâncias, storage-2-replica na primeira máquina virtual e storage-2 na segunda:

todos:
  vars:
    ...

  # INSTÂNCIAS
  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

  crianças:
    # AGRUPAR INSTÂNCIAS POR MÁQUINAS
    host1:
      vars:
        ...
      hosts:  # instâncias a serem iniciadas na primeira máquina
        storage-1:
        storage-2-replica:  # <==

    host2:
      vars:
        ...
      hosts:  # instâncias a serem iniciadas na segunda máquina
        app-1:
        storage-1-replica:
        storage-2:  # <==
  ...

Executamos o playbook do ansible:

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

Observe a opção --limit. Como cada instância do cluster é um host em termos do Ansible, podemos especificar claramente quais instâncias devem ser configuradas ao executar o playbook.

Novamente, acesse a interface Web http://localhost:8181/admin/cluster/dashboard e veja nossas novas instâncias:

Implantando aplicativos no Tarantool Cartridge de forma fácil e descontraída (parte 1)

Não vamos parar por aqui e vamos dominar o gerenciamento da topologia.

Gerenciamento de topologia

Vamos agrupar nossas novas instâncias em um conjunto de réplicas storage-2. Vamos adicionar um novo grupo replicaset_storage_2 e descrever em suas variáveis os parâmetros do conjunto de réplicas, assim como em replicaset_storage_1. Na seção hosts especificaremos quais instâncias farão parte deste grupo (ou seja, nosso conjunto de réplicas):

---
all:
  vars:
    ...
  hosts:
    ...
  children:
    ...
    # AGRUPAR INSTÂNCIAS POR CONJUNTOS DE REPLICA
    ...
    replicaset_storage_2:  # <==
      vars:  # configuração do conjunto de replica
        replicaset_alias: storage-2
        weight: 2
        failover_priority:
          - storage-2
          - storage-2-replica
        roles:
          - 'storage'

      hosts:   # instâncias do conjunto de replica
        storage-2:
        storage-2-replica:

Iniciamos novamente o playbook:

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

No parâmetro --limit desta vez passamos o nome do grupo que corresponde ao nosso conjunto de replica.

Vamos considerar a opção tags.

Nossa função executa diferentes tarefas em sequência, que estão marcadas com as seguintes tags:

  • cartridge-instances: gerenciamento de instâncias (configuração, conexão ao membership);
  • cartridge-replicasets: gerenciamento de topologia (gerenciamento de conjuntos de replica e remoção não reversível (expel) de instâncias do cluster);
  • cartridge-config: gerenciamento de outros parâmetros do cluster (vshard bootstrapping, modo de failover automático, parâmetros de autorização e configuração do aplicativo).

Podemos especificar claramente qual parte do trabalho queremos realizar, e então a função ignorará a execução das demais tarefas. No nosso caso, queremos trabalhar apenas com a topologia, por isso especificamos cartridge-replicasets.

Vamos avaliar o resultado dos nossos esforços. Encontramos um novo conjunto de replica em http://localhost:8181/admin/cluster/dashboard.

Implantando aplicativos no Tarantool Cartridge de forma fácil e descontraída (parte 1)

Uhul!

Experimente alterar a configuração das instâncias e dos conjuntos de replica e veja como a topologia do cluster muda. Você pode testar diferentes cenários operacionais, como atualização gradual ou aumento de memtx_memory. A função tentará fazer isso sem reiniciar a instância, para minimizar o possível tempo de inatividade do seu aplicativo.

Não se esqueça de executar vagrant halt, para parar as máquinas virtuais quando terminar de trabalhar com elas.

E o que acontece por trás das cenas?

Aqui eu explicarei em mais detalhes o que aconteceu sob o capô da função ansible durante nossos experimentos.

Consideremos passo a passo a implantação do aplicativo Cartridge.

Instalação do pacote e início das instâncias

Primeiro, é necessário levar o pacote para o servidor e instalá-lo. Atualmente, a função consegue trabalhar com pacotes RPM e DEB.

Em seguida, iniciamos as instâncias. Aqui é muito simples: cada instância é um serviço separado. Vou explicar com um exemplo: systemd$ systemctl start myapp@storage-1

Este comando iniciará a instância

. A instância iniciada procurará seu storage-1 da aplicação myapp. Os logs da instância podem ser visualizados com configuração em /etc/tarantool/conf.d/O arquivo de unidade journald.

para o serviço systemd será entregue junto com o pacote. /etc/systemd/system/myapp@.sevice para o serviço systemd será entregue juntamente com o pacote.

O Ansible possui módulos integrados para instalação de pacotes e gerenciamento de serviços systemd, aqui não estamos inventando nada novo.

Configuração da topologia do cluster

E aqui começa a parte mais interessante. Concorda que seria estranho se preocupar com um papel ansible especial para instalar pacotes e iniciar systemd-serviços.

É possível configurar o cluster manualmente:

  • Primeira opção: abrimos a interface Web e clicamos nos botões. Para iniciar alguns instantes pontualmente, isso serve muito bem.
  • Segunda opção: podemos usar a API GraphQl. Aqui já é possível automatizar algo, por exemplo, escrever um script em Python.
  • Terceira opção (para os fortes de espírito): acessamos o servidor, conectamo-nos a um dos instantes usando tarantoolctl connect e fazemos todas as manipulações necessárias com o módulo Lua cartridge.

A principal tarefa da nossa invenção é fazer por você exatamente essa parte, a mais difícil do trabalho.

O Ansible permite que você escreva seu próprio módulo e o utilize em um papel. Nosso papel usa esses módulos para gerenciar vários componentes do cluster.

Como isso funciona? Você descreve o estado desejado do cluster em uma configuração declarativa, e o papel fornece a cada módulo sua seção de configuração. O módulo obtém o estado atual do cluster e o compara com o que foi enviado. Em seguida, através do soquete de um dos instantes, o código é iniciado para levar o cluster ao estado necessário.

Resultados

Hoje nós explicamos e mostramos como implantar seu aplicativo no Tarantool Cartridge e configurar uma topologia simples. Para isso, usamos o Ansible — uma ferramenta poderosa que se destaca pela simplicidade de uso e permite configurar simultaneamente múltiplos nós na infraestrutura (neste caso, os instantes do cluster).

Acima, entendemos um dos muitos modos de descrever a configuração do cluster usando o Ansible. Assim que você sentir que está pronto para avançar, estude as melhores práticas para escrever playbooks. Talvez seja mais conveniente gerenciar a topologia através de group_vars e host_vars.

Em breve, vamos explicar como remover de forma irreversível (expel) instantes da topologia, iniciar o vshard, gerenciar o modo de failover automático, configurar a autorização e corrigir a configuração do cluster. Mas, por enquanto, você pode estudar por conta própria. documentação e experimentar com as configurações do cluster.

Se algo não estiver funcionando, por favor nos avise sobre o problema. Resolveremos tudo rapidamente!

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster