Implementa un servidor de aplicaciones recuperable en frío con instantáneas de discos persistentes

Este documento está dirigido a arquitectos y personas que trabajan en equipos de operaciones y administrativos. En el documento, se describe un patrón de ejemplo que puedes usar para tus propias implementaciones en Google Cloud.

En este patrón, se usan instantáneas de discos persistentes con un grupo de instancias administrado a fin de implementar un patrón de conmutación por error en frío para un servidor web.

En este instructivo, crearás un grupo de instancias administrado que ejecuta una sola VM con un disco persistente que almacena datos. Las instantáneas programadas del disco persistente minimizan la pérdida de datos en una situación de conmutación por error. El balanceo de cargas de HTTP(S) externo dirige a los usuarios a la VM que se ejecuta en el grupo de instancias administrado, como se muestra en la siguiente imagen:

El balanceo de cargas de HTTP(S) externo dirige a los usuarios a una sola VM que se ejecuta en un grupo de instancias administrado, y una política de recursos crea instantáneas regulares de un disco persistente conectado a la VM.

Si se produce una falla en la instancia, el grupo de instancias administrado intenta volver a crear la VM en la misma zona. Si la falla es a nivel de zona, Cloud Monitoring o similar puede informarte que hay un problema y crear de forma manual otro grupo de instancias administrado en otra zona o región. En cualquier situación de conmutación por error, la plataforma usa la instantánea de disco persistente más reciente para crear un disco de reemplazo y conectarlo a la VM nueva del grupo de instancias.

En este documento, usarás la dirección IP externa de la VM o el balanceador de cargas para ver una página básica en el servidor web. Este método te permite probar el patrón de conmutación por error en frío si no tienes un nombre de dominio registrado y sin ningún cambio de DNS. En un entorno de producción, crea y configura una zona y un registro de Cloud DNS que se resuelva en la dirección IP externa asignada al balanceador de cargas.

En este patrón, se equilibra la diferencia de costos de ejecutar varias VM o discos persistentes regionales y mantener cierto nivel de protección de datos. Los costos son más bajos cuando ejecutas una VM y un disco persistente, pero existe el riesgo de pérdida de datos, puesto que las instantáneas de los discos persistentes solo se toman en un intervalo establecido. Para reducir la posible pérdida de datos, considera implementar una aplicación en frío que se pueda recuperar y que use discos persistentes regionales.

En la siguiente tabla, se describen algunas diferencias de alto nivel en las opciones de protección de datos para los enfoques recuperables en frío que usan discos persistentes regionales o instantáneas de discos persistentes. Para obtener más información, consulta Opciones de alta disponibilidad con discos persistentes.

Discos persistentes regionales Instantáneas de discos persistentes
Pérdida de datos: Objetivo de punto de recuperación (RPO) Cero para una sola falla, como la interrupción sostenida en una zona o la desconexión de la red. Todos los datos desde la última instantánea que se tomó, que suele ser de una hora o más.

La posible pérdida de datos depende de tu programación de instantáneas, que controla la frecuencia con la que se toman las instantáneas.
Objetivo de tiempo de recuperación (RTO). Tiempo de implementación para una nueva VM, más varios segundos a fin de que se vuelva a conectar el disco persistente regional. El tiempo de implementación de una VM nueva más el tiempo para crear un disco persistente nuevo a partir de la instantánea más reciente.

La hora de creación del disco depende del tamaño de la instantánea y puede tardar decenas de minutos u horas.
Costo Los costos de almacenamiento se duplican, ya que el disco persistente regional se replica de forma continua en otra zona. Solo debes pagar por la cantidad de espacio de instantáneas consumido.
Para obtener más información, consulta Precios de imágenes y discos.

Objetivos

  • Crear un grupo de instancias administrado para ejecutar una VM con un disco persistente
  • Configurar una programación de instantáneas para tomar instantáneas normales del disco persistente
  • Crear una plantilla de instancias y una secuencia de comandos de inicio
  • Crear y configurar el balanceo de cargas de HTTP(S) externo
  • Prueba la conmutación por error del servidor web en frío con un grupo de instancias administrado de reemplazo.

Costos

En este instructivo, se usan los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

  4. Habilita la API Compute Engine.

    Habilita la API

  5. Instala e inicializa el SDK de Cloud.
  6. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  7. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

  8. Habilita la API Compute Engine.

    Habilita la API

  9. Instala e inicializa el SDK de Cloud.
  10. Puedes ejecutar la herramienta de línea de comandos de gcloud en Cloud Console sin instalar el SDK de Cloud. Para ejecutar la herramienta de gcloud en Cloud Console, usa Cloud Shell.

Prepare el entorno

En esta sección, defines algunas variables para los nombres y las ubicaciones de tus recursos. Los comandos de la herramienta de línea de comandos de gcloud usan estas variables a medida que implementas los recursos.

A menos que se indique lo contrario, debes ingresar todos los comandos en Cloud Shell o en tu entorno de desarrollo local en este instructivo.

  1. Reemplaza PROJECT_ID con el ID de tu proyecto. Si lo deseas, proporciona tu propio sufijo de nombre para los recursos, como app.

    Especifica una región, como us-central1, y dos zonas dentro de esa región, como us-central1-a y us-central1-f. En estas zonas, se define dónde se implementan el disco persistente y el grupo de instancias administrado iniciales, y dónde puedes realizar una conmutación por error manual si fuera necesario.

    PROJECT_ID=PROJECT_ID
    NAME_SUFFIX=app
    REGION=us-central1
    ZONE1=us-central1-a
    ZONE2=us-central1-f
    

Crea una VPC y una subred

Para proporcionar acceso de red a las VM, crea una nube privada virtual (VPC) y una subred. Como el grupo de instancias administrado funciona en varias zonas de una misma región, solo se crea una subred. Para obtener más información sobre las ventajas del modo de subred personalizado a fin de administrar los rangos de direcciones IP en uso en tu entorno, consulta Usa redes de VPC en modo personalizado.

  1. Crea la VPC con un modo de subred personalizado:

    gcloud compute networks create network-$NAME_SUFFIX \
        --subnet-mode=custom
    

    Si ves un mensaje de Cloud Shell, autoriza esta primera solicitud para realizar llamadas a la API.

  2. Crea una subred en la VPC nueva. Define tu propio rango de direcciones, como 10.1.0.0/20, que se ajuste al rango de tu red:

    gcloud compute networks subnets create subnet-$NAME_SUFFIX-$REGION \
        --network=network-$NAME_SUFFIX \
        --range=10.1.0.0/20 \
        --region=$REGION
    

Crea reglas de firewall

  1. Crea reglas de firewall para permitir el tráfico web y las verificaciones de estado del balanceador de cargas y los grupos de instancias administrados:

    gcloud compute firewall-rules create allow-http-$NAME_SUFFIX \
        --network=network-$NAME_SUFFIX \
        --direction=INGRESS \
        --priority=1000 \
        --action=ALLOW \
        --rules=tcp:80 \
        --source-ranges=0.0.0.0/0 \
        --target-tags=http-server
    
    gcloud compute firewall-rules create allow-health-check-$NAME_SUFFIX \
        --network=network-$NAME_SUFFIX \
        --action=allow \
        --direction=ingress \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --target-tags=allow-health-check \
        --rules=tcp:80
    

    La regla HTTP permite el tráfico a cualquier VM en la que se aplique la etiqueta http-server y desde cualquier fuente que use el rango 0.0.0.0/0. En el caso de la regla de verificación de estado, se establecen rangos predeterminados para Google Cloud a fin de permitir que la plataforma verifique de forma correcta el estado de los recursos.

  2. A fin de permitir el tráfico SSH para la configuración inicial de una imagen de VM base, apunta la regla de firewall a tu entorno mediante el parámetro --source-range. Es posible que debas trabajar con tu equipo de red para determinar qué rangos de origen usa tu organización.

    Reemplaza IP_ADDRESS_SCOPE por tus propios alcances de dirección IP:

    gcloud compute firewall-rules create allow-ssh-$NAME_SUFFIX \
        --network=network-$NAME_SUFFIX \
        --direction=INGRESS \
        --priority=1000 \
        --action=ALLOW \
        --rules=tcp:22 \
        --source-ranges=IP_ADDRESS_SCOPE
    
  3. Después de crear las reglas de firewall, verifica que se hayan agregado las tres reglas:

    gcloud compute firewall-rules list \
        --project=$PROJECT_ID \
        --filter="NETWORK=network-$NAME_SUFFIX"
    

    El siguiente resultado de ejemplo muestra que las tres reglas se crearon de forma correcta:

    NAME                    NETWORK      DIRECTION  PRIORITY  ALLOW
    allow-health-check-app  network-app  INGRESS    1000      tcp:80
    allow-http-app          network-app  INGRESS    1000      tcp:80
    allow-ssh-app           network-app  INGRESS    1000      tcp:22
    

Crea y configura una imagen de VM base

Para crear VM idénticas que implementes sin configuración adicional, usa una imagen de VM personalizada. En esta imagen, se captura la configuración del SO y Apache y se usa para crear cada VM en el grupo de instancias administrado en los siguientes pasos.

Debes usar un disco persistente para almacenar los datos de aplicación. En este documento, debes usar un sitio web básico de Apache para entregar la aplicación. Más adelante en este documento, crearás una programación de instantáneas que se conectará a este disco persistente para crear instantáneas de disco automatizadas.

En la VM, crea un archivo index.html básico en el disco persistente y actívalo en /var/www/example.com. Un archivo de configuración de Apache en /etc/apache2/sites-available/example.com.conf entrega contenido web desde la ubicación del disco persistente activado.

En el siguiente diagrama, se muestra la página HTML básica que entrega Apache que se almacena en el disco persistente:

La VM tiene una página HTML básica almacenada en el disco persistente con un archivo de configuración de Apache para cargar desde la ubicación del disco activado.

Debes compilar este entorno en los siguientes pasos.

  1. Crea una SSD de 10 GiB. Comprende tus necesidades de almacenamiento y los costos asociados de pagar por el espacio aprovisionado, no el espacio consumido. Para obtener más información, consulta los precios de los discos persistentes.

    gcloud compute disks create disk-$NAME_SUFFIX \
        --zone $ZONE1 \
        --size=10 \
        --type=pd-ssd
    
  2. Crea una VM base con el disco persistente conectado:

    gcloud compute instances create vm-base-$NAME_SUFFIX \
        --zone=$ZONE1 \
        --machine-type=n1-standard-1 \
        --subnet=subnet-$NAME_SUFFIX-$REGION \
        --tags=http-server \
        --image=debian-10-buster-v20210721 \
        --image-project=debian-cloud \
        --boot-disk-size=10GB \
        --boot-disk-type=pd-balanced \
        --boot-disk-device-name=vm-base-$NAME_SUFFIX \
        --disk=mode=rw,name=disk-$NAME_SUFFIX,device-name=disk-$NAME_SUFFIX
    

    Usa los parámetros definidos al comienzo de este documento para nombrar la VM y conectarte a la subred correcta. Los nombres también se asignan a partir de los parámetros del disco de arranque y el disco de datos.

  3. Para instalar y configurar el sitio web simple, primero conéctate a la VM base mediante SSH:

    gcloud compute ssh vm-base-$NAME_SUFFIX --zone=$ZONE1
    
  4. En la sesión SSH a la VM, crea una secuencia de comandos para configurar la VM en el editor que elijas. En el siguiente ejemplo, se usa Nano como editor:

    nano configure-vm.sh
    

    Pega la siguiente secuencia de comandos de configuración en el archivo. Actualiza la variable NAME_SUFFIX para que coincida con el valor establecido al comienzo de este documento, como app:

    #!/bin/bash
    
    NAME_SUFFIX=app
    
    # Create directory for the basic website files
    sudo mkdir -p /var/www/example.com
    sudo chmod a+w /var/www/example.com
    sudo chown -R www-data: /var/www/example.com
    
    # Find the disk name, then format and mount it
    DISK_NAME="google-disk-$NAME_SUFFIX"
    DISK_PATH="$(find /dev/disk/by-id -name "${DISK_NAME}" | xargs -I '{}' readlink -f '{}')"
    
    sudo mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard $DISK_PATH
    sudo mount -o discard,defaults $DISK_PATH /var/www/example.com
    
    # Install Apache, additional utilities, and cloud-init
    sudo apt-get update && sudo apt-get -y install apache2 moreutils cloud-init
    
    # Write out a basic HTML file to the mounted persistent disk
    sudo tee -a /var/www/example.com/index.html >/dev/null <<'EOF'
    <!doctype html>
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a test web server with persistent disk snapshots!</p>
    </body>
    </html>
    EOF
    
    # Write out an Apache configuration file
    sudo tee -a /etc/apache2/sites-available/example.com.conf >/dev/null <<'EOF'
    <VirtualHost *:80>
            ServerName www.example.com
    
            ServerAdmin webmaster@localhost
            DocumentRoot /var/www/example.com
    
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
    EOF
    
    # Enable the Apache configuration file and reload service
    sudo a2dissite 000-default
    sudo a2ensite example.com.conf
    sudo systemctl reload apache2
    
  5. Escribe el archivo y sal del editor. Por ejemplo, en Nano, usa Ctrl-O para escribir el archivo y, luego, sal con Ctrl-X.

  6. Haz que la secuencia de comandos de configuración sea ejecutable y, luego, ejecútala:

    chmod +x configure-vm.sh
    ./configure-vm.sh
    
  7. Si se produce una falla en la instancia y el grupo de instancias administrado necesita crear un reemplazo a partir de esta VM base, los datos de aplicación deben estar disponibles. Los siguientes pasos deben ejecutarse de forma automática en cada VM nueva:

    • Obtén información del servidor de metadatos.
    • Obtén la última instantánea del disco persistente.
    • Crea un disco a partir de esta última instantánea.
    • Conecta el disco nuevo a la VM.
    • Activa el disco dentro de la VM.

    Crea una secuencia de comandos de inicio llamada app-startup.sh que siga estos pasos que se requieren para la VM. Esta secuencia de comandos de inicio se aplica a una plantilla de instancias en el siguiente paso.

    sudo mkdir /opt/cloud-init-scripts
    
    sudo tee -a /opt/cloud-init-scripts/app-startup.sh >/dev/null <<'EOF'
    #!/bin/bash
    
    # Install jq and get an access token for API requests
    apt-get install -y jq
    OAUTH_TOKEN=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
        -H "Metadata-Flavor: Google" --silent | jq -r '.access_token')
    
    # Make a request against the metadata server to determine the project name,
    # instance name, and what zone it's running in
    ZONE_INFO=$(curl http://metadata.google.internal/computeMetadata/v1/instance/zone \
        -H "Metadata-Flavor: Google" --silent)
    PROJECT_NAME=$(curl http://metadata.google.internal/computeMetadata/v1/instance/zone \
        -H "Metadata-Flavor: Google" --silent | awk -v FS="/" '{print $2}')
    ZONE_NAME=$(curl http://metadata.google.internal/computeMetadata/v1/instance/zone \
        -H "Metadata-Flavor: Google" --silent | sed 's:.*/::')
    INSTANCE_NAME=$(curl http://metadata.google.internal/computeMetadata/v1/instance/name \
        -H "Metadata-Flavor: Google" --silent)
    
    # Get the latest snapshot of the app disk
    LATEST_SNAPSHOT=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" \
        https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/global/snapshots \
        --silent | jq -s '.[].items[] | select(.name | contains("disk-$NAME")) | .name' \
        | sort -r | head -n 1 | tr -d '"')
    
    # Create a persistent disk using the latest persistent disk snapshot
    curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json; charset=utf-8" \
        https://compute.googleapis.com/compute/v1/$ZONE_INFO/disks \
        --data '{"name":"'$LATEST_SNAPSHOT'-restored","sizeGb":"10","type":"zones/'$ZONE_NAME'/diskTypes/pd-ssd","sourceSnapshot":"https://www.googleapis.com/compute/v1/projects/'$PROJECT_NAME'/global/snapshots/'$LATEST_SNAPSHOT'"}'
    
    # Wait for the persistent disk to be created from the disk snapshot
    DISK_STATUS=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" \
        https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/zones/$ZONE_NAME/disks/$LATEST_SNAPSHOT-restored \
        --silent | jq -r .status)
    
    while [ $DISK_STATUS != "READY" ]
    do
        sleep 2
        DISK_STATUS=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" \
            https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/zones/$ZONE_NAME/disks/$LATEST_SNAPSHOT-restored \
            --silent | jq -r .status)
    done
    
    # Attach the new persistent disk created from the snapshot to the VM
    curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json; charset=utf-8" \
        https://compute.googleapis.com/compute/v1/$ZONE_INFO/instances/$INSTANCE_NAME/attachDisk \
        --data '{ "source": "/compute/v1/'$ZONE_INFO'/disks/'$LATEST_SNAPSHOT'-restored"}'
    
    # Wait for the persistent disk to be attached before mounting
    ATTACH_STATUS=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" \
        https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/zones/$ZONE_NAME/instances/$INSTANCE_NAME \
        --silent | jq '.disks[] | select(.source | contains("disk-"))')
    
    while [ -z "$ATTACH_STATUS" ]
    do
        sleep 2
        ATTACH_STATUS=$(curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" GET \
            https://compute.googleapis.com/compute/v1/projects/$PROJECT_NAME/zones/$ZONE_NAME/instances/$INSTANCE_NAME \
            --silent | jq '.disks[] | select(.source | contains("disk-"))')
    done
    
    # With the disk attached, mount the disk and restart Apache
    echo UUID=`blkid -s UUID -o value /dev/sdb` /var/www/example.com ext4 discard,defaults,nofail 0 2 \
        | tee -a /etc/fstab
    mount -a
    systemctl reload apache2
    
    # Remove jq so it's not left on the VM
    apt-get remove -y jq
    EOF
    
  8. Para aplicar la variable NAME_SUFFIX que definiste al comienzo del documento en la secuencia de comandos de inicio, como app, usa el comando envsubst:

    export NAME=app
    envsubst '$NAME' < "/opt/cloud-init-scripts/app-startup.sh" \
        | sudo sponge "/opt/cloud-init-scripts/app-startup.sh"
    
  9. Salga de la sesión SSH en la VM.

    exit
    
  10. Obtén la dirección IP de la VM y usa curl para ver la página web básica:

    curl $(gcloud compute instances describe vm-base-$NAME_SUFFIX \
        --zone $ZONE1 \
        --format="value(networkInterfaces.accessConfigs.[0].natIP)")
    

    Se muestra el sitio web básico, como se muestra en el siguiente resultado de ejemplo:

    <!doctype html>
    
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a test web server with persistent disk snapshots!</p>
    </body>
    </html>
    

    Este paso confirma que Apache esté configurado correctamente y que la página se cargue desde el disco persistente conectado. En las siguientes secciones, crearás una imagen con esta VM base y configurarás una plantilla de instancias con una secuencia de comandos de inicio.

Crea una programación de instantáneas de discos persistentes

Para asegurarte de que las VM creadas en el grupo de instancias administrado siempre tengan los datos más recientes del disco persistente, crea una programación de instantáneas. Este programa toma instantáneas automáticas de un disco persistente en momentos definidos y controla durante cuánto tiempo se retienen. En la siguiente imagen, se muestra cómo funciona este proceso de instantánea:

Se crea una política de recursos que define una programación de instantáneas y se conecta al disco persistente para tomar instantáneas regulares.

Piensa en las necesidades de tu aplicación y tus objetivos comerciales para determinar la frecuencia con la que debes tomar instantáneas. Por ejemplo, un sitio web estático necesita instantáneas con menos frecuencia que una aplicación activa que escribe datos en el disco.

Si deseas obtener más información para determinar el mejor enfoque para tus propias aplicaciones y qué método de recuperación usar, consulta la guía de planificación para la recuperación ante desastres.

  1. En esta situación, usarás una programación de instantáneas para crear instantáneas de discos persistentes regulares. Debes definir esta programación de instantáneas en una política de recursos. Las políticas de recursos te permiten definir acciones que ejecutar y conectarlas con los recursos de tu entorno.

    En esta política de recursos, debes definir una programación para crear una instantánea con la siguiente configuración:

    • Toma una instantánea cada 4 horas, a partir de las 10:00 p.m. UTC
    • Retener las instantáneas durante 1 día

    Configura esta programación según sea necesario para tu entorno, como la hora de inicio y la frecuencia con la que deseas tomar las instantáneas:

    gcloud compute resource-policies create snapshot-schedule snapshot-schedule-$NAME_SUFFIX \
        --description "Snapshot persistent disk every 4 hours" \
        --max-retention-days 1 \
        --start-time 22:00 \
        --hourly-schedule 4 \
        --region $REGION
    

    Si deseas obtener más información, consulta Usa instantáneas programadas para discos persistentes.

  2. Para usar la programación de instantáneas, conecta la política de recursos a tu disco persistente. Especifica el nombre de tu disco persistente y la política de recursos creada en el paso anterior:

    gcloud compute disks add-resource-policies disk-$NAME_SUFFIX \
        --resource-policies snapshot-schedule-$NAME_SUFFIX \
        --zone $ZONE1
    
  3. No puedes completar el resto de este documento y ver el grupo de instancias administrado en acción hasta que se cree la primera instantánea del disco. Crea ahora una instantánea de disco de forma manual y permite que la programación de instantáneas de la política de recursos cree instantáneas adicionales como se define a continuación:

    gcloud compute disks snapshot disk-$NAME_SUFFIX \
        --zone=$ZONE1 \
        --snapshot-names=disk-$NAME_SUFFIX-$(date "+%Y%m%d%H%M%S")
    

Cree una cuenta de servicio

Cada VM en el grupo de instancias administrado que se crea en los siguientes pasos debe ejecutar una secuencia de comandos de inicio. Esta secuencia de comandos de inicio crea un disco persistente a partir de una instantánea y, luego, lo conecta a la VM. Como práctica recomendada de seguridad, crea una cuenta de servicio nueva solo con los permisos necesarios para realizar estas operaciones de disco. Luego, asignas esta cuenta de servicio a la VM.

  1. Crea una cuenta de servicio para usar con las VM en el grupo de instancias administrado:

    gcloud iam service-accounts create instance-sa-$NAME_SUFFIX \
        --description="Service account for HA/DR example" \
        --display-name="HA/DR for VM instances"
    
  2. Crea una función personalizada y asigna solo los permisos necesarios para realizar las tareas de administración de disco. Los siguientes permisos son obligatorios:

    • compute.snapshots.list
    • compute.snapshots.useReadOnly
    • compute.disks.get
    • compute.disks.create
    • compute.instances.get
    • compute.instances.attachDisk
    • compute.disks.use
    gcloud iam roles create instance_snapshot_management_$NAME_SUFFIX \
        --project=$PROJECT_ID \
        --title="Snapshot management for VM instances" \
        --description="Custom role to allow an instance to create a persistent disk from a snapshot and attach to VM." \
        --permissions=compute.snapshots.list,compute.snapshots.useReadOnly,compute.disks.get,compute.disks.create,compute.instances.get,compute.instances.attachDisk,compute.disks.use \
        --stage=GA
    
  3. Agrega las vinculaciones de funciones necesarias para la cuenta de servicio nueva:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member="serviceAccount:instance-sa-$NAME_SUFFIX@$PROJECT_ID.iam.gserviceaccount.com" \
        --role="projects/$PROJECT_ID/roles/instance_snapshot_management_$NAME_SUFFIX"
    
    gcloud projects add-iam-policy-binding $PROJECT_ID \
        --member="serviceAccount:instance-sa-$NAME_SUFFIX@$PROJECT_ID.iam.gserviceaccount.com" \
        --role="roles/iam.serviceAccountUser"
    

Crea una imagen de VM y una plantilla de instancias

Para crear VM idénticas que se puedan implementar de forma automática sin una configuración adicional requerida, usa una imagen de VM personalizada. Esta imagen captura la configuración de SO y Apache. Cada VM creada en el grupo de instancias administrado en los siguientes pasos usa esta imagen.

  1. Antes de crear una imagen, debes detener la VM:

    gcloud compute instances stop vm-base-$NAME_SUFFIX --zone=$ZONE1
    
  2. Crea una imagen de la VM base configurada en la sección anterior:

    gcloud compute images create image-$NAME_SUFFIX \
        --source-disk=vm-base-$NAME_SUFFIX \
        --source-disk-zone=$ZONE1 \
        --storage-location=$REGION
    
  3. Usa cloud-init para ejecutar la secuencia de comandos de inicio anterior la primera vez que se inicia una VM en los grupos de instancias administrados. Se ejecuta una secuencia de comandos de inicio normal aplicada a la VM cada vez que se inicia la VM, por ejemplo, si la VM se reinicia después de las actualizaciones.

    Crea un archivo de configuración cloud-init para usarlo con la plantilla de instancias:

    tee -a cloud-init.yaml >/dev/null <<'EOF'
    #cloud-config
    
    runcmd:
     - [ bash, /opt/cloud-init-scripts/app-startup.sh ]
    EOF
    
  4. Crea una plantilla de instancias que aplique la configuración cloud-init para ejecutar la secuencia de comandos de inicio que crea un disco a partir de una instantánea y, luego, conecta y activa el disco en la VM:

    gcloud compute instance-templates create template-$NAME_SUFFIX \
        --machine-type=n1-standard-1 \
        --subnet=projects/$PROJECT_ID/regions/$REGION/subnetworks/subnet-$NAME_SUFFIX-$REGION \
        --tags=http-server \
        --image=image-$NAME_SUFFIX \
        --scopes cloud-platform \
        --service-account="instance-sa-$NAME_SUFFIX@$PROJECT_ID.iam.gserviceaccount.com" \
        --metadata-from-file user-data=cloud-init.yaml
    

Crea un grupo de instancias administrado

Un grupo de instancias administrado ejecuta las VM. El grupo de instancias administrado se ejecuta en una zona definida y supervisa el estado de las VM. Si ocurre una falla y la VM deja de ejecutarse, el grupo de instancias administrado intenta volver a crear otra VM en la misma zona y crea un disco persistente a partir de la última instantánea. Si la falla está a nivel de la zona, debes realizar la conmutación por error en frío y crear otro grupo de instancias administrado en una zona diferente de forma manual. La misma imagen personalizada y plantilla de instancias configuran la VM de forma idéntica y automática.

  1. Crea una verificación de estado para supervisar las VM del grupo de instancias administrado. Esta verificación de estado se asegura de que la VM responda en el puerto 80. Para tus propias aplicaciones, supervisa los puertos adecuados a fin de verificar el estado de la VM.

    gcloud compute health-checks create http http-basic-check-$NAME_SUFFIX --port 80
    
  2. Crea un grupo de instancias administrado con una sola VM. Esta VM única se inicia y crea un disco persistente a partir de la última instantánea, luego, la activa y comienza a entregar tráfico web.

    gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$ZONE1 \
        --base-instance-name=instance-vm-$NAME_SUFFIX \
        --template=template-$NAME_SUFFIX \
        --size=1 \
        --zone=$ZONE1 \
        --health-check=http-basic-check-$NAME_SUFFIX
    

Crea y configura un balanceador de cargas

Para que los usuarios accedan a tu sitio web, debes permitir el tráfico a través de las VM que se ejecutan en el grupo de instancias administrado. También debes redireccionar de manera automática el tráfico a VM nuevas si hay una falla de zona en un grupo de instancias administrado.

En la siguiente sección, crearás un balanceador de cargas externo con un servicio de backend para el tráfico HTTP en el puerto 80, y usarás la verificación de estado creada en los pasos anteriores. una dirección IP externa al servicio de backend

Para obtener más información, consulta Cómo configurar un balanceador de cargas de HTTP externo simple.

  1. Crea y configura el balanceador de cargas para tu aplicación:

    # Configure port rules for HTTP port 80
    gcloud compute instance-groups set-named-ports \
        instance-group-$NAME_SUFFIX-$ZONE1 \
        --named-ports http:80 \
        --zone $ZONE1
    
    # Create a backend service and add the managed instance group to it
    gcloud compute backend-services create \
        web-backend-service-$NAME_SUFFIX \
        --protocol=HTTP \
        --port-name=http \
        --health-checks=http-basic-check-$NAME_SUFFIX \
        --global
    
    gcloud compute backend-services add-backend \
        web-backend-service-$NAME_SUFFIX \
        --instance-group=instance-group-$NAME_SUFFIX-$ZONE1 \
        --instance-group-zone=$ZONE1 \
        --global
    
    # Create a URL map for the backend service
    gcloud compute url-maps create web-map-http-$NAME_SUFFIX \
        --default-service web-backend-service-$NAME_SUFFIX
    
    # Configure forwarding for the HTTP traffic
    gcloud compute target-http-proxies create \
        http-lb-proxy-$NAME_SUFFIX \
        --url-map web-map-http-$NAME_SUFFIX
    
    gcloud compute forwarding-rules create \
        http-content-rule-$NAME_SUFFIX \
        --global \
        --target-http-proxy=http-lb-proxy-$NAME_SUFFIX \
        --ports=80
    
  2. Obtén la dirección IP de la regla de reenvío para el tráfico web:

    IP_ADDRESS=$(gcloud compute forwarding-rules describe http-content-rule-$NAME_SUFFIX \
        --global \
        --format="value(IPAddress)")
    
  3. Usa curl o abre tu navegador web para ver el sitio web mediante la dirección IP del balanceador de cargas del paso anterior:

    curl $IP_ADDRESS
    

    El balanceador de cargas tarda unos minutos en terminar la implementación y dirigir el tráfico a tu backend de forma correcta. Se muestra un error HTTP 404 o 502 si el balanceador de cargas todavía se está implementando. Si es necesario, espera unos minutos y vuelve a acceder al sitio web.

    Se muestra el sitio web básico, como se muestra en el siguiente resultado de ejemplo:

    <!doctype html>
    
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a Compute Engine website with warm failover to Cloud Storage!</p>
    </body>
    </html>
    

Simula una falla y recuperación de zona

Revisemos las implementaciones de recursos antes de simular una falla a nivel de zona. Todos los recursos se crearon para brindar compatibilidad con el siguiente entorno:

El balanceo de cargas de HTTP(S) externo dirige a los usuarios a una sola VM que se ejecuta en un grupo de instancias administrado, y una política de recursos crea instantáneas regulares de un disco persistente conectado a la VM.

  • Una VM se ejecuta en un grupo de instancias administrado con un disco persistente conectado que almacena un sitio web básico.
  • Se toman instantáneas del disco persistente con regularidad mediante una programación de instantáneas de la política de recursos.
  • Se aplica una secuencia de comandos de inicio a una plantilla de instancias para que cualquier VM creada en el grupo de instancias administrado cree un disco persistente a partir de la última instantánea del disco y lo conecte.
  • Una verificación de estado supervisa el estado de la VM dentro del grupo de instancias administrado.
  • El balanceo de cargas de HTTP(S) externo dirige a los usuarios a la VM que se ejecuta en el grupo de instancias administrado.
  • Si la VM falla, el grupo de instancias administrado intenta volver a crear una VM en la misma zona. Si el error se produce a nivel de la zona, debes crear de forma manual un grupo de instancias administrado de reemplazo en otra zona de trabajo.

En un entorno de producción, es posible que recibas una alerta mediante Cloud Monitoring o cualquier otra solución de supervisión cuando exista un problema. Esta alerta le pide a una persona que comprenda el alcance de la falla antes de que crees un grupo de instancias administrado de reemplazo de forma manual en otra zona de trabajo. Un enfoque alternativo es usar la solución de supervisión para responder de forma automática a las interrupciones con el grupo de instancias administrado.

Cuando tú o tu solución de supervisión determinen que la acción más adecuada es realizar una conmutación por error, crea un grupo de instancias administrado de reemplazo. En este documento, crearás este recurso de reemplazo de forma manual.

  1. Para simular una falla a nivel de la zona, borra el backend del balanceador de cargas y el grupo de instancias administrado:

    gcloud compute backend-services remove-backend \
        web-backend-service-$NAME_SUFFIX \
        --instance-group=instance-group-$NAME_SUFFIX-$ZONE1 \
        --instance-group-zone=$ZONE1 \
        --global
    
    gcloud compute instance-groups managed delete instance-group-$NAME_SUFFIX-$ZONE1 \
          --zone=$ZONE1
    

    Cuando se te solicite, confirma la solicitud para borrar el grupo de instancias administrado.

    En un entorno de producción, el sistema de supervisión genera una alerta que ahora solicita una acción de conmutación por error en frío.

  2. Usa curl o el navegador web de nuevo para acceder a la dirección IP del balanceador de cargas:

    curl $IP_ADDRESS --max-time 5
    

    La solicitud curl falla porque no hay objetivos en buen estado para el balanceador de cargas.

  3. Para simular la conmutación por error en frío, crea un grupo de instancias administrado en una zona diferente:

    gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$ZONE2 \
        --template=template-$NAME_SUFFIX \
        --size=1 \
        --zone=$ZONE2 \
        --health-check=http-basic-check-$NAME_SUFFIX
    

    La imagen de VM, la plantilla de instancias y el disco persistente mantienen toda la configuración de la instancia de la aplicación.

  4. Actualiza el balanceador de cargas para agregar la VM y el grupo de instancias administrado nuevos:

    gcloud compute instance-groups set-named-ports \
        instance-group-$NAME_SUFFIX-$ZONE2 \
        --named-ports http:80 \
        --zone $ZONE2
    
    gcloud compute backend-services add-backend \
        web-backend-service-$NAME_SUFFIX \
        --instance-group=instance-group-$NAME_SUFFIX-$ZONE2 \
        --instance-group-zone=$ZONE2 \
        --global
    
  5. Usa curl o tu navegador web una vez más para acceder a la dirección IP del balanceador de cargas que dirige el tráfico a la VM que se ejecuta en el grupo de instancias administrado:

    curl $IP_ADDRESS
    

    La VM tarda unos minutos en terminar de implementar y restablecer los datos de la instantánea del disco persistente más reciente. Se muestra un error HTTP 404 o 502 si la VM aún se está implementando, y se muestra el sitio web de Apache predeterminado si aún se están restableciendo los datos. Si es necesario, espera unos minutos y vuelve a acceder al sitio web.

    En la siguiente respuesta de ejemplo, se muestra la página web que se ejecuta de forma correcta en la VM:

    <!doctype html>
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a test web server with persistent disk snapshots!</p>
    </body>
    </html>
    
  6. Verifica el estado del grupo de instancias administrado:

    gcloud compute instance-groups managed list-instances instance-group-$NAME_SUFFIX-$ZONE2 \
        --zone $ZONE2
    

    El siguiente resultado de ejemplo muestra el estado de la VM como RUNNING y HEALTHY:

    NAME             ZONE           STATUS   HEALTH_STATE  ACTION
    instance-vm-app  us-central1-f  RUNNING  HEALTHY       NONE
    
  7. Para verificar que el disco persistente conectado se creó a partir de una instantánea, consulta la fuente. Especifica la instancia NAME que se muestra en el comando list-instances anterior.

    gcloud compute instances describe NAME \
        --zone=$ZONE2 \
        --format="value(disks.[1].source)"
    

    El siguiente resultado de ejemplo muestra que el disco persistente se llama disk-app-us-central1-a-20210630165529-umopkt17-restored. La secuencia de comandos de inicio agrega el sufijo -restored al nombre de la instantánea de disco más reciente:

    https://www.googleapis.com/compute/v1/projects/project/zones/us-central1-f/disks/disk-app-us-central1-a-20210630165529-umopkt17-restored
    

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Para borrar los recursos individuales creados en este documento, completa los siguientes pasos.

  1. Borra la configuración del balanceador de cargas:

    gcloud compute forwarding-rules delete \
        http-content-rule-$NAME_SUFFIX --global --quiet
    
    gcloud compute target-http-proxies delete \
        http-lb-proxy-$NAME_SUFFIX --quiet
    
    gcloud compute url-maps delete web-map-http-$NAME_SUFFIX --quiet
    
    gcloud compute backend-services delete \
        web-backend-service-$NAME_SUFFIX --global --quiet
    
  2. Borra el grupo de instancias administrado y la verificación de estado:

    gcloud compute instance-groups managed delete instance-group-$NAME_SUFFIX-$ZONE2 \
        --zone=$ZONE2 --quiet
    
    gcloud compute health-checks delete http-basic-check-$NAME_SUFFIX --quiet
    
  3. Borra la plantilla de instancias, la configuración de cloud-init, las imágenes, la VM base, el disco persistente y la programación de instantáneas.

    gcloud compute instance-templates delete template-$NAME_SUFFIX --quiet
    
    rm cloud-init.yaml
    
    gcloud compute images delete image-$NAME_SUFFIX --quiet
    
    gcloud compute instances delete vm-base-$NAME_SUFFIX --zone=$ZONE1 --quiet
    
    gcloud compute disks delete disk-$NAME_SUFFIX --zone=$ZONE1 --quiet
    
    gcloud compute resource-policies delete \
        snapshot-schedule-$NAME_SUFFIX --region $REGION --quiet
    
  4. Enumera y, luego, borra las instantáneas y los discos creados por las instancias:

    gcloud compute disks list --filter="name:disk-$NAME_SUFFIX" \
        --uri | xargs gcloud compute disks delete
    
    gcloud compute snapshots list --filter="name:disk-$NAME_SUFFIX" \
        --uri | xargs gcloud compute snapshots delete
    
  5. Borra la función personalizada y la cuenta de servicio:

    gcloud iam roles delete instance_snapshot_management_$NAME_SUFFIX \
      --project=$PROJECT_ID --quiet
    
    gcloud iam service-accounts delete \
        instance-sa-$NAME_SUFFIX@$PROJECT_ID.iam.gserviceaccount.com --quiet
    
  6. Borra las reglas de firewall:

    gcloud compute firewall-rules delete allow-health-check-$NAME_SUFFIX --quiet
    
    gcloud compute firewall-rules delete allow-ssh-$NAME_SUFFIX --quiet
    
    gcloud compute firewall-rules delete allow-http-$NAME_SUFFIX --quiet
    
  7. Borra la subred y la VPC:

    gcloud compute networks subnets delete \
        subnet-$NAME_SUFFIX-$REGION --region=$REGION --quiet
    
    gcloud compute networks delete network-$NAME_SUFFIX --quiet
    

¿Qué sigue?