Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Hej alla! Som en del av mitt examensarbete har jag undersökt möjligheterna med en inhemsk molnplattform som Yandex.Cloud. Plattformen erbjuder olika tjÀnster för att lösa praktiska problem. Men ibland kan det vara nödvÀndigt att bygga sin egen molnapp baserat pÄ dessa tjÀnster med en ganska utspridd infrastruktur. I den hÀr artikeln vill jag dela med mig av erfarenheten av att driftsÀtta en sÄdan applikation.

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Vad vill vi uppnÄ?

Grafana — ett kraftfullt verktyg för att lösa analytiska uppgifter eller för att övervaka olika system. I sin grundversion Ă€r detta en virtuell maskin med en Grafana-webbserver och en databas (ClickHouse, InfluxDB, etc.) med dataset, som analytiken kommer att bygga pĂ„.

Efter att den virtuella maskinen med webbservern har startats kan man gÄ in pÄ dess vÀrd och fÄ en snygg anvÀndargrÀnssnitt, ange databaser som kÀllor för vidare arbete, skapa instrumentpaneler och diagram.

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Den grundlĂ€ggande versionen har en betydande nackdel — den Ă€r helt oĂ„terhĂ€mtningsbar. Det vill sĂ€ga, applikationens funktionalitet beror helt pĂ„ livskraften hos en enda virtuell maskin. Om den misslyckas eller om tio personer öppnar anvĂ€ndargrĂ€nssnittet samtidigt, sĂ„ uppstĂ„r det problem.

De löses enkelt: man behöver bara... driftsÀtta flera identiska virtuella maskiner med webbservern och placera dem bakom en L3-balancer. Men hÀr Àr det inte sÄ enkelt. Grafana lagrar anvÀndarinstÀllningarna (sökvÀgar till databaser, instrumentpaneler, diagram etc.) direkt pÄ disken av sin virtuella maskin. SÄledes, om man Àndrar nÄgra instÀllningar i anvÀndargrÀnssnittet, kommer dessa Àndringar endast att Äterspeglas pÄ den virtuella maskin som balanceraren har skickat oss till. Detta kommer att leda till inkonsekventa instÀllningar av vÄr applikation, problem med att starta och anvÀnda den.

HÀr kommer en annan databas, till exempel MySQL eller dess motsvarighet, till hjÀlp. Vi sÀger till Grafana att den ska lagra anvÀndarinstÀllningarna i denna "reserv"-databas. Efter det rÀcker det med att en gÄng ange sökvÀgen till denna databas pÄ varje maskin, och alla andra anvÀndarinstÀllningar kan redigeras pÄ nÄgon av de virtuella maskinerna; de kommer att vÀxa ut till de andra.

HÀr Àr schemat för den slutliga infrastrukturen hos applikationen:

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

LĂ€r oss att manuellt lansera

MySQL och ClickHouse

Innan du kan installera en sÄdan applikation med ett knapptryck, behövde man lÀra sig att manuellt starta varje komponent och integrera dem med varandra.

HÀr kan Yandex.Cloud hjÀlpa oss, som erbjuder L3-lastbalanserare, ClickHouse och MySQL som managed-tjÀnster. AnvÀndaren behöver bara ange parametrar och vÀnta medan plattformen gör allt redo.

Jag registrerade mig, skapade en molninstans och en betalningskonto. Efter det loggade jag in i molnet och startade MySQL- och ClickHouse-kluster med minimala instÀllningar. Jag vÀntade tills de blev aktiva.

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempelDistribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Man fĂ„r inte glömma att skapa en databas i varje kluster och stĂ€lla in Ă„tkomst med anvĂ€ndarnamn och lösenord. Jag gĂ„r inte in pĂ„ detaljer hĂ€r – allt Ă€r ganska uppenbart i grĂ€nssnittet.

En subtil detalj var att dessa databaser har mÄnga vÀrdar som sÀkerstÀller deras redundans. Men Grafana krÀver exakt en vÀrd för varje databas den arbetar med. dokumentationen Cloud:et ledde mig till en lösning. Det visar sig att en vÀrd av typen c-<cluster_id>.rw.mdb.yandexcloud.net mappas till den aktuella aktiva master-vÀrden i klustret med motsvarande ID. Det Àr den vi kommer att ge till Grafana.

Webbserver

Nu ÄterstÄr det bara för webbservern. Vi kommer att starta en vanlig virtuell maskin med Linux och manuellt konfigurera Grafana pÄ den.

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Vi ansluter oss via ssh och installerar nödvÀndiga paket.

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 

Efter det startar vi Grafana via systemctl och installerar pluginet för att arbeta med ClickHouse (ja, det ingÄr inte i standardkonfigurationen).

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

Allt, efter detta kan vi med ett enkelt kommando

sudo service grafana-server start

starta webbservern. Nu kan vi i webblÀsaren ange den externa IP-adressen pÄ den virtuella maskinen, ange port 3000 och se Grafanas vackra grÀnssnitt.
Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Men skynda dig inte, innan vi konfigurerar Grafana fÄr vi inte glömma att ge den sökvÀgen till MySQL för att spara instÀllningarna dÀr.

All konfiguration av Grafanas webbserver ligger i filen /etc/grafana/grafana.ini. Den nödvÀndiga raden ser ut sÄ hÀr:

;url =

Vi stÀller in vÀrden för MySQL-klustret. I samma fil finns anvÀndarnamn och lösenord för att fÄ Ätkomst till Grafana pÄ bilden ovan, som bÄda Àr lika med standard. admin.

Du kan anvÀnda sed-kommandon:

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

Det Àr dags att starta om webbservern!

sudo service grafana-server restart

Nu anger vi ClickHouse som datakÀlla i Grafanas grÀnssnitt.

Jag fick en fungerande konfiguration med följande instÀllningar:

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Som URL angav jag https://c-.rw.mdb.yandexcloud.net:8443

Det Àr klart! Vi har en fungerande virtuell maskin med en webbserver ansluten till CH och MySQL. Du kan redan börja ladda upp dataset till ClickHouse och bygga dashboardar. Men vi har fortfarande inte nÄtt vÄrt mÄl och har inte utvecklat en fullstÀndig infrastruktur.

Packer

Yandex.Cloud lÄter dig skapa en bild av en befintlig virtuell maskin, och pÄ grundval av den kan du skapa hur mÄnga identiska maskiner som helst. Det Àr precis detta vi kommer att anvÀnda. För att enkelt samla ihop bilden anvÀnder vi verktyget Packer frÄn HashiCorp. Det tar en json-fil som input med instruktioner för att skapa bilden.

VÄr json-fil kommer att bestÄ av tvÄ block: builders och provisioners. Den första blocket beskriver parametrar för sjÀlva bilden som entity, och den andra ger instruktioner för att fylla den med önskat innehÄll.

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

I denna mall mÄste du ange identifieraren för avsnittet i molnet dÀr du vill skapa bilden, samt vÀgen till filen med nycklarna för servicekontot som tidigare skapats i detta avsnitt. Du kan lÀsa mer om hur du skapar servicekonton och nycklar i filformat i den relevanta sektionen. dokumentationen.

Denna konfiguration anger att bilden av disken kommer att byggas pÄ grundval av plattformen ubuntu-1804-lts, placerad i det relevanta avsnittet för anvÀndaren i bilden. GRAFANA under namnet grafana-{{timestamp}}.

Provisioners

Nu börjar den intressanta delen av konfigurationen. HÀr kommer vi att beskriva de steg som mÄste utföras pÄ den virtuella maskinen innan dess tillstÄnd fryses i en diskavbildning.

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

HÀr Àr alla ÄtgÀrder uppdelade i tre steg. I det första steget körs ett enkelt skript som skapar en hjÀlpmapp.

prepare-ctg.sh:

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

I nÀsta steg placerar vi skriptet i denna mapp som mÄste köras direkt efter att den virtuella maskinen har startats. Det hÀr skriptet kommer att skriva in anvÀndarvariablerna som mÄste anges i Grafana-konfigurationen och starta om webbservern.

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

Efter detta ÄterstÄr det tre saker:
1) installera paketen
2) aktivera Grafana i systemctl och installera ClickHouse-pluginet
3) stÀlla in skriptet setup.sh i kö för att köras direkt efter att den virtuella maskinen har startats.

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;

Nu ÄterstÄr det att köra Packer sÄ att vi fÄr en bild som placeras i den angivna partitionen. Vid skapandet av den virtuella maskinen kan vi vÀlja den som startdisk och vid start fÄ en fÀrdig Grafana-webbserver.

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel
Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Instansgrupp och lastbalanserare

NÀr en diskavbildning har skapats som gör det möjligt att skapa flera identiska Grafana-webbservrar, kan vi skapa en instansgrupp. PÄ Yandex Cloud kallas denna term för en samling virtuella maskiner med samma egenskaper. Vid skapandet av en instansgrupp konfigureras prototypen för alla maskiner i denna grupp och sedan egenskaperna för sjÀlva gruppen (till exempel minimi- och maximalt antal aktiva maskiner). Om det aktuella antalet inte motsvarar dessa kriterier, kommer instansgruppen sjÀlv att ta bort onödiga maskiner eller skapa nya i enlighet med förebilden.

I vÄrt fall kommer vi att skapa en instansgrupp av webbservrar som kommer att genereras frÄn den diskavbildning som skapades tidigare.

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Den senaste instÀllningen av instansgruppen Àr verkligen anmÀrkningsvÀrd. MÄlgruppen i integrationen med Load Balancer kommer att hjÀlpa till att konfigurera L3-balansaren ovanför virtuella maskiner i denna grupp med ett par knapptryckningar.

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Vid konfigurationen av balansaren genomförde jag tvÄ viktiga aspekter:

  1. Jag gjorde det sÄ att balansaren tar emot anvÀndartrafik pÄ port 80, och omdirigerar den till port 3000 pÄ de virtuella maskinerna, dÀr Grafana ligger.
  2. Jag konfigurerade livskontrollen av maskinerna genom att pinga dem pÄ port 3000.

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Mini-sammanfattning

Äntligen lyckades vi manuellt implementera den önskade applikationsinfrastrukturen, och nu har vi en högt tillgĂ€nglig Grafana-tjĂ€nst. Det krĂ€vs bara att veta IP-adressen till balansaren som ingĂ„ngspunkt för applikationen och vĂ€rden för ClickHouse-klustret, för att ladda datasetet dit.

Verkar det vara en seger? Ja, det Àr en seger. Men nÄgot kÀnns fortfarande off. Hela processen ovan krÀver vÀldigt mÄnga manuella ÄtgÀrder och Àr helt omöjlig att skala, vi vill automatisera den sÄ mycket som möjligt. Det hÀr kommer nÀsta avsnitt att handla om.

Integration med Terraform

Vi kommer Äterigen att anvÀnda verktyget frÄn företaget HashiCorp som heter Terraform. Det kommer att hjÀlpa oss att med ett knapptryck implementera hela applikationsinfrastrukturen, baserat pÄ nÄgra variabler som anvÀndaren skickar. LÄt oss skriva ett recept som kan köras flera gÄnger i olika omrÄden för olika anvÀndare.

Allt arbete med Terraform handlar om att skriva en konfigurationsfil (*.tf) och att skapa infrastrukturen baserat pÄ den.

Variabler

I början av filen kommer vi att föra ut variabler, frÄn vilka det beror pÄ var och hur den framtida infrastrukturen kommer att implementeras.

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

Hela processen med att implementera applikationen kommer att reduceras till att bygga en diskbild och stÀlla in dessa variabler. Jag förklarar vad de svarar för:

oauth_token — en token för att fĂ„ tillgĂ„ng till molnet. Kan erhĂ„llas via lĂ€nken.
cloud_id — identifierare för molnet dĂ€r vi kommer att implementera applikationen
folder_id — identifier för sektionen dĂ€r vi kommer att distribuera applikationen
service_account_id — identifier för servicekontot i den aktuella sektionen av molnet.
image_id — identifier för diskavbildningen som erhĂ„llits med hjĂ€lp av Packer
username och password — anvĂ€ndarnamn och lösenord för Ă„tkomst till bĂ„de databaserna och Grafana-webbservern
dbname — namn pĂ„ databasen inom kluster CH och MySQL
public_key_path — sökvĂ€g till filen med din offentliga ssh-nyckel, som kan anvĂ€ndas för att ansluta som ubuntu till virtuella maskiner med webbservrar

Leverantörens instÀllningar

Nu behöver vi konfigurera Terraform-leverantören — i vĂ„rt fall Yandex:

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

Man kan mÀrka att vi hÀr anvÀnder variabler som angivits ovan.

NĂ€tverk och kluster

Nu ska vi skapa ett nÀtverk dÀr elementen i vÄr infrastruktur ska kommunicera, tre delnÀt (ett i varje region) och höja kluster för CH och 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
  }
}

Som du kan se Àr varje av de tvÄ klustren skapade pÄ ett sÀtt som gör dem ganska motstÄndskraftiga genom att de Àr placerade i tre tillgÀnglighetszoner.

Webbservrar

Det kan tyckas att jag kunde fortsÀtta pÄ samma sÀtt, men jag stötte pÄ en svÄrighet. Tidigare startade jag först MySQL-klustret och bara efter det, nÀr jag kÀnde till dess ID, samlade jag en diskavbild med den nödvÀndiga konfigurationen dÀr jag angav vÀrden till klustret. Men nu kÀnner vi inte till kluster-ID:t förrÀn Terraform har kört, vilket Àven gÀller vid skapandet av avbilden. DÀrför var jag tvungen att anvÀnda följande knep.

Genom att anvÀnda Amazons metadata-tjÀnst kommer vi att överföra vissa parametrar till den virtuella maskinen som den kommer att acceptera och bearbeta. Vi behöver att efter starten ska maskinen hÀmta metadata för MySQL-klustret och för anvÀndarnamn-lösenord som anvÀndaren angav i Terraform-filen. Litet Àndrar vi innehÄllet i filen setup.sh, som körs nÀr den virtuella maskinen slÄs pÄ.

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

Instansgrupp och lastbalanserare

Genom att Äterkompilera den nya diskavbilden kan vi Àntligen skriva klart vÄr fil för Terraform.

Vi anger att vi vill anvÀnda en befintlig diskavbild:

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

Nu ska vi skapa en instansgrupp:

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

Det Àr vÀrt att notera hur vi överförde till metadata cluster_uri, username och password. Det Àr just dessa som den virtuella maskinen vid starten kommer att hÀmta och placera i Grafana-konfigurationen.

Nu Àr det dags för lastbalanseraren.

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

Lite socker

Det ÄterstÄr bara en liten sak. Efter att infrastrukturen har rullats ut mÄste vi gÄ till Grafana UI och manuellt lÀgga till CH-klustret (vars ID vi fortfarande behöver hÀmta) som datakÀlla. Men Terraform vet ju redan kluster-ID. Vi fÄr be den att fÄ jobbet gjort.

Vi lĂ€gger till en ny leverantör — Grafana, och som vĂ€rd ger vi den IP-adressen till lastbalanseraren. Alla Ă€ndringar som Terraform gör pĂ„ maskinen, som lastbalanseraren bestĂ€mmer, kommer att vĂ€xa in i MySQL, vilket innebĂ€r att de kommer att reflekteras pĂ„ alla andra maskiner.

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

Kamma

Vi kommer att fÄ fram IP-adressen till lastbalanseraren och vÀrden för ClickHouse-klustret

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

Körning kan börja

Det Àr klart! VÄr konfigurationsfil Àr redo och vi kan, efter att ha stÀllt in variablerna, be Terraform att starta allt vi har beskrivit ovan. Hela processen tog mig ungefÀr 15 minuter.
I slutet kan man se ett fint meddelande:

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

Och i molnet kommer element av den uppsatta infrastrukturen att synas:

Distribution av distribuerade tjÀnster i Yandex.Cloud med Grafana som exempel

Sammanfattningsvis

Nu, med exemplet frĂ„n Grafana, kan var och en av er lĂ€ra sig att distribuera applikationer med en rik cloud-arkitektur pĂ„ Yandex.Cloud-plattformen. Verktyg frĂ„n HashiCorp som Packer och Terraform kan hjĂ€lpa dig med detta. Jag hoppas att denna artikel Ă€r till nytta för nĂ„gon 🙂

P.S. Jag kommer att bifoga en lÀnk till ett förrÄd dÀr du kan hitta fÀrdiga recept för Packer och Terraform, vars fragment jag refererade till i denna artikel.

FörrÄd

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster