Łatwe i naturalne wdrażanie aplikacji na kasecie Tarantool (część 1)

Łatwe i naturalne wdrażanie aplikacji na kasecie Tarantool (część 1)

Już rozmawialiśmy Nabój Tarantool, co pozwala na tworzenie aplikacji rozproszonych i ich pakowanie. Nie pozostało już nic: dowiedz się, jak wdrażać te aplikacje i zarządzać nimi. Nie martw się, pomyśleliśmy o wszystkim! Zebraliśmy i napisaliśmy wszystkie najlepsze praktyki dotyczące pracy z wkładem Tarantool ansible-role, który rozłoży pakiet na serwery, uruchomi instancje, połączy je w klaster, skonfiguruje autoryzację, załaduje vshard, włączy automatyczne przełączanie awaryjne i załata konfigurację klastra.

Ciekawy? Wtedy zapytam pod nacięciem, wszystko opowiemy i pokażemy.

Zacznijmy od przykładu

Omówimy tylko część funkcjonalności naszej roli. Zawsze możesz znaleźć pełny opis wszystkich jego funkcji i parametrów wejściowych dokumentacja. Ale lepiej spróbować raz, niż zobaczyć sto razy, więc wdrożmy małą aplikację.

Wkład Tarantool posiada instruktaż stworzyć małą aplikację Cartridge przechowującą informacje o klientach banku i ich rachunkach, a także udostępniającą API do zarządzania danymi poprzez HTTP. W tym celu aplikacja opisuje dwie możliwe role: api и storagektóre można przypisać do instancji.

Sam Cartridge nie mówi nic o tym, jak uruchomić procesy, daje jedynie możliwość konfiguracji już działających instancji. Użytkownik musi sam wykonać resztę: rozłożyć pliki konfiguracyjne, uruchomić usługi i skonfigurować topologię. Ale tego wszystkiego nie zrobimy my, zrobi to za nas Ansible.

Od słów do czynów

Wdróżmy więc naszą aplikację na dwóch maszynach wirtualnych i skonfigurujmy prostą topologię:

  • Zestaw replik app-1 zagra rolę apico obejmuje tę rolę vshard-router. Tutaj będzie tylko jeden przypadek.
  • zestaw replik storage-1 realizuje rolę storage (i w tym samym czasie vshard-storage), tutaj dodajemy dwie instancje z różnych maszyn.

Łatwe i naturalne wdrażanie aplikacji na kasecie Tarantool (część 1)

Aby uruchomić przykład, potrzebujemy Włóczęga и Wiarygodne (wersja 2.8 lub nowsza).

Sama rola jest Galaktyka ansible. To repozytorium, które pozwala dzielić się swoją pracą i korzystać z gotowych ról.

Sklonuj repozytorium na przykładzie:

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

Podnosimy maszyny wirtualne:

$ vagrant up

Zainstaluj rolę ansible Tarantool Cartridge:

$ ansible-galaxy install tarantool.cartridge,1.0.1

Uruchom zainstalowaną rolę:

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

Czekamy na koniec wykonywania podręcznika, przejdź do http://localhost:8181/admin/cluster/dashboard i ciesz się efektem:

Łatwe i naturalne wdrażanie aplikacji na kasecie Tarantool (część 1)

Można wlać dane. Fajnie, prawda?

Teraz zastanówmy się, jak z tym pracować, jednocześnie dodając do topologii kolejny zestaw replik.

Zaczynamy rozumieć

Więc co się stało?

Mamy dwie maszyny wirtualne, na których działa podręcznik ansible, który konfiguruje nasz klaster. Przyjrzyjmy się zawartości pliku 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

Nic ciekawego się tu nie dzieje, rozpoczynamy rolę ansible, która nazywa się tarantool.cartridge.

Wszystko najważniejsze (mianowicie konfiguracja klastra) znajduje się w inwentarz-plik 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:

Wszystko, czego potrzebujemy, to nauczyć się zarządzać instancjami i zestawami replik, zmieniając zawartość tego pliku. Następnie dodamy do niego nowe sekcje. Aby nie pomylić się, gdzie je dodać, możesz zajrzeć do ostatecznej wersji tego pliku, hosts.updated.yml, który znajduje się w przykładowym repozytorium.

Zarządzanie instancjami

W Ansible każda instancja jest hostem (nie mylić z serwerem żelaznym), tj. węzeł infrastruktury, którym będzie zarządzał Ansible. Dla każdego hosta możemy określić parametry połączenia (np ansible_host и ansible_user), a także konfigurację instancji. Opis instancji znajduje się w dziale hosts.

Rozważ konfigurację instancji storage-1:

all:
  vars:
    ...

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

  ...

W zmiennej config określiliśmy parametry instancji - advertise URI и HTTP port.
Poniżej znajdują się parametry instancji app-1 и storage-1-replica.

Musimy przekazać Ansible parametry połączenia dla każdej instancji. Logiczne wydaje się grupowanie instancji w grupy maszyn wirtualnych. W tym celu instancje łączy się w grupy. host1 и host2oraz w każdej grupie w sekcji vars wartości ansible_host и ansible_user dla jednej maszyny wirtualnej. I w dziale hosts - hosty (są to instancje) zaliczane do tej grupy:

all:
  vars:
    ...
  hosts:
    ...
  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:

Zaczynamy się zmieniać hosts.yml. Dodajmy jeszcze dwa przypadki, storage-2-replica na pierwszej maszynie wirtualnej i storage-2 Na drugim:

all:
  vars:
    ...

  # INSTANCES
  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:
    # GROUP INSTANCES BY MACHINES
    host1:
      vars:
        ...
      hosts:  # instances to be started on the first machine
        storage-1:
        storage-2-replica:  # <==

    host2:
      vars:
        ...
      hosts:  # instances to be started on the second machine
        app-1:
        storage-1-replica:
        storage-2:  # <==
  ...

Uruchom podręcznik anible:

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

Zwróć uwagę na opcję --limit. Ponieważ każda instancja klastra jest hostem w rozumieniu Ansible, możemy jawnie określić, które instancje powinny zostać skonfigurowane podczas uruchamiania podręcznika.

Powrót do interfejsu internetowego http://localhost:8181/admin/cluster/dashboard i obserwuj nasze nowe instancje:

Łatwe i naturalne wdrażanie aplikacji na kasecie Tarantool (część 1)

Nie spoczniemy na laurach i opanujemy sterowanie topologią.

Zarządzanie topologią

Połączmy nasze nowe instancje w zestaw replik storage-2. Dodaj nową grupę replicaset_storage_2 i opisz w jego zmiennych parametry zestawu replik przez analogię do replicaset_storage_1. W sekcji hosts określ, które instancje zostaną uwzględnione w tej grupie (czyli naszym zestawie replik):

---
all:
  vars:
    ...
  hosts:
    ...
  children:
    ...
    # GROUP INSTANCES BY REPLICA SETS
    ...
    replicaset_storage_2:  # <==
      vars:  # replicaset configuration
        replicaset_alias: storage-2
        weight: 2
        failover_priority:
          - storage-2
          - storage-2-replica
        roles:
          - 'storage'

      hosts:   # replicaset instances
        storage-2:
        storage-2-replica:

Zacznijmy od nowa podręcznik:

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

Według parametru --limit tym razem przekazaliśmy nazwę grupy odpowiadającej naszemu zestawowi replik.

Rozważ tę opcję tags.

Nasza rola sekwencyjnie wykonuje różne zadania, które oznaczone są następującymi tagami:

  • cartridge-instances: zarządzanie instancjami (konfiguracja, połączenie z członkostwem);
  • cartridge-replicasets: zarządzanie topologią (zarządzanie replikatorami i trwałe usuwanie (wyrzucanie) instancji z klastra);
  • cartridge-config: zarządzaj innymi parametrami klastra (ładowanie vshard, automatyczny tryb przełączania awaryjnego, parametry autoryzacji i konfiguracja aplikacji).

Możemy jawnie określić jaką część pracy chcemy wykonać, wtedy rola pominie resztę zadań. W naszym przypadku chcemy pracować tylko z topologią, więc to określiliśmy cartridge-replicasets.

Oceńmy wynik naszych wysiłków. Znalezienie nowego zestawu replik http://localhost:8181/admin/cluster/dashboard.

Łatwe i naturalne wdrażanie aplikacji na kasecie Tarantool (część 1)

Hooray!

Poeksperymentuj z rekonfiguracją instancji i zestawów replik i zobacz, jak zmienia się topologia klastra. Możesz wypróbować różne scenariusze operacyjne, na przykład aktualizacja krocząca lub zwiększyć memtx_memory. Rola spróbuje to zrobić bez ponownego uruchamiania instancji, aby skrócić możliwy przestój aplikacji.

Nie zapomnij biegać vagrant haltaby zatrzymać maszyny wirtualne, gdy już z nimi skończysz.

A co jest pod maską?

Tutaj opowiem więcej o tym, co wydarzyło się pod maską roli ansible podczas naszych eksperymentów.

Przyjrzyjmy się krok po kroku wdrażaniu aplikacji Cartridge.

Instalacja pakietu i uruchomienie instancji

Najpierw musisz dostarczyć pakiet na serwer i zainstalować go. Teraz rola może współpracować z pakietami RPM i DEB.

Następnie uruchamiamy instancje. Tutaj wszystko jest bardzo proste: każda instancja jest osobna systemd-praca. Mówię o przykładzie:

$ systemctl start myapp@storage-1

To polecenie uruchomi instancję storage-1 приложения myapp. Uruchomiona instancja będzie szukać swojego konfiguracja в /etc/tarantool/conf.d/. Dzienniki instancji można przeglądać za pomocą journald.

Plik jednostki /etc/systemd/system/[email protected] dla usługi systemowej zostaną dostarczone wraz z pakietem.

Ansible ma wbudowane moduły do ​​instalowania pakietów i zarządzania usługami systemowymi, nie wymyśliliśmy tu niczego nowego.

Konfiguracja topologii klastra

I tu zaczyna się najciekawsze. Zgadzam się, byłoby dziwnie zawracać sobie głowę specjalną rolą ansible do instalowania pakietów i uruchamiania systemd-usługi.

Klaster możesz skonfigurować ręcznie:

  • Pierwsza opcja: otwórz interfejs WWW i kliknij przyciski. W przypadku jednorazowego uruchomienia kilku instancji jest to całkiem odpowiednie.
  • Druga opcja: możesz użyć API GraphQl. Tutaj możesz już coś zautomatyzować, na przykład napisać skrypt w Pythonie.
  • Opcja trzecia (dla mocnych duchem): wejdź na serwer, połącz się z jedną z instancji za pomocą tarantoolctl connect i wykonaj wszystkie niezbędne manipulacje za pomocą modułu Lua cartridge.

Głównym zadaniem naszego wynalazku jest wykonanie dla Ciebie tej najtrudniejszej części pracy.

Ansible pozwala na napisanie własnego modułu i użycie go w roli. Nasza rola wykorzystuje te moduły do ​​zarządzania różnymi komponentami klastra.

Jak to działa? Żądany stan klastra opisujesz w konfiguracji deklaratywnej, a rola zapewnia każdemu modułowi sekcję konfiguracyjną jako dane wejściowe. Moduł odbiera aktualny stan klastra i porównuje go z sygnałem wejściowym. Następnie przez gniazdo jednej z instancji uruchamiany jest kod, który doprowadza klaster do pożądanego stanu.

Wyniki

Dzisiaj opowiedzieliśmy i pokazaliśmy, jak wdrożyć aplikację na Tarantool Cartridge i skonfigurować prostą topologię. W tym celu wykorzystaliśmy Ansible, potężne narzędzie, które jest proste w obsłudze i pozwala na jednoczesną konfigurację wielu węzłów infrastruktury (w naszym przypadku są to instancje klastrowe).

Powyżej omówiliśmy jeden z wielu sposobów opisu konfiguracji klastra za pomocą Ansible. Kiedy już wiesz, że jesteś gotowy, aby przejść dalej, ucz się Najlepsze praktyki do pisania podręczników. Zarządzanie topologią może okazać się wygodniejsze group_vars и host_vars.

Już wkrótce powiemy Ci jak trwale usunąć (wyrzucić) instancje z topologii, załadować vshard, zarządzać automatycznym trybem przełączania awaryjnego, skonfigurować autoryzację i załatać konfigurację klastra. W międzyczasie możesz uczyć się samodzielnie dokumentacja i eksperymentuj ze zmianą parametrów klastra.

Jeśli coś nie działa, upewnij się poinformować nam o problemie. Szybko to rozwiążemy!

Źródło: www.habr.com

Dodaj komentarz