Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Ciao a tutti! Nell'ambito del progetto di ricerca ho studiato le possibilità di una piattaforma cloud russa chiamata Yandex.Cloud. La piattaforma offre vari servizi per risolvere compiti pratici. Tuttavia, a volte è necessario configurare la propria applicazione cloud con un'infrastruttura piuttosto complessa basata su questi servizi. In questo articolo voglio condividere la mia esperienza nella distribuzione di tale applicazione.

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Cosa si desidera ottenere?

Grafana — uno strumento potente per risolvere compiti analitici o di monitoraggio di certi sistemi. Nella sua configurazione base, si tratta di una macchina virtuale con il server web di Grafana, oltre a un database (ClickHouse, InfluxDB, ecc.) con un dataset su cui verrà costruita l'analisi.

Dopo aver avviato la macchina virtuale con il server web, sarà possibile accedere al suo host e ottenere un'interfaccia utente ben progettata, specificare i database come sorgenti per il lavoro futuro, creare dashboard e grafici.

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

La versione base ha un significativo svantaggio: è completamente non ridondante. Cioè, l'intera funzionalità dell'applicazione dipende dalla solidità di una sola macchina virtuale. Se questa si guasta o se dieci persone aprono contemporaneamente l'interfaccia utente, sorgono problemi.

Si risolvono semplicemente: è sufficiente… distribuire molte macchine virtuali identiche con il server web e metterle sotto un bilanciatore L3. Ma qui non è tutto così semplice. Grafana memorizza le impostazioni utente (percorsi ai database, dashboard, grafici, ecc.) direttamente sul disco della sua macchina virtuale. Così, se si modificano alcune impostazioni nell'interfaccia utente, queste modifiche saranno visibili solo sulla macchina virtuale verso cui ci ha indirizzato il bilanciatore. Questo porterà a impostazioni inconsistenti per la nostra applicazione, creando problemi con l'avvio e l'uso.

Qui entra in gioco un ulteriore database, ad esempio, MySQL o un suo equivalente. Diciamo a Grafana che deve memorizzare le impostazioni utente proprio in questo "database di riserva". Dopo, basterà una volta indicare su ogni macchina il percorso a questo DB, e tutte le altre impostazioni utente possono essere modificate su una qualsiasi delle macchine virtuali, propagandosi alle altre.

Ecco lo schema finale dell'infrastruttura dell'applicazione:

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Impareremo a sollevare con le mani

MySQL e ClickHouse

Prima di distribuire un'applicazione del genere con un solo clic, era necessario imparare a sollevare manualmente ciascun componente e integrarli tra loro.

Qui ci aiuterà Yandex.Cloud, che offre bilanciatori L3, ClickHouse e MySQL come servizi gestiti. L'utente deve solo specificare i parametri e attendere che la piattaforma metta tutto in uno stato funzionante.

Mi sono registrato, ho creato il mio cloud e il mio account di pagamento. Dopo questo, sono andato nel cloud e ho sollevato i cluster MySQL e ClickHouse con impostazioni minime. Ho atteso che diventassero attivi.

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di GrafanaDistribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Non dimenticate di creare un database in ciascun cluster e di configurare l'accesso tramite nome utente e password. Non entrerò nei dettagli qui — nell'interfaccia è tutto abbastanza ovvio.

Un dettaglio poco ovvio era che questi database hanno molti host che garantiscono la loro resilienza. Tuttavia, Grafana richiede esattamente un host per ciascun database con cui lavora. documentazione Il cloud mi ha portato alla soluzione. Si scopre che un host del tipo c-<cluster_id>.rw.mdb.yandexcloud.net si mappa sull'attuale master host attivo del cluster con l'ID corrispondente. Proprio quello daremo a Grafana.

Server Web

Ora tocca al server web. Possiamo sollevare una normale macchina virtuale con Linux e configurare Grafana manualmente.

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Collegiamoci via ssh e installiamo i pacchetti necessari.

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 

Dopo questo, faremo partire Grafana tramite systemctl e installeremo il plugin per lavorare con ClickHouse (sì, nella versione base non è incluso).

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

Tutto, dopo di che, con un semplice comando

sudo service grafana-server start

avvieremo il server web. Ora sarà possibile digitare l'indirizzo IP pubblico della macchina virtuale nel browser, specificare la porta 3000 e vedere la bella interfaccia di Grafana.
Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Ma non bisogna affrettarsi, prima di configurare Grafana, non dimenticate di specificare il percorso per MySQL, per memorizzare le impostazioni lì.

Tutta la configurazione del server web di Grafana si trova nel file /etc/grafana/grafana.ini. La riga necessaria appare così:

;url =

Stiamo collegando l'host al cluster MySQL. In questo stesso file si trovano username e password per accedere a Grafana nell'immagine sopra, che per impostazione predefinita sono entrambe uguali. admin.

Puoi utilizzare comandi 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

È il momento di riavviare il server web!

sudo service grafana-server restart

Ora nell'interfaccia di Grafana impostiamo ClickHouse come DataSource.

Ho ottenuto una configurazione funzionante con le seguenti impostazioni:

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Come URL ho indicato https://c-.rw.mdb.yandexcloud.net:8443

Perfetto! Abbiamo una macchina virtuale funzionante con un server web connesso a CH e MySQL. Possiamo già caricare un dataset in ClickHouse e creare dashboard. Tuttavia, non abbiamo ancora raggiunto il nostro obiettivo e non abbiamo implementato un'infrastruttura completa.

Packer

Yandex.Cloud consente di creare un'immagine del disco di una macchina virtuale esistente e, su questa base, un numero illimitato di macchine identiche. Proprio questo faremo. Per facilitare la creazione dell'immagine, utilizzeremo lo strumento Packer di HashiCorp. Accetta un file json come input con le istruzioni per la creazione dell'immagine.

Il nostro file json sarà composto da due blocchi: builders e provisioners. Il primo blocco descrive i parametri dell'immagine come entità, mentre il secondo le istruzioni per popolare il contenuto necessario.

Builders

{
"builders": [
    {
      "type": "yandex",
      "endpoint": "{{user `endpoint`}}",
      "folder_id": "",
      "subnet_id": "{{user `subnet_id`}}",
      "zone": "{{user `zone`}}",
      "labels": {},
      "use_ipv4_nat": true,
      "use_internal_ip": false,
      "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"
    }
  ],
...
}

In questo template è necessario impostare l'identificatore della partizione nel cloud dove si desidera creare l'immagine, oltre al percorso del file con le chiavi dal servizio account, precedentemente creato in questa partizione. Maggiori dettagli sulla creazione di account di servizio e chiavi sotto forma di file possono essere letti nella sezione corrispondente. documentazione.

Questa configurazione indica che l'immagine del disco sarà creata sulla base della piattaforma ubuntu-1804-lts, collocata nella corrispondente sezione dell'utente nella famiglia di immagini GRAFANA con il nome grafana-{{timestamp}}.

Provisioners

Ora passiamo alla parte più interessante della configurazione. Qui verrà descritta la sequenza di azioni da compiere sulla macchina virtuale prima di congelare il suo stato in un'immagine disco.

{
...,
"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"
        ]
        }
  ]
}

Tutte le azioni sono divise in 3 fasi. Nella prima fase viene eseguito un semplice script che crea una directory ausiliaria.

prepare-ctg.sh:

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

Nella fase successiva, inseriamo in questa directory uno script che deve essere eseguito subito dopo l'avvio della macchina virtuale. Questo script inserirà le variabili utente, necessarie per la configurazione di Grafana, e riavvierà il server web.

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

Dopo, rimangono da fare 3 cose:
1) installare i pacchetti
2) avviare Grafana con systemctl e installare il plugin ClickHouse
3) mettere lo script setup.sh in coda per l'esecuzione immediata dopo l'accensione della macchina virtuale.

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

run-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;

Ora rimane da avviare Packer e ottenere l'immagine salvata nella directory specificata. Quando creiamo la macchina virtuale, possiamo selezionarla come disco di avvio e ottenere un server web Grafana pronto dopo l'avvio.

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana
Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Gruppo di istanze e bilanciatore

Dopo aver creato l'immagine disco, che consente di generare molteplici server web Grafana identici, possiamo creare un gruppo di istanze. Sulla piattaforma Yandex.Cloud, questo termine si riferisce all'aggregazione di macchine virtuali con caratteristiche simili. Durante la creazione del gruppo di istanze, viene configurato il prototipo di tutte le macchine nel gruppo, seguito dalle caratteristiche del gruppo stesso (ad esempio, il numero minimo e massimo di macchine attive). Se il numero attuale non soddisfa questi criteri, il gruppo di istanze eliminerà automaticamente le macchine non necessarie o ne creerà di nuove in base all'immagine e alla somiglianza.

Nell'ambito del nostro compito, creeremo un gruppo di istanze di server web, che saranno generati dall'immagine disco creata in precedenza.

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

L'ultima configurazione del gruppo di istanza è davvero notevole. Il gruppo target in integrazione con il Load Balancer aiuterà a impostare il bilanciatore L3 sopra le macchine virtuali di questo gruppo con la pressione di un paio di pulsanti.

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Durante la configurazione del bilanciatore ho realizzato due punti importanti:

  1. Ho configurato il bilanciatore per accettare il traffico degli utenti sulla porta 80 e reindirizzarlo alla porta 3000 delle macchine virtuali, proprio dove risiede Grafana.
  2. Ho impostato un controllo di vitalità delle macchine, pingandole sulla porta 3000.

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Mini-riassunto

Finalmente siamo riusciti a distribuire manualmente l'infrastruttura dell'applicazione desiderata, e ora abbiamo un servizio Grafana altamente resiliente. È sufficiente conoscere l'indirizzo IP del bilanciatore come punto di ingresso nell'applicazione e l'host del cluster ClickHouse per caricare il dataset.

Sembra una vittoria? Sì, è una vittoria. Ma qualcosa risulta comunque confuso. L'intero processo sopra richiede molte azioni manuali e non è per niente scalabile; vorremmo automatizzarlo il più possibile. Questo sarà l'argomento della prossima sezione.

Integrazione con Terraform

Useremo di nuovo lo strumento di HashiCorp chiamato Terraform. Ci aiuterà a distribuire l'intera infrastruttura dell'applicazione con la pressione di un pulsante, basandosi su alcune variabili fornite dall'utente. Scriviamo una ricetta che possa essere eseguita più volte in diverse sezioni di diversi utenti.

Tutto il lavoro con Terraform si riduce alla scrittura di un file di configurazione (*.tf) e alla creazione di infrastrutture sulla sua base.

Variabili

All'inizio del file, estrarremo le variabili da cui dipenderà dove e come sarà distribuita l'infrastruttura futura.

variable "oauth_token" {
    type = string
    default = ""
}
variable "cloud_id" {
    type = string
    default = ""
}
variable "folder_id" {
    type = string
    default = ""
}
variable "service_account_id" {
    type = string
    default = ""
}
variable "image_id" {
    type = string
    default = ""
}
variable "username" {
    type = string
    default = ""
}
variable "password" {
    type = string
    default = ""
}
variable "dbname" {
    type = string
    default = ""
}
variable "public_key_path" {
    type = string
    default = ""
}

L'intero processo di distribuzione dell'applicazione si ridurrà all'assemblaggio dell'immagine del disco e all'impostazione di queste variabili. Spiegherò a cosa servono:

oauth_token — token per accedere al cloud. Può essere ottenuto tramite link.
cloud_id — identificatore del cloud dove distribuiremo l'applicazione
folder_id — identificatore della sezione in cui svilupperemo l'applicazione
service_account_id — identificatore dell'account di servizio nella corrispondente sezione del cloud.
image_id — identificatore dell'immagine del disco ottenuta tramite Packer
username e password — nome utente e password per accedere a entrambi i database e al server web di Grafana
dbname — nome del database all'interno dei cluster CH e MySQL
public_key_path — percorso del file contenente la tua chiave ssh pubblica, tramite cui sarà possibile connettersi con il nome ubuntu alle macchine virtuali con server web

Configurazione del provider

Ora dobbiamo configurare il provider Terraform — nel nostro caso Yandex:

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

Si può notare che qui utilizziamo le variabili definite in precedenza.

Rete e cluster

Ora creiamo una rete in cui comunicheranno gli elementi della nostra infrastruttura, tre sottoreti (una in ciascuna regione) e alzeremo i cluster CH e MySQL.


resource "yandex_vpc_network" "grafana_network" {}

resource "yandex_vpc_subnet" "subnet_a" {
  zona           = "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" {
  zona           = "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" {
  zona           = "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" {
  nome        = "grafana-clickhouse"
  ambiente    = "PRODUZIONE"
  network_id  = yandex_vpc_network.grafana_network.id

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

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

  database {
    nome = var.dbname
  }

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

  host {
    tipo      = "CLICKHOUSE"
    zona      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }

  host {
    tipo      = "CLICKHOUSE"
    zona      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }

  host {
    tipo      = "CLICKHOUSE"
    zona      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }

  host {
    tipo      = "ZOOKEEPER"
    zona      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }

  host {
    tipo      = "ZOOKEEPER"
    zona      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }

  host {
    tipo      = "ZOOKEEPER"
    zona      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }
}

resource "yandex_mdb_mysql_cluster" "mysql_cluster" {
  nome        = "grafana_mysql"
  ambiente    = "PRODUZIONE"
  network_id  = yandex_vpc_network.grafana_network.id
  versione    = "8.0"

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

  database {
    nome = var.dbname
  }

  user {
    nome     = var.username
    password = var.password
    permission {
      database_name = var.dbname
      roles         = ["TUTTI"]
    }
  }

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

Come si può notare, ciascuno dei due cluster è stato creato con una buona tolleranza ai guasti grazie al posizionamento in tre zone di disponibilità.

Server web

Sembra che si possa continuare allo stesso modo, ma mi sono trovato di fronte a una difficoltà. In precedenza, avevo prima creato il cluster MySQL e solo dopo, conoscendo il suo ID, assemblavo l'immagine del disco con la configurazione necessaria, indicando l'host del cluster. Ma ora non conosciamo l'ID del cluster prima dell'esecuzione di Terraform, incluso il momento dell'assemblaggio dell'immagine. Pertanto, ho dovuto ricorrere al seguente trucchetto.

Utilizzando il servizio di metadati di Amazon, passeremo alla macchina virtuale alcuni parametri che essa accetterà e elaborerà. Abbiamo bisogno che, dopo l'avvio, la macchina acceda ai metadati per l'host del cluster MySQL e per il nome utente-password che l'utente ha indicato nel file Terraform. Modificheremo leggermente il contenuto del file setup.sh, che viene eseguito all'accensione della macchina virtuale.

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

Gruppo di istanze e bilanciatore

Ricostruendo una nuova immagine del disco, finalmente possiamo completare il nostro file per Terraform.

Indichiamo che vogliamo utilizzare un'immagine del disco esistente:

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

Ora creiamo un gruppo di istanze:

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"
  }
}

Vale la pena notare come abbiamo passato ai metadati cluster_uri, username e password. Sarà proprio questo che la macchina virtuale recupererà all'avvio e inserirà nella configurazione di Grafana.

La palla passa al bilanciatore.

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
      }
    }
  }
}

Un po' di zucchero

Restano solo pochi dettagli. Dopo che l'infrastruttura sarà stata distribuita, dovremo accedere all'interfaccia utente di Grafana e aggiungere manualmente il cluster CH (il cui ID deve ancora essere ottenuto) come sorgente dati. Ma Terraform conosce l'ID del cluster. Assegniamogli il compito di portare a termine il lavoro.

Aggiungiamo un nuovo fornitore — Grafana, mentre come host le daremo l'indirizzo IP del bilanciatore. Tutte le modifiche che Terraform apporterà alla macchina, a cui indicherà il suo bilanciatore, si rifletteranno in MySQL, e quindi anche su tutte le altre macchine.

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"
}

Pettinato

Visualizziamo l'indirizzo IP del bilanciatore e l'host del cluster 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"
}

Pronto per l'avvio

Tutto! Il nostro file di configurazione è pronto e possiamo dire a Terraform di sollevare tutto ciò che abbiamo descritto sopra impostando le variabili. L'intero processo mi ha impegnato circa 15 minuti.
Alla fine è possibile vedere un bel messaggio:

Applicazione completata! Risorse: 9 aggiunte, 0 modificate, 0 distrutte.
Uscite:

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

E nel cloud saranno visibili gli elementi dell'infrastruttura sollevata:

Distribuzione di servizi distribuiti su Yandex.Cloud con un esempio di Grafana

Riassumiamo

Ora, grazie all'esempio di Grafana, ciascuno di voi sa come implementare applicazioni con un'architettura cloud distribuita sulla piattaforma Yandex.Cloud. A questo possono aiutarti strumenti utili di HashiCorp come Packer e Terraform. Spero che questo articolo possa risultare utile a qualcuno 🙂

P.S. In basso allego un link al repository dove puoi trovare ricette pronte per Packer e Terraform, di cui ho fornito frammenti in questo articolo.

Repository

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster