VMs con balanceo de cargas

Arquitectura

Las VMs con balanceo de cargas son una secuencia de comandos de compilación de infraestructura que configura un clúster de VM y un balanceador de cargas para exponer una ruta pública a las VM:

  • Procesamiento - VMs - Compute Engine
  • Procesamiento - Clúster - Grupo de instancias administrado
  • Procesamiento: plantilla de máquina: plantilla de instancias
  • Herramientas de redes, balanceo de cargas, balanceador de cargas de Cloud

En esta aplicación de ejemplo, se configura un sitio HTML estático simple con NGINX y se balancean las cargas en el clúster.


Comenzar

Haz clic en el siguiente vínculo para obtener una copia del código fuente en Cloud Shell. Una vez allí, un solo comando iniciará una copia de trabajo de la aplicación en tu proyecto.

Abrir en Cloud Shell

Consulta el código fuente en GitHub


Componentes de VMs con balanceo de cargas

La arquitectura de VMs con balanceo de cargas utiliza varios productos. A continuación, se enumeran los componentes y más información sobre ellos, además de vínculos a videos relacionados, documentación del producto y explicaciones interactivas.
Video Documentos Explicaciones
Compute Engine Compute Engine es la tecnología virtual de Google Cloud. Con él, puedes iniciar muchas configuraciones diferentes de VM para adaptarlas a la forma de las necesidades de procesamiento que tengas.
Cloud Load Balancing El balanceador de cargas de Google Cloud te permite colocar un balanceador de cargas frente al bucket de Storage, lo que te permite usar certificados SSL, Logging y Monitoring.

Secuencias de comandos

La secuencia de comandos de instalación usa un archivo ejecutable escrito en go y las herramientas de la CLI de Terraform para tomar un proyecto vacío y, luego, instalar la aplicación en él. El resultado debe ser una aplicación que funcione y una URL para la dirección IP del balanceo de cargas.

./main.tf

Habilita los servicios

Los servicios de Google Cloud están inhabilitados en un proyecto de forma predeterminada. Activa los siguientes servicios obligatorios:

  • Compute Engine: Máquinas virtuales y servicios de redes (como el balanceador de cargas)
variable "gcp_service_list" {
  description = "The list of apis necessary for the project"
  type        = list(string)
  default = [
      "compute.googleapis.com",
  ]
}

resource "google_project_service" "all" {
  for_each                   = toset(var.gcp_service_list)
  project                    = var.project_number
  service                    = each.key
  disable_dependent_services = false
  disable_on_destroy         = false
}

Crear un modelo de instancia en el que se basarán las VM administradas

El siguiente comando crea una VM, instala el software necesario en ella y, luego, implementa el código.

resource "google_compute_instance" "exemplar" {
    name         = "${var.basename}-exemplar"
    machine_type = "n1-standard-1"
    zone         = var.zone
    project      = var.project_id

    tags                    = ["http-server"]
    metadata_startup_script = "apt-get update -y \n apt-get install nginx -y \n  printf '${data.local_file.index.content}'  | tee /var/www/html/index.html \n chgrp root /var/www/html/index.html \n chown root /var/www/html/index.html \n chmod +r /var/www/html/index.html"

    boot_disk {
        auto_delete = true
        device_name = "${var.basename}-exemplar"
        initialize_params {
        image = "family/debian-10"
        size  = 200
        type  = "pd-standard"
        }
    }

    network_interface {
        network = "default"
        access_config {
        // Ephemeral public IP
        }
    }

    depends_on = [google_project_service.all]
}

Crear instantánea e imagen de disco

El siguiente comando usa la VM para crear una instantánea. Luego, la instantánea se usa para crear una imagen de disco. Todas las VMs del clúster se basan en esta imagen.

resource "google_compute_snapshot" "snapshot" {
    project           = var.project_id
    name              = "${var.basename}-snapshot"
    source_disk       = google_compute_instance.exemplar.boot_disk[0].source
    zone              = var.zone
    storage_locations = ["${var.region}"]
    depends_on        = [time_sleep.startup_completion]
}

resource "google_compute_image" "exemplar" {
    project         = var.project_id
    name            = "${var.basename}-latest"
    family          = var.basename
    source_snapshot = google_compute_snapshot.snapshot.self_link
    depends_on      = [google_compute_snapshot.snapshot]
}

Crear plantilla de instancias

El siguiente comando crea una plantilla con la configuración para todas las VMs en el clúster. Usa la imagen de disco creada en el comando anterior.

El comando incluye una secuencia de comandos de inicio que personaliza el código HTML que entregan las VMs en el clúster.

 resource "google_compute_instance_template" "default" {
    project     = var.project_id
    name        = "${var.basename}-template"
    description = "This template is used to create app server instances."
    tags        = ["httpserver"]

    metadata_startup_script = "sed -i.bak \"s/\{\{NODENAME\}\}/$HOSTNAME/\" /var/www/html/index.html"

    instance_description = "BasicLB node"
    machine_type         = "n1-standard-1"
    can_ip_forward       = false

    // Create a new boot disk from an image
    disk {
        source_image = google_compute_image.exemplar.self_link
        auto_delete  = true
        boot         = true
    }

    network_interface {
        network = "default"
    }

    depends_on = [google_compute_image.exemplar]
}

Crear grupo de instancias administrado

Solicita una cantidad N de máquinas de la plantilla de instancias que se administrarán como parte de este grupo.

resource "google_compute_instance_group_manager" "default" {
    project            = var.project_id
    name               = "${var.basename}-mig"
    zone               = var.zone
    target_size        = var.nodes
    base_instance_name = "${var.basename}-mig"

    version {
        instance_template = google_compute_instance_template.default.id
    }

    named_port {
        name = "http"
        port = "80"
    }

    depends_on = [google_compute_instance_template.default]
}

Crear dirección IP externa

Se requiere para vincular un host al nombre de dominio y comunicarse en general a través de Internet.

resource "google_compute_global_address" "default" {
    project    = var.project_id
    name       = "${var.basename}-ip"
    ip_version = "IPV4"
}

Crear balanceador de cargas

Con el siguiente comando, se crea un balanceador de cargas y se implementan las verificaciones de estado y los servicios de backend. Configura el balanceador de cargas para que se conecte al grupo de instancias.

resource "google_compute_health_check" "http" {
    project = var.project_id
    name    = "${var.basename}-health-chk"

    tcp_health_check {
        port = "80"
    }
}

resource "google_compute_firewall" "allow-health-check" {
    project       = var.project_id
    name          = "allow-health-check"
    network       = local.defaultnetwork
    source_ranges = ["130.211.0.0/22", "35.191.0.0/16"]

    allow {
        protocol = "tcp"
        ports    = ["80"]
    }
}

resource "google_compute_backend_service" "default" {
    project               = var.project_id
    name                  = "${var.basename}-service"
    load_balancing_scheme = "EXTERNAL"
    protocol              = "HTTP"
    port_name             = "http"
    backend {
        group = google_compute_instance_group_manager.default.instance_group
    }

    health_checks = [google_compute_health_check.http.id]
    }

    resource "google_compute_url_map" "lb" {
    project         = var.project_id
    name            = "${var.basename}-lb"
    default_service = google_compute_backend_service.default.id
}

Habilitar HTTP

Con el siguiente comando, se configuran las reglas de red que apuntan al puerto 80 del balanceador de cargas al servicio.

resource "google_compute_target_http_proxy" "default" {
    project = var.project_id
    name    = "${var.basename}-lb-proxy"
    url_map = google_compute_url_map.lb.id
}

resource "google_compute_forwarding_rule" "google_compute_forwarding_rule" {
    project               = var.project_id
    name                  = "${var.basename}-http-lb-forwarding-rule"
    provider              = google-beta
    region                = "none"
    load_balancing_scheme = "EXTERNAL"
    port_range            = "80"
    target                = google_compute_target_http_proxy.default.id
    ip_address            = google_compute_global_address.default.id
}

Conclusión

Una vez ejecutado, deberías tener un sitio web simple en ejecución en varias instancias de Compute Engine, liderado por un balanceador de cargas en tu proyecto. Además, debes tener todo el código para modificar o extender esta solución a fin de que se adapte a tu entorno.