Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

¡Hola a todos! Como parte de mi trabajo de curso, investigué las capacidades de una plataforma de nube nacional como Yandex.Cloud. La plataforma ofrece diversos servicios para la resolución de problemas prácticos. Sin embargo, en ocasiones es necesario montar tu propia aplicación en la nube con una infraestructura bastante amplia basada en estos servicios. En este artículo quiero compartir mi experiencia en la implementación de una aplicación de este tipo.

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

¿Qué quieres recibir?

Grafana — una poderosa herramienta para resolver problemas analíticos o monitorear problemas de cualquier sistema. En su configuración básica se trata de una máquina virtual con un servidor web Grafana, así como una base de datos (ClickHouse, InfluxDB, etc.) con un conjunto de datos en el que se basará la analítica.

Después de iniciar una máquina virtual con un servidor web, puede ir a su host y obtener una hermosa interfaz de usuario, especificar bases de datos como fuentes para seguir trabajando, crear paneles y gráficos.

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

La versión básica tiene un inconveniente importante: no es en absoluto tolerante a fallos. Es decir, toda la funcionalidad de la aplicación depende de la viabilidad de una máquina virtual. Si se niega o 10 personas abren la interfaz de usuario al mismo tiempo, surgirán problemas.

Se pueden resolver de manera simple: solo necesita... implementar muchas máquinas virtuales idénticas con un servidor web y colocarlas bajo un equilibrador L3. Pero aquí no todo está tan claro. Grafana almacena la configuración del usuario (rutas a bases de datos, paneles, gráficos, etc.) directamente en el disco de su máquina virtual. Por lo tanto, si cambiamos algunas configuraciones en la interfaz de usuario, estos cambios se reflejarán solo en la máquina virtual donde nos envió el balanceador. Esto dará lugar a configuraciones inconsistentes para nuestra aplicación, causando problemas con el inicio y el uso.

Aquí vendrá al rescate otra base de datos, por ejemplo MySQL o su equivalente. Le decimos a Grafana que debería almacenar la configuración del usuario en esta base de datos "de repuesto". Después, bastará con especificar la ruta a esta base de datos una vez en cada máquina, y editar todas las demás configuraciones de usuario en cualquiera de las máquinas virtuales, que se extenderán a las demás.

A continuación se muestra un diagrama de la infraestructura de la aplicación final:

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Aprendamos a levantar con las manos

MySQL y ClickHouse

Antes de implementar una aplicación de este tipo con solo hacer clic en un botón, era necesario aprender a manejar cada uno de sus componentes e integrarlos entre sí.

Aquí nos ayudará Yandex.Cloud, que proporciona balanceadores L3, ClickHouse y MySQL como servicios administrados. El usuario solo necesita especificar los parámetros y esperar hasta que la plataforma haga que todo funcione correctamente.

Me registré, creé una nube y una cuenta de pago. Después de eso, fui a la nube y configuré los clústeres MySQL y ClickHouse con configuraciones mínimas. Esperé hasta que se activaron.

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemploImplementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

También debe recordar crear una base de datos en cada clúster y configurar el acceso a ella mediante un nombre de usuario y contraseña. No entraré en detalles aquí: todo es bastante obvio en la interfaz.

El detalle no obvio fue que estas bases de datos tienen muchos hosts, lo que garantiza su tolerancia a fallos. Sin embargo, Grafana requiere exactamente un host para cada base de datos con la que trabaja. lectura larga documentación Las nubes me llevaron a tomar una decisión. Resulta que el anfitrión de la especie. c-<cluster_id>.rw.mdb.yandexcloud.net asignado al host maestro activo actual del clúster con el ID correspondiente. Esto es lo que le daremos a Grafana.

Servidor web

Ahora depende del servidor web. Levantemos una máquina virtual normal con Linux y configuremos Grafana manualmente en ella.

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Conectémonos vía ssh e instalemos los paquetes necesarios.

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 

Después de eso, ejecutemos Grafana en systemctl e instalemos el complemento para trabajar con ClickHouse (sí, no se incluye en el paquete básico).

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

Eso es todo, después con un simple comando.

sudo service grafana-server start

Iniciaremos el servidor web. Ahora puede ingresar la dirección IP externa de la máquina virtual en el navegador, especificar el puerto 3000 y ver la hermosa interfaz de usuario de Grafana.
Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Pero no te apresures, antes de configurar Grafana, debes recordar indicarle la ruta a MySQL para poder almacenar la configuración allí.

Toda la configuración del servidor web Grafana está en el archivo /etc/grafana/grafana.ini. La línea requerida se ve así:

;url =

Configuramos el host para el clúster MySQL. El mismo archivo contiene el nombre de usuario y la contraseña para acceder a Grafana en la imagen de arriba, que por defecto son iguales. admin.

Puedes usar comandos 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

¡Es hora de reiniciar el servidor web!

sudo service grafana-server restart

Ahora, en la interfaz de usuario de Grafana, especificaremos ClickHouse como fuente de datos.

Pude lograr una configuración funcional con las siguientes configuraciones:

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Especificé como la URL https://c-<cluster_id>.rw.mdb.yandexcloud.net:8443

¡Todo! Tenemos una máquina virtual en funcionamiento con un servidor web conectado a CH y MySQL. Ya puede cargar el conjunto de datos en ClickHouse y crear paneles. Sin embargo, todavía no hemos logrado nuestro objetivo y no hemos desplegado una infraestructura completa.

Envasador

Yandex.Cloud le permite crear una imagen de disco de una máquina virtual existente y, en base a ella, cualquier número de máquinas idénticas entre sí. Esto es exactamente lo que usaremos. Para ensamblar cómodamente la imagen, tome la herramienta. Envasador de HashiCorp. Toma como entrada un archivo json con instrucciones para ensamblar la imagen.

Nuestro archivo json constará de dos bloques: constructores y aprovisionadores. El primer bloque describe los parámetros de la imagen en sí como una entidad, y el segundo bloque describe instrucciones para llenarla con el contenido necesario.

Constructores

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

En esta plantilla deberás configurar el identificador de la sección en la nube donde deseas crear la imagen, así como la ruta al archivo con las claves de la cuenta de servicio creada previamente en esta sección. Puedes leer más sobre la creación de cuentas de servicio y claves en forma de archivo en la sección correspondiente documentación.

Esta configuración dice que la imagen del disco se creará según la plataforma. ubuntu-1804-lts, colocado en la sección de usuario correspondiente en la familia de imágenes GRAFANA bajo el nombre grafana-{{timestamp}}.

Aprovisionadores

Ahora viene la parte más interesante de la configuración. Describirá la secuencia de acciones que deberán realizarse en la máquina virtual antes de congelar su estado en una imagen de 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"
        ]
        }
  ]
}

Aquí todas las acciones se dividen en 3 etapas. En la primera etapa, se ejecuta un script simple que crea un directorio auxiliar.

preparar-ctg.sh:

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

En la siguiente etapa, colocamos un script en este directorio, que deberá ejecutarse inmediatamente después de iniciar la máquina virtual. Este script colocará las variables de usuario que deben registrarse en la configuración de Grafana y reiniciará el servidor web.

configuración.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

Después de esto quedan 3 cosas por hacer:
1) instalar paquetes
2) ejecute Grafana en systemctl e instale el complemento ClickHouse
3) coloque el script setup.sh en la cola de inicio inmediatamente después de encender la máquina virtual.

instalar-paquetes.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

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

Ahora todo lo que queda es ejecutar Packer y colocar la imagen de salida en la sección especificada. Al crear una máquina virtual, puede seleccionarla como disco de arranque y, después del lanzamiento, recibirá un servidor web Grafana listo para usar.

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo
Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Grupo de instancias y equilibrador

Una vez que tengamos una imagen de disco que nos permita crear muchos servidores web Grafana idénticos, podemos crear un grupo de instancias. En la plataforma Yandex.Cloud, este término se refiere a la unión de máquinas virtuales que tienen las mismas características. Al crear un grupo de instancias, se configura el prototipo de todas las máquinas de este grupo y luego las características del grupo en sí (por ejemplo, el número mínimo y máximo de máquinas activas). Si el número actual no cumple con estos criterios, entonces el propio grupo de instancias eliminará las máquinas innecesarias o creará otras nuevas a su propia imagen.

Como parte de nuestra tarea, crearemos un grupo de instancias de servidores web que se generarán a partir de la imagen de disco creada previamente.

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Lo realmente destacable es la configuración del grupo de última instancia. El grupo objetivo en integración con Load Balancer le ayudará a configurar un equilibrador L3 sobre las máquinas virtuales de este grupo haciendo clic en un par de botones.

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Al configurar el equilibrador, implementé dos puntos importantes:

  1. Hice que el equilibrador aceptara el tráfico de usuarios en el puerto 80 y lo redirigiera al puerto 3000 de las máquinas virtuales, exactamente donde vive Grafana.
  2. Configuré la verificación de la viabilidad de las máquinas haciendo ping al puerto 3000.

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

Mini resumen

Finalmente, pudimos implementar manualmente la infraestructura de aplicaciones deseada y ahora tenemos un servicio Grafana altamente resistente. Solo necesita conocer la dirección IP del equilibrador como punto de entrada a la aplicación y el host del clúster ClickHouse para poder cargar el conjunto de datos en él.

¿Parecería una victoria? Sí, victoria. Pero algo todavía me confunde. Todo el proceso anterior requiere muchos pasos manuales y no es escalable en absoluto; me gustaría automatizarlo si es posible. A esto se dedicará la siguiente sección.

Integración de Terraform

Usaremos nuevamente una herramienta de HashiCorp llamada Terraform. Le ayudará a implementar toda la infraestructura de la aplicación con solo hacer clic en un botón, en función de varias variables pasadas por el usuario. Escribamos una receta que se pueda ejecutar varias veces en diferentes secciones de diferentes usuarios.

Todo el trabajo con Terraform se reduce a escribir un archivo de configuración (*.tf) y la creación de infraestructuras basadas en él.

Variables

Al principio del archivo, incluiremos variables que determinan dónde y cómo se implementará la infraestructura futura.

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

Todo el proceso de implementación de la aplicación se reducirá a crear una imagen de disco y configurar estas variables. Déjame explicarte de qué son responsables:

token_oauth – un token para acceder a la nube. Se puede obtener por enlace.
id_nube — identificador de nube donde implementaremos la aplicación
id_carpeta — identificador de sección donde implementaremos la aplicación
id_cuenta_servicio — identificador de cuenta de servicio en la sección correspondiente de la nube.
id_imagen — identificador de la imagen del disco obtenida usando Packer
nombre de usuario и la contraseña — nombre de usuario y contraseña para acceder a ambas bases de datos y al servidor web de Grafana
nombre de la base de datos — nombre de la base de datos dentro de los clústeres CH y MySQL
ruta_clave_pública — ruta al archivo con su clave ssh pública, que puede usar para conectarse con el nombre ubuntu a máquinas virtuales con servidores web

Configuración del proveedor

Ahora necesita configurar el proveedor Terraform, en nuestro caso, Yandex:

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

Notarás que aquí estamos usando las variables definidas anteriormente.

Red y clusters

Ahora crearemos una red en la que se comunicarán elementos de nuestra infraestructura, tres subredes (una en cada región) y levantaremos clusters CH y 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
  }
}

Como puede ver, cada uno de los dos clústeres se crea con bastante tolerancia a fallas al estar ubicado en tres zonas de disponibilidad.

servidores web

Parecía que podríamos continuar con el mismo espíritu, pero me encontré con dificultades. Antes de esto, primero levanté un clúster MySQL y solo después de eso, conociendo su ID, recopilé una imagen de disco con la configuración requerida, donde especifiqué el host para el clúster. Pero ahora no conocemos el ID del clúster antes de iniciar Terraform, ni siquiera en el momento de crear la imagen. Por lo tanto, tuve que recurrir a lo siguiente truco.

Utilizando el servicio de metadatos de Amazon, pasaremos algunos parámetros a la máquina virtual, que aceptará y procesará. Necesitamos que la máquina vaya a los metadatos detrás del host del clúster MySQL y el nombre de usuario-contraseña, que el usuario especificó en el archivo Terraform, después de comenzar. Cambiemos ligeramente el contenido del archivo. setup.sh, que se ejecuta cuando se enciende la máquina virtual.

configuración.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

Grupo de instancias y balanceador.

Habiendo reconstruido una nueva imagen de disco, finalmente podemos agregar nuestro archivo para Terraform.

Indiquemos que queremos utilizar una imagen de disco existente:

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

Ahora creemos un grupo de instancias:

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 prestar atención a cómo lo pasamos a los metadatos. cluster_uri, username и password. Son estos los que la máquina virtual sacará al inicio y los colocará en la configuración de Grafana.

Depende del equilibrador.

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 poco de azúcar

Ya queda poco. Una vez implementada la infraestructura, deberá ir a la interfaz de usuario de Grafana y agregar manualmente el clúster CH (cuyo ID aún debe obtenerse) como fuente de datos. Pero Terraform conoce el ID del clúster. Confiémosle que lleve el asunto a buen puerto.

Agreguemos un nuevo proveedor, Grafana, y proporcionemos la dirección IP del equilibrador como host. Todos los cambios que Terraform realiza en la máquina donde su balanceador determina crecerán en MySQL y, por lo tanto, en todas las demás máquinas.

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

Peinémonos

Mostremos la dirección IP del equilibrador y el host del clúster 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"
}

Poder correr

¡Todo! Nuestro archivo de configuración está listo y podemos, configurando las variables, decirle a Terraform que genere todo lo que describimos anteriormente. Todo el proceso me llevó unos 15 minutos.
Al final puedes ver un bonito mensaje:

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

Y en la nube serán visibles los elementos de la infraestructura elevada:

Implementación de servicios distribuidos en Yandex.Cloud usando Grafana como ejemplo

para resumir

Ahora, usando Grafana como ejemplo, cada uno de ustedes puede implementar aplicaciones con una arquitectura de nube en expansión en la plataforma Yandex.Cloud. Herramientas útiles de HashiCorp como Packer y Terraform pueden ayudarle con esto. Espero que alguien encuentre útil este artículo :)

PD: A continuación adjuntaré un enlace al repositorio donde puede encontrar recetas preparadas para Packer y Terraform, cuyos fragmentos proporcioné en este artículo.

repositorio

Fuente: habr.com

Añadir un comentario