Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Cześć wszystkim! W ramach zajęć badałem możliwości takiej domowej platformy chmurowej jak Yandex.Cloud. Platforma oferuje różne usługi rozwiązywania praktycznych problemów. Czasami jednak trzeba założyć własną aplikację chmurową z dość rozbudowaną infrastrukturą opartą na tych usługach. W tym artykule chcę podzielić się swoim doświadczeniem we wdrażaniu takiej aplikacji.

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Co chcesz otrzymać?

grafana — potężne narzędzie do rozwiązywania problemów analitycznych lub problemów monitorowania dowolnych systemów. W podstawowej konfiguracji jest to maszyna wirtualna z serwerem WWW Grafana, a także bazą danych (ClickHouse, InfluxDB itp.) zawierającą zbiór danych, na którym będzie oparta analityka.

Po uruchomieniu maszyny wirtualnej z serwerem WWW możesz udać się na jej host i uzyskać piękny interfejs użytkownika, określić bazy danych jako źródła dalszej pracy, stworzyć dashboardy i wykresy.

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Podstawowa wersja ma jedną istotną wadę – nie jest w ogóle odporna na błędy. Oznacza to, że cała funkcjonalność aplikacji zależy od wydajności jednej maszyny wirtualnej. Jeśli odmówi lub 10 osób otworzy interfejs użytkownika w tym samym czasie, pojawią się problemy.

Można je rozwiązać w prosty sposób: wystarczy... wdrożyć wiele identycznych maszyn wirtualnych z serwerem WWW i umieścić je pod balanserem L3. Ale nie wszystko jest tutaj takie jasne. Grafana przechowuje ustawienia użytkownika (ścieżki do baz danych, dashboardów, wykresów itp.) bezpośrednio na dysku swojej maszyny wirtualnej. Tym samym, jeśli zmienimy jakieś ustawienia w interfejsie użytkownika, zmiany te odzwierciedlą się tylko na maszynie wirtualnej, do której przysłał nas balanser. Doprowadzi to do niespójnych ustawień naszej aplikacji, powodując problemy z uruchomieniem i użytkowaniem.

Tutaj na ratunek przyjdzie inna baza danych, na przykład MySQL lub jej odpowiednik. Mówimy Grafanie, że powinna przechowywać ustawienia użytkownika w tej „zapasowej” bazie danych. Następnie wystarczy podać ścieżkę do tej bazy danych raz na każdej maszynie i edytować wszystkie pozostałe ustawienia użytkownika na dowolnej z maszyn wirtualnych, zostaną one rozszerzone na pozostałe.

Oto schemat ostatecznej infrastruktury aplikacji:

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Nauczmy się podnosić rękami

MySQL i ClickHouse

Przed wdrożeniem takiej aplikacji jednym kliknięciem należało nauczyć się obsługi każdego z jej komponentów i zintegrować je ze sobą.

Tutaj pomoże nam Yandex.Cloud, który udostępnia balansery L3, ClickHouse i MySQL jako usługi zarządzane. Użytkownik musi jedynie określić parametry i poczekać, aż platforma przywróci wszystko do stanu używalności.

Zarejestrowałem się, założyłem chmurę i konto płatnicze. Następnie udałem się do chmury i skonfigurowałem klastry MySQL i ClickHouse z minimalnymi ustawieniami. Poczekałem, aż się uaktywnią.

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie GrafanyWdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Należy także pamiętać o stworzeniu w każdym klastrze bazy danych i skonfigurowaniu dostępu do niej za pomocą loginu i hasła. Nie będę się tutaj wdawał w szczegóły – w interfejsie wszystko jest dość oczywiste.

Nieoczywistym szczegółem było to, że te bazy danych mają wiele hostów, co zapewnia ich odporność na awarie. Jednakże Grafana wymaga dokładnie jednego hosta dla każdej bazy danych, z którą współpracuje. Długie czytanie dokumentacja Chmury skłoniły mnie do podjęcia decyzji. Okazuje się, że żywiciel gatunku c-<cluster_id>.rw.mdb.yandexcloud.net zamapowany na bieżącego aktywnego głównego hosta klastra z odpowiednim identyfikatorem. To właśnie przekażemy Grafanie.

serwer internetowy

Teraz wszystko zależy od serwera WWW. Stwórzmy zwykłą maszynę wirtualną z Linuksem i ręcznie skonfigurujmy na niej Grafanę.

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Połączmy się przez ssh i zainstalujmy niezbędne pakiety.

sudo apt-get install -y apt-transport-https software-properties-common wget
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo add-apt-repository "deb https://packages.grafana.com/enterprise/deb stable main"
sudo apt-get update
sudo apt-get install -y grafana-enterprise 

Następnie uruchommy Grafanę pod systemctl i zainstalujmy wtyczkę do pracy z ClickHouse (tak, nie jest ona dostarczana w pakiecie podstawowym).

sudo systemctl start grafana-server
sudo systemctl enable grafana-server
sudo grafana-cli plugins install vertamedia-clickhouse-datasource

To wszystko, potem za pomocą prostego polecenia

sudo service grafana-server start

uruchomimy serwer WWW. Teraz możesz wpisać w przeglądarce zewnętrzny adres IP maszyny wirtualnej, określić port 3000 i zobaczyć piękny interfejs Grafana.
Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Ale nie spiesz się, przed skonfigurowaniem Grafany musisz pamiętać o podaniu mu ścieżki do MySQL, aby mógł tam zapisać ustawienia.

Cała konfiguracja serwera WWW Grafana znajduje się w pliku /etc/grafana/grafana.ini. Wymagana linia wygląda następująco:

;url =

Ustawiamy hosta na klaster MySQL. W tym samym pliku znajduje się login i hasło dostępu do Grafany z powyższego obrazka, które domyślnie są sobie równe admin.

Możesz użyć poleceń sed:

sudo sed -i "s#.*;url =.*#url = mysql://${MYSQL_USERNAME}:${MYSQL_PASSWORD}@${MYSQL_CLUSTER_URI}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_user =.*#admin_user = ${GRAFANA_USERNAME}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_password =.*#admin_password = ${GRAFANA_PASSWORD}#" /etc/grafana/grafana.ini

Czas zrestartować serwer WWW!

sudo service grafana-server restart

Teraz w interfejsie Grafana określimy ClickHouse jako źródło danych.

Udało mi się uzyskać działającą konfigurację z następującymi ustawieniami:

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Podałem jako adres URL https://c-<cluster_id>.rw.mdb.yandexcloud.net:8443

Wszystko! Mamy jedną działającą maszynę wirtualną z serwerem WWW podłączonym do CH i MySQL. Możesz już przesłać zbiór danych do ClickHouse i zbudować dashboardy. Jednak nie osiągnęliśmy jeszcze celu i nie wdrożyliśmy pełnoprawnej infrastruktury.

Pakowacz

Yandex.Cloud umożliwia utworzenie obrazu dysku istniejącej maszyny wirtualnej, a na jego podstawie - dowolnej liczby identycznych maszyn. Właśnie tego będziemy używać. Aby wygodnie złożyć obraz, weź narzędzie Pakowacz z HashiCorp. Jako dane wejściowe pobierany jest plik json z instrukcjami montażu obrazu.

Nasz plik json będzie składał się z dwóch bloków: konstruktorów i dostawców. Pierwszy blok opisuje parametry samego obrazu jako całości, natomiast drugi blok opisuje instrukcje wypełnienia go niezbędną treścią.

Konstruktorzy

{
"builders": [
    {
      "type": "yandex",
      "endpoint": "{{user `endpoint`}}",
      "folder_id": "<folder_id>",
      "subnet_id": "{{user `subnet_id`}}",
      "zone": "{{user `zone`}}",
      "labels": {},
      "use_ipv4_nat": true,
      "use_internal_ip": false,
      "service_account_key_file": "<service_account_key_file>",
      "image_name": "grafana-{{timestamp}}",
      "image_family": "grafana",
      "image_labels": {},
      "image_description": "GRAFANA",
      "source_image_family": "ubuntu-1804-lts",
      "disk_size_gb": 3,
      "disk_type": "network-hdd",
      "ssh_username": "ubuntu"
    }
  ],
...
}

W tym szablonie należy ustawić identyfikator sekcji w chmurze, w której chcesz utworzyć obraz, a także ścieżkę do pliku z kluczami z konta usługi utworzonego wcześniej w tej sekcji. Więcej o tworzeniu kont usług i kluczy w formie pliku przeczytasz w odpowiednim dziale dokumentacja.

Ta konfiguracja mówi, że obraz dysku zostanie zbudowany w oparciu o platformę ubuntu-1804-lts, umieszczony w odpowiedniej sekcji użytkownika w rodzinie obrazów GRAFANA pod imieniem grafana-{{timestamp}}.

Zaopatrzenie

Teraz następuje bardziej interesująca część konfiguracji. Opisze sekwencję działań, które należy wykonać na maszynie wirtualnej przed zamrożeniem jej stanu w obrazie dysku.

{
...,
"provisioners": [
    {
            "type": "shell",
            "pause_before": "5s",
            "scripts": [
                "prepare-ctg.sh"
            ]
        },
    {
            "type": "file",
            "source": "setup.sh",
            "destination": "/opt/grafana/setup.sh"
        },
        {
            "type": "shell",
        "execute_command": "sudo {{ .Vars }} bash '{{ .Path }}'",
            "pause_before": "5s",
            "scripts": [
                "install-packages.sh",
                "grafana-setup.sh",
                "run-setup-at-reboot.sh"
        ]
        }
  ]
}

Tutaj wszystkie działania są podzielone na 3 etapy. W pierwszym etapie wykonywany jest prosty skrypt tworzący katalog pomocniczy.

przygotuj-ctg.sh:

#!/bin/bash
sudo mkdir -p /opt/grafana
sudo chown -R ubuntu:ubuntu /opt/grafana

W kolejnym etapie umieszczamy w tym katalogu skrypt, który trzeba będzie uruchomić od razu po uruchomieniu maszyny wirtualnej. Ten skrypt umieści zmienne użytkownika, które należy zarejestrować w konfiguracji Grafany i zrestartuje serwer WWW.

setup.sh:

#!/bin/bash
CLUSTER_ID="<cluster_id>"
USERNAME="<username>"
PASSWORD="<password>"
sudo sed -i "s#.*;url =.*#url = mysql://${USERNAME}:${PASSWORD}@c-${CLUSTER_ID}.rw.mdb.yandexcloud.net#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_user =.*#admin_user = ${USERNAME}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_password =.*#admin_password = ${PASSWORD}#" /etc/grafana/grafana.ini
sudo service grafana-server restart

Po tym pozostają 3 rzeczy do zrobienia:
1) zainstaluj pakiety
2) uruchom Grafanę w systemiectl i zainstaluj wtyczkę ClickHouse
3) natychmiast po włączeniu maszyny wirtualnej umieść skrypt setup.sh w kolejce uruchamiania.

install-packages.sh:

#!/bin/bash
sudo systemd-run --property='After=apt-daily.service apt-daily-upgrade.service' --wait /bin/true
sudo apt-get install -y apt-transport-https
sudo apt-get install -y software-properties-common wget
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo add-apt-repository "deb https://packages.grafana.com/enterprise/deb stable main"
sudo apt-get update
sudo apt-get install -y grafana-enterprise 

grafana-setup.sh:

#!/bin/bash
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
sudo grafana-cli plugins install vertamedia-clickhouse-datasource

uruchom-setup-at-reboot.sh:

#!/bin/bash
chmod +x /opt/grafana/setup.sh
cat > /etc/cron.d/first-boot <<EOF
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
@reboot root /bin/bash /opt/grafana/setup.sh > /var/log/yc-setup.log 2>&1
EOF
chmod +x /etc/cron.d/first-boot;

Teraz pozostaje tylko uruchomić Packera i umieścić obraz wyjściowy w określonej sekcji. Tworząc maszynę wirtualną, możesz wybrać ją jako dysk startowy, a po uruchomieniu otrzymasz gotowy serwer WWW Grafana.

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany
Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Grupa instancji i moduł równoważący

Kiedy już mamy obraz dysku, który pozwala nam utworzyć wiele identycznych serwerów internetowych Grafana, możemy utworzyć grupę instancji. Na platformie Yandex.Cloud termin ten odnosi się do połączenia maszyn wirtualnych o tych samych cechach. Podczas tworzenia grupy instancji konfigurowany jest prototyp wszystkich maszyn w tej grupie, a następnie charakterystyka samej grupy (np. minimalna i maksymalna liczba aktywnych maszyn). Jeśli aktualna liczba nie spełnia tych kryteriów, wówczas grupa instancji sama usunie niepotrzebne maszyny lub utworzy nowe na swój własny obraz.

W ramach naszego zadania utworzymy grupę instancji serwerów WWW, która zostanie wygenerowana z wcześniej utworzonego obrazu dysku.

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

To, co jest naprawdę niezwykłe, to ostatnia konfiguracja grupy instancji. Grupa docelowa w integracji z Load Balancer pomoże Ci skonfigurować balanser L3 na maszynach wirtualnych tej grupy poprzez kliknięcie kilku przycisków.

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Konfigurując balanser zaimplementowałem dwa ważne punkty:

  1. Sprawiłem, że balanser akceptował ruch użytkowników na porcie 80 i przekierowywał go na port 3000 maszyn wirtualnych, dokładnie tam, gdzie mieszka Grafana.
  2. Skonfigurowałem sprawdzanie żywotności maszyn poprzez pingowanie ich do portu 3000.

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Mini podsumowanie

Wreszcie udało nam się ręcznie wdrożyć żądaną infrastrukturę aplikacji i teraz mamy wysoce odporną usługę Grafana. Wystarczy znać adres IP balansera jako punktu wejścia do aplikacji oraz hosta klastra ClickHouse, aby załadować do niego zbiór danych.

Wydawałoby się, że to zwycięstwo? Tak, zwycięstwo. Ale coś wciąż mnie niepokoi. Cały powyższy proces wymaga wielu ręcznych kroków i nie jest w ogóle skalowalny; chciałbym go zautomatyzować, jeśli to możliwe. Temu poświęcona będzie następna część.

Integracja z Terraformem

Po raz kolejny skorzystamy z narzędzia firmy HashiCorp o nazwie Terraform. Pomoże Ci wdrożyć całą infrastrukturę aplikacji jednym kliknięciem, w oparciu o kilka zmiennych przekazanych przez użytkownika. Napiszmy przepis, który można uruchomić wielokrotnie w różnych sekcjach różnych użytkowników.

Cała praca z Terraformem sprowadza się do zapisania pliku konfiguracyjnego (*.tf) i tworzenie w oparciu o nią infrastruktury.

Zmienne

Na samym początku pliku umieścimy zmienne określające, gdzie i w jaki sposób będzie wdrażana przyszła infrastruktura.

variable "oauth_token" {
    type = string
    default = "<oauth-token>"
}
variable "cloud_id" {
    type = string
    default = "<cloud-id>"
}
variable "folder_id" {
    type = string
    default = "<folder_id>"
}
variable "service_account_id" {
    type = string
    default = "<service_account_id>"
}
variable "image_id" {
    type = string
    default = "<image_id>"
}
variable "username" {
    type = string
    default = "<username>"
}
variable "password" {
    type = string
    default = "<password>"
}
variable "dbname" {
    type = string
    default = "<dbname>"
}
variable "public_key_path" {
    type = string
    default = "<path to ssh public key>"
}

Cały proces wdrażania aplikacji sprowadza się do zbudowania obrazu dysku i ustawienia tych zmiennych. Wyjaśnię za co odpowiadają:

token_oauth — token umożliwiający dostęp do chmury. Można uzyskać przez powiązanie.
identyfikator_chmury — identyfikator chmury, w której wdrożymy aplikację
identyfikator_folderu — identyfikator sekcji, w której będziemy wdrażać aplikację
identyfikator_konta_usługi — identyfikator konta usługi w odpowiedniej sekcji chmury.
identyfikator_obrazu — identyfikator obrazu dysku uzyskany za pomocą programu Packer
nazwa użytkownika и password — nazwa użytkownika i hasło umożliwiające dostęp do obu baz danych i serwera internetowego Grafana
nazwa_bazy — nazwa bazy danych wewnątrz klastrów CH i MySQL
ścieżka_klucza_publicznego — ścieżka do pliku z Twoim publicznym kluczem ssh, za pomocą którego możesz się połączyć pod nazwą ubuntu do maszyn wirtualnych z serwerami WWW

Konfiguracja dostawcy

Teraz musisz skonfigurować dostawcę Terraform - w naszym przypadku Yandex:

provider "yandex" {
  token     = var.oauth_token
  cloud_id  = var.cloud_id
  folder_id = var.folder_id
  zone      = "ru-central1-a"
}

Zauważysz, że tutaj używamy zmiennych zdefiniowanych powyżej.

Sieć i klastry

Teraz utworzymy sieć, w której będą się komunikować elementy naszej infrastruktury, trzy podsieci (po jednej w każdym regionie) oraz wyhodujemy klastry CH i MySQL.


resource "yandex_vpc_network" "grafana_network" {}

resource "yandex_vpc_subnet" "subnet_a" {
  zone           = "ru-central1-a"
  network_id     = yandex_vpc_network.grafana_network.id
  v4_cidr_blocks = ["10.1.0.0/24"]
}

resource "yandex_vpc_subnet" "subnet_b" {
  zone           = "ru-central1-b"
  network_id     = yandex_vpc_network.grafana_network.id
  v4_cidr_blocks = ["10.2.0.0/24"]
}

resource "yandex_vpc_subnet" "subnet_c" {
  zone           = "ru-central1-c"
  network_id     = yandex_vpc_network.grafana_network.id
  v4_cidr_blocks = ["10.3.0.0/24"]
}

resource "yandex_mdb_clickhouse_cluster" "ch_cluster" {
  name        = "grafana-clickhouse"
  environment = "PRODUCTION"
  network_id  = yandex_vpc_network.grafana_network.id

  clickhouse {
    resources {
      resource_preset_id = "s2.micro"
      disk_type_id       = "network-ssd"
      disk_size          = 16
    }
  }

  zookeeper {
    resources {
      resource_preset_id = "s2.micro"
      disk_type_id       = "network-ssd"
      disk_size          = 10
    }
  }

  database {
    name = var.dbname
  }

  user {
    name     = var.username
    password = var.password
    permission {
      database_name = var.dbname
    }
  }

  host {
    type      = "CLICKHOUSE"
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }

  host {
    type      = "CLICKHOUSE"
    zone      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }

  host {
    type      = "CLICKHOUSE"
    zone      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }

  host {
    type      = "ZOOKEEPER"
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }

  host {
    type      = "ZOOKEEPER"
    zone      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }

  host {
    type      = "ZOOKEEPER"
    zone      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }
}

resource "yandex_mdb_mysql_cluster" "mysql_cluster" {
  name        = "grafana_mysql"
  environment = "PRODUCTION"
  network_id  = yandex_vpc_network.grafana_network.id
  version     = "8.0"

  resources {
    resource_preset_id = "s2.micro"
    disk_type_id       = "network-ssd"
    disk_size          = 16
  }

  database {
    name = var.dbname
  }

  user {
    name     = var.username
    password = var.password
    permission {
      database_name = var.dbname
      roles         = ["ALL"]
    }
  }

  host {
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }
  host {
    zone      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }
  host {
    zone      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }
}

Jak widać, każdy z dwóch klastrów jest dość odporny na awarie, ponieważ jest zlokalizowany w trzech strefach dostępności.

Serwery internetowe

Wydawałoby się, że moglibyśmy kontynuować w tym samym duchu, ale napotkałem trudności. Wcześniej najpierw wywołałem klaster MySQL i dopiero potem znając jego ID zebrałem obraz dysku z wymaganą konfiguracją, gdzie podałem hosta dla klastra. Ale teraz nie znamy identyfikatora klastra przed uruchomieniem Terraforma, w tym w momencie budowania obrazu. Dlatego musiałem zastosować się do poniższych sztuczka.

Korzystając z usługi metadanych Amazon, przekażemy maszynie wirtualnej pewne parametry, które ona zaakceptuje i przetworzy. Potrzebujemy, aby maszyna przeszła do metadanych znajdujących się za hostem klastra MySQL i nazwą użytkownika-hasłem, które użytkownik określił w pliku Terraform po uruchomieniu. Zmieńmy nieco zawartość pliku setup.sh, który działa po włączeniu maszyny wirtualnej.

setup.sh:

#!/bin/bash
CLUSTER_URI="$(curl -H 'Metadata-Flavor:Google' http://169.254.169.254/computeMetadata/v1/instance/attributes/mysql_cluster_uri)"
USERNAME="$(curl -H 'Metadata-Flavor:Google' http://169.254.169.254/computeMetadata/v1/instance/attributes/username)"
PASSWORD="$(curl -H 'Metadata-Flavor:Google' http://169.254.169.254/computeMetadata/v1/instance/attributes/password)"
sudo sed -i "s#.*;url =.*#url = mysql://${USERNAME}:${PASSWORD}@${CLUSTER_URI}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_user =.*#admin_user = ${USERNAME}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_password =.*#admin_password = ${PASSWORD}#" /etc/grafana/grafana.ini
sudo service grafana-server restart

Grupa Intance i balanser

Po przebudowaniu nowego obrazu dysku możemy wreszcie dodać nasz plik do Terraforma.

Wskażmy, że chcemy użyć istniejącego obrazu dysku:

data "yandex_compute_image" "grafana_image" {
  image_id = var.image_id
}

Utwórzmy teraz grupę instancji:

resource "yandex_compute_instance_group" "grafana_group" {
  name               = "grafana-group"
  folder_id          = var.folder_id
  service_account_id = var.service_account_id
  instance_template {
    platform_id = "standard-v1"
    resources {
      memory = 1
      cores  = 1
    }
    boot_disk {
      mode = "READ_WRITE"
      initialize_params {
        image_id = data.yandex_compute_image.grafana_image.id
        size     = 4
      }
    }
    network_interface {
      network_id = yandex_vpc_network.grafana_network.id
      subnet_ids = [yandex_vpc_subnet.subnet_a.id, yandex_vpc_subnet.subnet_b.id, yandex_vpc_subnet.subnet_c.id]
      nat = "true"
    }
    metadata = {
      mysql_cluster_uri = "c-${yandex_mdb_mysql_cluster.mysql_cluster.id}.rw.mdb.yandexcloud.net:3306/${var.dbname}"
      username = var.username
      password = var.password
      ssh-keys = "ubuntu:${file("${var.public_key_path}")}"
    }
    network_settings {
      type = "STANDARD"
    }
  }

  scale_policy {
    fixed_scale {
      size = 6
    }
  }

  allocation_policy {
    zones = ["ru-central1-a", "ru-central1-b", "ru-central1-c"]
  }

  deploy_policy {
    max_unavailable = 2
    max_creating    = 2
    max_expansion   = 2
    max_deleting    = 2
  }

  load_balancer {
    target_group_name = "grafana-target-group"
  }
}

Warto zwrócić uwagę na to, w jaki sposób przekazaliśmy to do metadanych cluster_uri, username и password. To właśnie one zostaną pobrane przez maszynę wirtualną podczas uruchamiania i umieszczone w konfiguracji Grafany.

To zależy od balansera.

resource "yandex_lb_network_load_balancer" "grafana_balancer" {
  name = "grafana-balancer"

  listener {
    name = "grafana-listener"
    port = 80
    target_port = 3000
    external_address_spec {
      ip_version = "ipv4"
    }
  }

  attached_target_group {
    target_group_id = yandex_compute_instance_group.grafana_group.load_balancer.0.target_group_id

    healthcheck {
      name = "healthcheck"
      tcp_options {
        port = 3000
      }
    }
  }
}

trochę cukru

Zostało tylko trochę. Po wdrożeniu infrastruktury będziesz musiał przejść do interfejsu użytkownika Grafany i ręcznie dodać klaster CH (którego identyfikator nadal wymaga uzyskania) jako źródło danych. Ale Terraform zna identyfikator klastra. Powierzmy mu doprowadzenie sprawy do skutku.

Dodajmy nowego dostawcę - Grafanę i podajmy jej adres IP balansera jako hosta. Wszystkie zmiany wprowadzone przez Terraform na maszynie, którą określa jego balanser, będą rosły w MySQL, a zatem na wszystkich innych maszynach.

provider "grafana" {
  url  = "http://${[for s in yandex_lb_network_load_balancer.grafana_balancer.listener: s.external_address_spec.0.address].0}"
  auth = "${var.username}:${var.password}"
}

resource "grafana_data_source" "ch_data_source" {
  type          = "vertamedia-clickhouse-datasource"
  name          = "grafana"
  url           = "https://c-${yandex_mdb_clickhouse_cluster.ch_cluster.id}.rw.mdb.yandexcloud.net:8443"
  basic_auth_enabled = "true"
  basic_auth_username = var.username
  basic_auth_password = var.password
  is_default = "true"
  access_mode = "proxy"
}

Czeszemy włosy

Wyświetlmy adres IP modułu równoważącego i hosta klastra ClickHouse

output "grafana_balancer_ip_address" {
  value = [for s in yandex_lb_network_load_balancer.grafana_balancer.listener: s.external_address_spec.0.address].0
}

output "clickhouse_cluster_host" {
  value = "https://c-${yandex_mdb_clickhouse_cluster.ch_cluster.id}.rw.mdb.yandexcloud.net:8443"
}

Można uruchomić

Wszystko! Nasz plik konfiguracyjny jest gotowy i możemy ustawiając zmienne nakazać Terraformowi podniesienie wszystkiego, co opisaliśmy powyżej. Cały proces zajął mi około 15 minut.
Na koniec możesz zobaczyć piękną wiadomość:

Apply complete! Resources: 9 added, 0 changed, 0 destroyed.
Outputs:

clickhouse_cluster_host = https://c-c9q14ipa2ngadqsbp2iq.rw.mdb.yandexcloud.net:8443
grafana_balancer_ip_address = 130.193.50.25

Natomiast w chmurze widoczne będą elementy podwyższonej infrastruktury:

Wdrożenie usług rozproszonych w Yandex.Cloud na przykładzie Grafany

Zsumować

Teraz, na przykładzie Grafany, każdy z Was może wdrażać aplikacje z rozbudowaną architekturą chmurową na platformie Yandex.Cloud. Pomocne narzędzia firmy HashiCorp, takie jak Packer i Terraform, mogą Ci w tym pomóc. Mam nadzieję, że komuś przyda się ten artykuł :)

PS Poniżej załączam link do repozytorium, w którym można znaleźć gotowe przepisy na Packera i Terraforma, których fragmenty podałem w tym artykule.

magazyn

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

Dodaj komentarz