Ahoj všichni! V rámci své kurzové práce jsem zkoumal možnosti takové tuzemské cloudové platformy jako je
co chcete dostávat?
Po spuštění virtuálního stroje s webovým serverem můžete přejít k jeho hostiteli a získat krásné uživatelské rozhraní, specifikovat databáze jako zdroje pro další práci, vytvářet dashboardy a grafy.
Základní verze má jednu podstatnou nevýhodu – není vůbec odolná vůči poruchám. To znamená, že celý výkon aplikace závisí na životaschopnosti jednoho virtuálního stroje. Pokud odmítne nebo pokud UI otevře 10 lidí současně, nastanou problémy.
Jsou řešeny jednoduše: stačí nasadit mnoho identických virtuálních strojů s webovým serverem a umístit je pod L3 balancer. Tady ale není vše tak jednoznačné. Grafana ukládá uživatelská nastavení (cesty k databázím, dashboardům, grafice atd.) přímo na disk svého virtuálního stroje. Pokud tedy změníte některá nastavení v uživatelském rozhraní, pak se tyto změny zobrazí pouze na virtuálním stroji, kam nás balancer poslal. To povede k nekonzistentnímu nastavení naší aplikace, problémům se spouštěním a používáním.
Zde přijde na pomoc další databáze, například MySQL nebo její ekvivalent. Říkáme Grafaně, že by měla ukládat uživatelská nastavení do této "náhradní" databáze. Poté bude stačit na každém stroji jednou zadat cestu k této databázi a upravit všechna další uživatelská nastavení na kterémkoli z virtuálních strojů, na zbytku se rozrostou.
Zde je schéma konečné aplikační infrastruktury:
Naučte se zvedat rukama
MySQL a ClickHouse
Před nasazením takové aplikace kliknutím na tlačítko bylo nutné naučit se každou její součást zvednout pomocí úchytů a vzájemně je integrovat.
Zde nám pomůže Yandex.Cloud, který poskytuje L3 balancery, ClickHouse a MySQL jako spravované služby. Uživateli stačí zadat parametry a počkat, až platforma vše uvede do funkčního stavu.
Zaregistroval jsem se, vytvořil si cloud a fakturační účet. Poté jsem přešel do cloudu a vytvořil clustery MySQL a ClickHouse s minimálním nastavením. Počkejte, až budou aktivní.
Také si musíte pamatovat na vytvoření databáze v každém clusteru a nakonfigurovat k ní přístup pomocí přihlašovacího jména a hesla. Nebudu zde zabíhat do podrobností – vše je v rozhraní zcela zřejmé.
Nezřejmým detailem bylo, že tyto databáze mají mnoho hostitelů, kteří poskytují odolnost proti chybám. Grafana však vyžaduje přesně jednoho hostitele pro každou databázi, se kterou pracuje. Dlouhé čtení c-<cluster_id>.rw.mdb.yandexcloud.net
Mapuje na aktuálního aktivního hlavního hostitele klastru s odpovídajícím ID. To je to, co dáme Grafaně.
webový server
Nyní je to na webovém serveru. Vychováme běžný virtuální stroj s Linuxem a nastavíme na něm Grafanu rukama.
Pojďme se připojit přes ssh a nainstalovat potřebné balíčky.
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
Poté spustíme Grafana pod systemctl a nainstalujeme plugin pro práci s ClickHouse (ano, není součástí základního balení).
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
sudo grafana-cli plugins install vertamedia-clickhouse-datasource
Vše poté pomocí jednoduchého příkazu
sudo service grafana-server start
spustíme webový server. Nyní bude možné vjet do externí IP adresy virtuálního stroje v prohlížeči, zadat port 3000 a vidět krásné UI grafana.
Ale nespěchejte, před nastavením Grafany nesmíte zapomenout zadat cestu k MySQL, aby tam nastavení uložila.
Celá konfigurace webového serveru Grafana je v souboru /etc/grafana/grafana.ini
. Požadovaný řádek vypadá takto:
;url =
Vystavujeme hostitele clusteru MySQL. Stejný soubor obsahuje přihlašovací jméno a heslo pro přístup do Grafany na obrázku výše, které jsou ve výchozím nastavení stejné admin
.
Můžete použít příkazy 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
Je čas restartovat webový server!
sudo service grafana-server restart
Nyní v uživatelském rozhraní Grafana určíme ClickHouse jako DataSource.
Podařilo se mi dosáhnout funkční konfigurace s následujícím nastavením:
Uvedl jsem jako URL https://c-<cluster_id>.rw.mdb.yandexcloud.net:8443
Všechno! Máme jeden funkční virtuální stroj s webovým serverem připojeným k CH a MySQL. Již můžete nahrát datovou sadu do ClickHouse a vytvořit řídicí panely. Zatím jsme však nedosáhli svého cíle a nenasadili plnohodnotnou infrastrukturu.
Packer
Yandex.Cloud vám umožňuje vytvořit obraz disku existujícího virtuálního stroje a na jeho základě můžete vytvořit tolik stejných strojů, kolik chcete. To je přesně to, co budeme používat. Chcete-li obraz pohodlně sestavit, vezměte si nástroj
Náš soubor json se bude skládat ze dvou bloků: builderů a provizorů. První blok popisuje parametry samotného obrázku jako entity a druhý popisuje instrukce pro jeho naplnění potřebným obsahem.
Builders
{
"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"
}
],
...
}
V této šabloně je potřeba nastavit identifikátor sekce v cloudu, kde chcete vytvořit obrázek, a také cestu k souboru s klíči z účtu služby dříve vytvořeného v této sekci. Více o vytváření servisních účtů a klíčů ve formě souboru si můžete přečíst v příslušné sekci.
Tato konfigurace říká, že obraz disku bude vytvořen na základě platformy ubuntu-1804-lts
, umístěnou v příslušné uživatelské sekci v rodině obrázků GRAFANA
pod jménem grafana-{{timestamp}}
.
Poskytovatelé
Nyní k zajímavější části konfigurace. Bude popisovat posloupnost akcí, které bude nutné provést na virtuálním počítači před zmrazením jeho stavu do obrazu disku.
{
...,
"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"
]
}
]
}
Zde jsou všechny akce rozděleny do 3 etap. V první fázi se spustí jednoduchý skript, který vytvoří pomocný adresář.
připravit-ctg.sh:
#!/bin/bash
sudo mkdir -p /opt/grafana
sudo chown -R ubuntu:ubuntu /opt/grafana
V další fázi do tohoto adresáře umístíme skript, který bude potřeba spustit ihned po spuštění virtuálního stroje. Tento skript vloží uživatelské proměnné, které mají být nastaveny, do konfigurace Grafany a restartuje webový server.
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
Poté je třeba udělat 3 věci:
1) nainstalovat balíčky
2) spusťte Grafana pod systemctl a nainstalujte plugin ClickHouse
3) vložte skript setup.sh do fronty, aby se spustil ihned po zapnutí virtuálního stroje.
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;
Nyní zbývá spustit Packer a získat výstupní obraz umístěný do určeného oddílu. Při vytváření virtuálního stroje jej můžete vybrat jako spouštěcí disk a po spuštění získat hotový webový server Grafana.
Skupina instancí a balancer
Jakmile existuje obraz disku, který vám umožní vytvořit mnoho identických webových serverů Grafana, můžeme vytvořit skupinu instancí. Na platformě Yandex.Cloud tento termín označuje spojení virtuálních strojů, které mají stejné vlastnosti. Při vytváření skupiny instancí se nakonfiguruje prototyp všech počítačů v této skupině a poté vlastnosti samotné skupiny (například minimální a maximální počet aktivních počítačů). Pokud aktuální počet nesplňuje toto kritérium, pak skupina instancí sama odstraní nepotřebné počítače nebo vytvoří nové v obrazu a podobě.
V rámci našeho úkolu vytvoříme skupinu instancí webových serverů, které budou vytvořeny z dříve vytvořeného obrazu disku.
Poslední nastavení skupiny instance je opravdu pozoruhodné. Cílová skupina v integraci s Load Balancer vám pomůže nastavit vyvažovač L3 nad virtuálními stroji této skupiny stisknutím několika tlačítek.
Při nastavování balanceru jsem implementoval dva důležité body:
- Udělal jsem to tak, že balancer akceptoval uživatelský provoz na portu 80 a přesměroval ho na port 3000 virtuálních strojů, kde žije Grafana.
- Nastavte kontroly stavu počítače pomocí příkazu ping na portu 3000.
minisoučet
Konečně jsme byli schopni ručně nasadit požadovanou aplikační infrastrukturu a nyní máme vysoce odolnou službu Grafana. Stačí znát IP adresu balanceru jako vstupního bodu do aplikace a hostitele clusteru ClickHouse, abychom do něj mohli načíst datovou sadu.
Zdálo by se to jako vítězství? Ano, vítězství. Ale pořád mě něco trápí. Celý proces výše vyžaduje spoustu ručních akcí a vůbec se neškáluje, chci ho pokud možno automatizovat. To bude předmětem dalšího oddílu.
Integrace s Terraformem
Opět použijeme nástroj od HashiCorp tzv
Veškerá práce s Terraformem spočívá v zápisu konfiguračního souboru (*.tf
) a vytvoření infrastruktury na něm založené.
Proměnné
Na samém začátku souboru vyjmeme proměnné, které určují, kde a jak bude budoucí infrastruktura nasazena.
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>"
}
Celý proces nasazení aplikace bude sestávat z vytvoření obrazu disku a nastavení těchto proměnných. Dovolte mi vysvětlit, za co jsou zodpovědní:
oauth_token — token pro přístup do cloudu. Lze získat prostřednictvím
cloud_id - identifikátor cloudu, kam aplikaci nasadíme
folder_id — identifikátor sekce, kam aplikaci nasadíme
service_account_id — identifikátor účtu služby v odpovídající části cloudu.
image_id - identifikátor obrazu disku získaný pomocí Packeru
uživatelské jméno и heslo - uživatelské jméno a heslo pro přístup k databázím a webovému serveru Grafana
dbname - název databáze uvnitř clusterů CH a MySQL
cesta_veřejného_klíče - cesta k souboru s vaším veřejným ssh klíčem, přes který se můžete připojit pod jménem ubuntu
na virtuální stroje s webovými servery
Nastavení poskytovatele
Nyní musíte nakonfigurovat poskytovatele Terraform - v našem případě Yandex:
provider "yandex" {
token = var.oauth_token
cloud_id = var.cloud_id
folder_id = var.folder_id
zone = "ru-central1-a"
}
Můžete vidět, že zde používáme proměnné definované výše.
Síť a clustery
Nyní vytvoříme síť, ve které budou komunikovat prvky naší infrastruktury, tři podsítě (jedna v každém regionu) a zvedneme clustery CH a 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 můžete vidět, každý ze dvou clusterů je postaven tak, aby byl poměrně odolný vůči chybám tím, že je umístěn ve třech zónách dostupnosti.
webové servery
Zdálo by se, že můžete pokračovat ve stejném duchu, ale narazil jsem na potíže. Předtím jsem nejprve zvedl cluster MySQL a teprve poté jsem se znalostí jeho ID shromáždil obraz disku s požadovanou konfigurací, kde jsem uvedl hostitele do clusteru. Nyní však neznáme ID clusteru před spuštěním Terraformu, včetně doby vytváření obrazu. Musel jsem se tedy uchýlit k následujícímu
Pomocí metadatové služby od Amazonu předáme virtuálnímu stroji některé parametry, které přijme a zpracuje. Potřebujeme, aby stroj přešel na metadata pro hostitele MySQL clusteru a pro uživatelské jméno-heslo, které uživatel po spuštění zadal v souboru Terraform. Mírně změňte obsah souboru setup.sh
, který se spustí, když je virtuální stroj zapnutý.
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
Intenční skupina a balancer
Po přestavění nového obrazu disku můžeme konečně přidat náš soubor pro Terraform.
Označujeme, že chceme použít existující obraz disku:
data "yandex_compute_image" "grafana_image" {
image_id = var.image_id
}
Nyní vytvoříme skupinu instancí:
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"
}
}
Stojí za to věnovat pozornost tomu, jak jsme předali metadata cluster_uri
, username
и password
. Je to jejich virtuální stroj, který jej získá při spuštění a vloží do konfigurace Grafana.
Je to o balanceru.
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
}
}
}
}
Trochu cukru
Zbývalo jen velmi málo. Po nasazení infrastruktury budete muset přejít do uživatelského rozhraní Grafana a ručně přidat cluster CH (jehož ID stále potřebujete získat) jako zdroj dat. Ale Terraform zná ID clusteru. Nechme ho dokončit práci.
Přidejme nového poskytovatele - Grafana a dáme balanceru IP jako hostitele. Všechny změny, které Terraform provede na stroji, kde jeho balancer určí, porostou v MySQL, a tedy na všech ostatních strojích.
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"
}
Rozčešeme
Display balancer IP a hostitel clusteru 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"
}
Může běžet
Všechno! Náš konfigurační soubor je připraven a my můžeme nastavením proměnných říct Terraformu, aby zvýšil vše, co jsme popsali výše. Celý proces mi trval asi 15 minut.
Na konci můžete vidět krásnou zprávu:
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
A v cloudu budou viditelné prvky zvýšené infrastruktury:
Shrnout
Nyní na příkladu Grafany může každý z vás nasadit aplikace s rozlehlou cloudovou architekturou na platformě Yandex.Cloud. S tím vám mohou pomoci užitečné nástroje od HashiCorp jako Packer a Terraform. Doufám, že tento článek bude pro někoho užitečný 🙂
PS Níže připojím odkaz na úložiště, kde najdete hotové recepty na Packer a Terraform, jejichž fragmenty jsem citoval v tomto článku.
Zdroj: www.habr.com