Aloja y escala una app web en Google Cloud con Compute Engine

1. Introducción

Existen muchas formas de implementar sitios web en Google Cloud, y cada solución ofrece diferentes funciones, capacidades y niveles de control. Compute Engine ofrece un amplio nivel de control sobre la infraestructura utilizada para ejecutar un sitio web, pero también requiere un poco más de administración operativa que otras soluciones como Google Kubernetes Engine, App Engine, entre otras. Con Compute Engine, tienes un control más detallado sobre distintos aspectos de la infraestructura, como las máquinas virtuales y el balanceador de cargas, por ejemplo. Hoy implementarás una app de ejemplo, el sitio web de comercio electrónico de Fancy Store, para demostrar que es muy simple implementar y escalar un sitio web con Compute Engine.

Qué aprenderás

Al final del codelab, tendrás instancias dentro de los grupos de instancias administrados que proporcionarán reparación automática, balanceo de cargas, ajuste de escala automático y actualizaciones progresivas para tu sitio web.

Requisitos previos

2. Configuración del entorno

Configuración del entorno de autoaprendizaje

  1. Accede a la consola de Cloud y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Recuerde el ID de proyecto, un nombre único en todos los proyectos de Google Cloud (el nombre anterior ya se encuentra en uso y no lo podrá usar). Se mencionará más adelante en este codelab como PROJECT_ID.

  1. A continuación, deberás habilitar la facturación en la consola de Cloud para usar los recursos de Google Cloud recursos.

Ejecutar este codelab no debería costar mucho, tal vez nada. Asegúrate de seguir las instrucciones de la sección “Realiza una limpieza”, en la que se aconseja cómo cerrar recursos para que no se te facture más allá de este instructivo. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.

Habilita la API de Compute Engine

A continuación, debes habilitar la API de Compute Engine. Para habilitar una API, debes aceptar las condiciones del servicio y la responsabilidad de facturación de la API.

En Cloud Shell, ejecuta el siguiente comando para habilitar la API de Compute Engine:

gcloud services enable compute.googleapis.com

Cloud Shell

Si bien Google Cloud se puede operar de manera remota desde tu laptop, en este codelab usarás Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.

Esta máquina virtual basada en Debian está cargada con todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Esto significa que todo lo que necesitarás para este Codelab es un navegador (sí, funciona en una Chromebook).

  1. Para activar Cloud Shell desde la consola de Cloud, solo haz clic en Activar Cloud Shella8460e837e9f5fda.png (el aprovisionamiento y la conexión al entorno debería llevar solo unos minutos).

b532b2f19ab85dda.png

Captura de pantalla del 14 de junio de 2017 a las 10.13.43 p.m. .png

Una vez conectado a Cloud Shell, debería ver que ya se autenticó y que el proyecto ya se configuró con tu PROJECT_ID:

gcloud auth list

Resultado del comando

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Resultado del comando

[core]
project = <PROJECT_ID>

Si, por algún motivo, el proyecto no está configurado, solo emite el siguiente comando:

gcloud config set project <PROJECT_ID>

Si no conoce su PROJECT_ID, Observa el ID que usaste en los pasos de configuración o búscalo en el panel de la consola de Cloud:

2485e00c1223af09.png

Cloud Shell también configura algunas variables de entorno de forma predeterminada, lo que puede resultar útil cuando ejecutas comandos futuros.

echo $GOOGLE_CLOUD_PROJECT

Resultado del comando

<PROJECT_ID>
  1. Establece la zona predeterminada y la configuración del proyecto.
gcloud config set compute/zone us-central1-f

Puedes elegir una variedad de zonas diferentes. Para obtener más información, consulta Regiones y zonas.

Crea un bucket de Cloud Storage

Usaremos un bucket de Cloud Storage para alojar el código compilado y nuestras secuencias de comandos de inicio. En Cloud Shell, ejecuta el siguiente comando para crear un nuevo bucket de Cloud Storage:

gsutil mb gs://fancy-store-$DEVSHELL_PROJECT_ID

3. Clona el repositorio de código fuente

Usarás el sitio web de comercio electrónico existente de Fancy Store que se basa en el repositorio monolith-to-microservices como modelo para tu sitio web. Clonarás el código fuente de tu repositorio para poder enfocarte en los aspectos de la implementación en Compute Engine. Más adelante, realizarás una pequeña actualización en el código para comprobar lo fácil que es realizar actualizaciones en Compute Engine.

También puedes clonar automáticamente el repositorio de código en el proyecto, así como abrir Cloud Shell y el editor de código integrado, a través del siguiente vínculo: Abrir en Cloud Shell.

Como alternativa, puedes clonar el repositorio de forma manual con los siguientes comandos en Cloud Shell:

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices

En el símbolo del sistema de Cloud Shell, ejecuta la compilación inicial del código para permitir que la app se ejecute de manera local. Es posible que la ejecución de la secuencia de comandos tarde unos minutos.

./setup.sh

Realiza las pruebas necesarias en tu app. Ejecuta el siguiente comando para iniciar el servidor web:

cd microservices
npm start

Resultado:

Products microservice listening on port 8082!
Frontend microservice listening on port 8080!
Orders microservice listening on port 8081!

Para obtener una vista previa de tu app, haz clic en el ícono de vista previa en la Web y selecciona “Vista previa en el puerto 8080”.

6634c06dd0b9172c.png

Se debería abrir una ventana nueva en la que podrás ver el frontend de Fancy Store en acción.

abf2ca314bf80d03.png

Puedes cerrar esta ventana después de ver el sitio web. Para detener el proceso del servidor web, presiona Control+C (Command+C en Macintosh) en la ventana de la terminal.

4. Crea instancias de Compute Engine

Ahora que tienes tu entorno de desarrollo activo, puedes implementar algunas instancias de Compute Engine. En los siguientes pasos, harás lo siguiente:

  1. Crear una secuencia de comandos de inicio para configurar las instancias
  2. Clonar el código fuente y subirlo a Cloud Storage
  3. Implementar una instancia de Compute Engine para alojar los microservicios de backend
  4. Reconfigurar el código de frontend para utilizar la instancia de microservicios de backend
  5. Implementar una instancia de Compute Engine para alojar el microservicio de frontend
  6. Configurar la red para permitir la comunicación

Crea una secuencia de comandos de inicio

Se usará la secuencia de comandos de inicio para indicarle a la instancia qué hacer cada vez que se inicie. De esta forma, se configuran automáticamente las instancias.

Haz clic en el ícono de lápiz ubicado en la cinta de Cloud Shell para abrir el editor de código.

Navega a la carpeta monolith-to-microservices. Haz clic en Archivo > Nuevo archivo y crea un archivo llamado startup-script.sh.

439553c934139b82.png

En el archivo nuevo, pega el siguiente código, parte del cual editarás después de pegarlo:

#!/bin/bash

# Install logging monitor. The monitor will automatically pick up logs sent to
# syslog.
curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash
service google-fluentd restart &

# Install dependencies from apt
apt-get update
apt-get install -yq ca-certificates git build-essential supervisor psmisc

# Install nodejs
mkdir /opt/nodejs
curl https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x64.tar.gz | tar xvzf - -C /opt/nodejs --strip-components=1
ln -s /opt/nodejs/bin/node /usr/bin/node
ln -s /opt/nodejs/bin/npm /usr/bin/npm

# Get the application source code from the Google Cloud Storage bucket.
mkdir /fancy-store
gsutil -m cp -r gs://fancy-store-[DEVSHELL_PROJECT_ID]/monolith-to-microservices/microservices/* /fancy-store/

# Install app dependencies.
cd /fancy-store/
npm install

# Create a nodeapp user. The application will run as this user.
useradd -m -d /home/nodeapp nodeapp
chown -R nodeapp:nodeapp /opt/app

# Configure supervisor to run the node app.
cat >/etc/supervisor/conf.d/node-app.conf << EOF
[program:nodeapp]
directory=/fancy-store
command=npm start
autostart=true
autorestart=true
user=nodeapp
environment=HOME="/home/nodeapp",USER="nodeapp",NODE_ENV="production"
stdout_logfile=syslog
stderr_logfile=syslog
EOF

supervisorctl reread
supervisorctl update

Ahora, en el editor de código, busca el texto [DEVSHELL_PROJECT_ID] y reemplázalo por el resultado del siguiente comando:

echo $DEVSHELL_PROJECT_ID

Resultado de ejemplo:

my-gce-codelab-253520

La línea de código de startup-script.sh debería ser similar a la que se ve a continuación:

gs://fancy-store-my-gce-codelab-253520/monolith-to-microservices/microservices/* /fancy-store/

La secuencia de comandos de inicio realiza las siguientes tareas:

  • Instalación del agente de Logging, que recopila automáticamente registros de syslog
  • Instalación de Node.js y Supervisor, que ejecuta la app como un daemon
  • Clonación del código fuente de la app desde el bucket de Cloud Storage y la instalación de dependencias
  • Configuración de Supervisor, que ejecuta la app, garantiza que se reinicie la app si se cierra de forma inesperada o si la detiene un administrador o un proceso, y envía las transmisiones stdout y stderr de la app a syslog para que las recopile el agente de Logging.

Ahora copia el archivo startup-script.sh creado en el bucket de Cloud Storage que creaste anteriormente:

gsutil cp ~/monolith-to-microservices/startup-script.sh gs://fancy-store-$DEVSHELL_PROJECT_ID

Ahora podrás acceder al archivo mediante el siguiente vínculo: https://storage.googleapis.com/[BUCKET_NAME]/startup-script.sh. [BUCKET_NAME] representa el nombre del bucket de Cloud Storage. De manera predeterminada, este archivo solo será visible para cuentas de servicio y usuarios autorizados, por lo que no será posible acceder a él mediante un navegador web. Las instancias de Compute Engine podrán acceder automáticamente a través de sus cuentas de servicio.

Copie el código en el bucket de Cloud Storage

Cuando se inician las instancias, estas extraen el código del bucket de Cloud Storage para que puedas almacenar algunas variables de configuración en el archivo ".env" del código.

Copia el código clonado en el bucket de Cloud Storage:

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

Implemente la instancia de backend

La primera instancia que implementarás será la de backend, que alojará los microservicios de pedidos y productos.

Ejecuta el siguiente comando en Cloud Shell para crear una instancia f1-micro configurada para usar la secuencia de comandos de inicio que creaste anteriormente y etiquetada como instancia de backend para que puedas aplicarle reglas de firewall específicas más adelante:

gcloud compute instances create backend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=backend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh

Configure la conexión al backend

Antes de implementar el frontend de la app, debes actualizar la configuración para que apunte al backend que implementaste.

Recupera la dirección IP externa del backend, que se puede ver en el siguiente comando en la pestaña EXTERNAL_IP de la instancia de backend:

gcloud compute instances list

Resultado de ejemplo:

NAME     ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
backend  us-central1-a  f1-micro                   10.128.0.2   34.68.223.88  RUNNING

En el editor de código de Cloud Shell, navega a la carpeta monolith-to-microservices > react-app. En el menú del editor de código, selecciona View > Toggle Hidden Files para ver el archivo .env.

e7314ceda643e16.png

Edita el archivo .env para que apunte a la dirección IP externa del backend. [BACKEND_ADDRESS] a continuación representa la dirección IP externa de la instancia de backend determinada a partir del comando anterior en la herramienta de gcloud.

REACT_APP_ORDERS_URL=http://[BACKEND_ADDRESS]:8081/api/orders
REACT_APP_PRODUCTS_URL=http://[BACKEND_ADDRESS]:8082/api/products

Guarda el archivo.

Usa el siguiente comando para volver a compilar react-app, lo que actualizará el código del frontend:

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

Copia el código de la app en el bucket de Cloud Storage:

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

Implemente la instancia de frontend

Una vez que hayas configurado el código, podrás implementar la instancia de frontend. Ejecuta el siguiente comando para implementar la instancia de frontend con un comando similar al anterior, pero esta instancia está etiquetada como "frontend" por motivos relacionados con el firewall.

gcloud compute instances create frontend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=frontend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh 

Configura la red

Crea reglas de firewall que permitan que el frontend acceda al puerto 8080, y el backend, a los puertos 8081 y 8082. Los comandos de firewall utilizan las etiquetas que se asignan al momento de crear las instancias para la app.

gcloud compute firewall-rules create fw-fe \
    --allow tcp:8080 \
    --target-tags=frontend
gcloud compute firewall-rules create fw-be \
    --allow tcp:8081-8082 \
    --target-tags=backend

Ahora el sitio web debería funcionar. Determina la dirección IP externa del frontend. La dirección se puede determinar buscando la EXTERNAL_IP de la instancia de frontend:

gcloud compute instances list

Resultado de ejemplo:

NAME      ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
backend   us-central1-a  f1-micro                   10.128.0.2   104.198.235.171  RUNNING
frontend  us-central1-a  f1-micro                   10.128.0.3   34.69.141.9      RUNNING

Es posible que la instancia tarde algunos minutos en iniciarse y configurarse. Ejecuta el siguiente comando para supervisar la preparación de la app:

watch -n 5 curl http://[EXTERNAL_IP]:8080 

Una vez que veas un resultado similar al siguiente, el sitio web debería estar listo. Presiona Control+C (Command+C en Macintosh) en el símbolo del sistema para detener el comando watch.

80dc8721dc08d7e4.png

Dirígete a http://[FRONTEND_ADDRESS]:8080 con una nueva pestaña del navegador web para acceder al sitio web. [FRONTEND_ADDRESS] es la EXTERNAL_IP determinada anteriormente.

Intenta navegar a las páginas Productos y Pedidos, que también deberían funcionar.

a11460a1fffb07d8.png

5. Crea grupos de instancias administrados

Para permitir el escalamiento de tu aplicación, se crearán grupos de instancias administrados, que utilizarán las instancias de frontend y backend como plantillas de instancias.

Un grupo de instancias administrado contiene instancias idénticas que puedes administrar como una única entidad en una sola zona. Los grupos de instancias administrados mantienen la alta disponibilidad de sus aplicaciones, ya que conservan sus instancias disponibles de manera proactiva, es decir, en estado RUNNING. Usarás grupos de instancias administrados para que tus instancias de frontend y backend proporcionen reparación automática, balanceo de cargas, ajuste de escala automático y actualizaciones progresivas.

Crea una plantilla de instancias a partir de una instancia de origen

Antes de crear un grupo de instancias administrado, debes crear una plantilla de instancias que será la base del grupo. Las plantillas de instancias te permiten definir el tipo de máquina, la imagen del disco de arranque o del contenedor, la red y otras propiedades de la instancia que usarás cuando crees nuevas instancias de máquinas virtuales (VM). Puedes usar esas plantillas para crear instancias en un grupo de instancias administrado o incluso instancias individuales.

Para crear la plantilla de instancias, usa las instancias existentes que creaste.

Primero, debes detener ambas instancias.

gcloud compute instances stop frontend
gcloud compute instances stop backend

Ahora, crea la plantilla de instancias a partir de las instancias de origen.

gcloud compute instance-templates create fancy-fe \
    --source-instance=frontend
gcloud compute instance-templates create fancy-be \
    --source-instance=backend

Confirma que se hayan creado las plantillas de instancias:

gcloud compute instance-templates list

Resultado de ejemplo:

NAME      MACHINE_TYPE  PREEMPTIBLE  CREATION_TIMESTAMP
fancy-be  f1-micro                   2019-09-12T07:52:57.544-07:00
fancy-fe  f1-micro                   2019-09-12T07:52:48.238-07:00

Crea un grupo de instancias administrado

Crearás dos grupos de instancias administrados, uno para el frontend y otro para el backend. Esos grupos de instancias administrados usarán las plantillas de instancias creadas anteriormente y se configurarán para tener dos instancias en cada grupo para iniciar. Las instancias recibirán automáticamente un nombre según el "base-instance-name" especificado con caracteres aleatorios agregados.

gcloud compute instance-groups managed create fancy-fe-mig \
    --base-instance-name fancy-fe \
    --size 2 \
    --template fancy-fe
gcloud compute instance-groups managed create fancy-be-mig \
    --base-instance-name fancy-be \
    --size 2 \
    --template fancy-be

Para tu aplicación, el microservicio de frontend se ejecuta en el puerto 8080, y los microservicios de backend se ejecutan en el puerto 8081 para los pedidos y en el puerto 8082 para los productos. Dado que estos son puertos no estándar, especificarás puertos con nombre para identificarlos. Los puertos con nombre son metadatos de pares clave-valor que muestran el nombre del servicio y el puerto en el que se ejecuta. Los puertos con nombre se pueden asignar a un grupo de instancias; eso indica que el servicio está disponible en todas las instancias del grupo. El balanceador de cargas, que configurarás más adelante, usa esa información.

gcloud compute instance-groups set-named-ports fancy-fe-mig \ 
    --named-ports frontend:8080
gcloud compute instance-groups set-named-ports fancy-be-mig \
    --named-ports orders:8081,products:8082

Configurar la reparación automática

Para mejorar la disponibilidad de la app y verificar que responda, puedes configurar una política de reparación automática para los grupos de instancias administrados.

Una política de reparación automática se basa en una verificación de estado de la app para comprobar que la app responda según lo esperado. Comprobar si una app responde es más preciso que verificar si una instancia está en estado RUNNING, que es el comportamiento predeterminado.

Crea una verificación de estado para el frontend y el backend que repare la instancia si pasa a estar en mal estado tres veces consecutivas:

gcloud compute health-checks create http fancy-fe-hc \
    --port 8080 \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3
gcloud compute health-checks create http fancy-be-hc \
    --port 8081 \
    --request-path=/api/orders \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3

Crea una regla de firewall para permitir que los sondeos de verificación de estado se conecten con los microservicios en los puertos 8080 y 8081:

gcloud compute firewall-rules create allow-health-check \
    --allow tcp:8080-8081 \
    --source-ranges 130.211.0.0/22,35.191.0.0/16 \
    --network default

Aplica las verificaciones de estado a sus servicios respectivos:

gcloud compute instance-groups managed update fancy-fe-mig \
    --health-check fancy-fe-hc \
    --initial-delay 300
gcloud compute instance-groups managed update fancy-be-mig \
    --health-check fancy-be-hc \
    --initial-delay 300

Continúa con el codelab para darle tiempo a la reparación automática de supervisar las instancias del grupo. Más adelante, simularás una falla para probar la reparación automática.

6. Crear balanceador de cargas

Para complementar nuestros grupos de instancias administrados, usarás el balanceo de cargas HTTP(S) para entregar tráfico a los microservicios de frontend y backend, y usarás asignaciones para enviar tráfico a los servicios de backend adecuados en función de las reglas de rutas de acceso. Esto expondrá una única dirección IP con balanceo de cargas para todos los servicios.

Para obtener más información sobre las opciones de balanceo de cargas disponibles en Google Cloud, consulta la Descripción general del balanceo de cargas.

Crea un balanceo de cargas HTTP(S)

Google Cloud ofrece muchos tipos diferentes de balanceo de cargas, pero usarás el balanceo de cargas de HTTP(S) para tu tráfico. El balanceo de cargas HTTP(S) se estructura de la siguiente manera:

  1. Una regla de reenvío dirige las solicitudes entrantes a un proxy HTTP de destino.
  2. El proxy HTTP de destino compara cada solicitud con un mapa de URL para determinar el servicio de backend apropiado para la solicitud.
  3. El servicio de backend dirige cada solicitud a un backend adecuado según la capacidad de entrega, la zona y el estado de la instancia de los backends asociados. El estado de cada instancia de backend se comprueba mediante una verificación de estado HTTP. Si el servicio de backend está configurado para usar una verificación de estado HTTPS o HTTP/2, la solicitud se encriptará de camino a la instancia de backend.
  4. Las sesiones entre el balanceador de cargas y la instancia pueden usar los protocolos HTTP, HTTPS o HTTP/2. Si usas HTTPS o HTTP/2, cada instancia de los servicios de backend debe tener un certificado SSL.

Crea verificaciones de estado que se utilizarán para determinar qué instancias pueden entregar tráfico para cada servicio.

gcloud compute http-health-checks create fancy-fe-frontend-hc \
  --request-path / \
  --port 8080
gcloud compute http-health-checks create fancy-be-orders-hc \
  --request-path /api/orders \
  --port 8081
gcloud compute http-health-checks create fancy-be-products-hc \
  --request-path /api/products \
  --port 8082

Crea servicios de backend hacia los que se pueda dirigir el tráfico de carga balanceada. Los servicios de backend utilizarán las verificaciones de estado y los puertos con nombre que creaste.

gcloud compute backend-services create fancy-fe-frontend \
  --http-health-checks fancy-fe-frontend-hc \
  --port-name frontend \
  --global
gcloud compute backend-services create fancy-be-orders \
  --http-health-checks fancy-be-orders-hc \
  --port-name orders \
  --global
gcloud compute backend-services create fancy-be-products \
  --http-health-checks fancy-be-products-hc \
  --port-name products \
  --global

Agrega los servicios de backend.

gcloud compute backend-services add-backend fancy-fe-frontend \
  --instance-group fancy-fe-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-orders \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global
gcloud compute backend-services add-backend fancy-be-products \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-f \
  --global

Crea un mapa de URL. El mapa de URL define las URLs que se dirigen hacia cada uno de los servicios de backend.

gcloud compute url-maps create fancy-map \
  --default-service fancy-fe-frontend

Crea un comparador de rutas de acceso para permitir que las rutas /api/orders y /api/products se dirijan hacia sus respectivos servicios.

gcloud compute url-maps add-path-matcher fancy-map \
   --default-service fancy-fe-frontend \
   --path-matcher-name orders \
   --path-rules "/api/orders=fancy-be-orders,/api/products=fancy-be-products"

Crea el proxy que se vincula al mapa de URL creado.

gcloud compute target-http-proxies create fancy-proxy \
  --url-map fancy-map

Crea una regla de reenvío global que vincule el proxy a una dirección IP pública y a un puerto.

gcloud compute forwarding-rules create fancy-http-rule \
  --global \
  --target-http-proxy fancy-proxy \
  --ports 80

Actualizar configuración

Ahora que tienes una nueva dirección IP estática, debes actualizar el código del frontend para que dirija hacia la dirección nueva, en lugar de hacia la dirección efímera que utilizaste antes y que llevaba a la instancia de backend.

En Cloud Shell, cambia a la carpeta react-app, que contiene el archivo .env con la configuración.

cd ~/monolith-to-microservices/react-app/

Busca la dirección IP del balanceador de cargas:

gcloud compute forwarding-rules list --global

Resultado de ejemplo:

NAME                    REGION  IP_ADDRESS     IP_PROTOCOL  TARGET
fancy-http-rule          34.102.237.51  TCP          fancy-proxy

Edita el archivo .env con tu editor de texto preferido (como GNU nano) para que dirija a la dirección IP pública del balanceador de cargas. [LB_IP] representa la dirección IP externa de la instancia de backend.

REACT_APP_ORDERS_URL=http://[LB_IP]/api/orders
REACT_APP_PRODUCTS_URL=http://[LB_IP]/api/products

Vuelve a compilar react-app, lo que actualizará el código del frontend.

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

Copia el código de la aplicación en el bucket de GCS.

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

Actualiza las instancias de frontend

Ahora quieres que las instancias de frontend del grupo de instancias administrado extraigan el nuevo código. Tus instancias extraen el código cuando se inician, por lo que puedes ejecutar un comando de reinicio progresivo.

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable 100%

Prueba el sitio web

Espera unos 30 segundos después de ejecutar el comando rolling-action restart para dar tiempo a que se procesen las instancias. Luego, verifica el estado del grupo de instancias administrado hasta que las instancias aparezcan en la lista.

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

Después de que aparezcan los elementos en la lista, presiona Control+C (Command+C en Macintosh) para salir del comando watch.

Confirma que el servicio aparezca como en buen estado.

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

Resultado de ejemplo:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

Una vez que aparezcan en la lista, presiona Control+C (Command+C en Macintosh) para salir del comando watch.

Luego, se podrá acceder a la aplicación a través de http://[LB_IP], donde [LB_IP] es la IP_ADDRESS que se especificó para el balanceador de cargas y que se puede encontrar con el siguiente comando:

gcloud compute forwarding-rules list --global

7. Escala Compute Engine

Hasta ahora, creaste dos grupos de instancias administrados, cada uno con dos instancias. La configuración funciona correctamente, pero no deja de ser una configuración estática, más allá de la carga. Ahora, crearás una política de ajuste de escala automático en función del uso para escalar automáticamente cada grupo de instancias administrado.

Cambio de tamaño automático según el uso

Para crear la política de ajuste de escala automático, ejecuta los siguientes comandos en Cloud Shell. Crearán un escalador automático en los grupos de instancias administrados que automáticamente agrega instancias cuando el balanceador de cargas supera el 60% de uso o las quita cuando está por debajo de esa cifra.

gcloud compute instance-groups managed set-autoscaling \
  fancy-fe-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60
gcloud compute instance-groups managed set-autoscaling \
  fancy-be-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60

Habilita la red de distribución de contenidos

Otra función que puede ser de utilidad con el escalamiento es habilitar Cloud CDN, un servicio de red de distribución de contenidos, para brindar almacenamiento en caché al servicio de frontend. Para ello, puedes ejecutar el siguiente comando en tu servicio de frontend:

gcloud compute backend-services update fancy-fe-frontend \
    --enable-cdn --global

Ahora, cuando un usuario solicita contenido del balanceador de cargas, la solicitud llega a un frontend de Google, que primero busca una respuesta para la solicitud del usuario en la caché de Cloud CDN. Si el frontend encuentra una respuesta almacenada en caché, se la envía al usuario. Esto se conoce como acierto de caché.

De lo contrario, si el frontend no encuentra una respuesta almacenada en caché para la solicitud, realiza una solicitud directamente al backend. Si la respuesta a esa solicitud se puede almacenar en caché, el frontend la almacena en la caché de Cloud CDN para que se pueda usar en solicitudes posteriores.

8. Actualizar el sitio web

Actualiza la plantilla de instancias

Las plantillas de instancias existentes no se pueden editar. Sin embargo, dado que tus instancias no tienen estado y toda la configuración se realiza a través de la secuencia de comandos de inicio, solo debes modificar la plantilla de instancias si deseas cambiar la imagen principal de la configuración de la plantilla. Ahora, realizarás un cambio simple para usar y desplegar un tipo de máquina más grande.

Actualiza la instancia de frontend, que actúa como base de la plantilla de instancias. Durante la actualización, colocarás un archivo en la versión actualizada de la imagen de la plantilla de instancias. Luego, actualizarás la plantilla, lanzarás la nueva y confirmarás que dicho archivo esté en las instancias del grupo de instancias administrado.

Modificarás el tipo de máquina de tu plantilla de instancias. Para ello, cambiarás el tipo de máquina estándar f1-micro por uno personalizado con 4 vCPU y 3840 MiB de RAM.

En Cloud Shell, ejecuta el siguiente comando para modificar el tipo de máquina de la instancia de frontend:

gcloud compute instances set-machine-type frontend --machine-type custom-4-3840

Crea la nueva plantilla de instancias:

gcloud compute instance-templates create fancy-fe-new \
    --source-instance=frontend \
    --source-instance-zone=us-central1-a

Lanza la plantilla de instancias actualizada en el grupo de instancias administrado:

gcloud compute instance-groups managed rolling-action start-update fancy-fe-mig \
    --version template=fancy-fe-new

Supervisa el estado de la actualización:

watch -n 2 gcloud compute instance-groups managed list-instances fancy-fe-mig

Una vez que tengas más de 1 instancia con el estado RUNNING, ACTION configurado como None y con INSTANCE_TEMPLATE configurado como el nuevo nombre de la plantilla (fancy-fe-new), copia el nombre de una de las máquinas que se indican en la lista para usarlo en el siguiente comando.

Control+S (Command+S en Macintosh) para salir del proceso de vigilancia

Ejecuta el siguiente comando para ver si la máquina virtual está utilizando el nuevo tipo de máquina (custom-4-3840). [VM_NAME] es la nueva instancia creada:

gcloud compute instances describe [VM_NAME] | grep machineType

Resultado esperado (ejemplo):

machineType: https://www.googleapis.com/compute/v1/projects/project-name/zones/us-central1-f/machineTypes/custom-4-3840

Realiza cambios en el sitio web

Tu equipo de marketing te pidió que cambiara la página principal de tu sitio. Consideran que deberías ofrecer más información sobre la identidad de la empresa y el producto que vendes. En esta sección, agregarás texto a la página principal para satisfacer al equipo de Marketing. Al parecer, uno de tus desarrolladores ya creó los cambios con el nombre de archivo index.js.new. Puedes copiar el archivo en index.js y deberías ver reflejados los cambios. Sigue las instrucciones que se incluyen a continuación para realizar los cambios apropiados.

Ejecuta los siguientes comandos, copia el archivo actualizado en el nombre de archivo correcto y, luego, imprime su contenido para verificar los cambios:

cd ~/monolith-to-microservices/react-app/src/pages/Home
mv index.js.new index.js
cat ~/monolith-to-microservices/react-app/src/pages/Home/index.js

El código resultante debería verse así:

/*
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    width: "800px",
    margin: "0 auto",
    padding: theme.spacing(3, 2)
  }
}));
export default function Home() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <Paper className={classes.paper}>
        <Typography variant="h5">
          Fancy Fashion &amp; Style Online
        </Typography>
        <br />
        <Typography variant="body1">
          Tired of mainstream fashion ideas, popular trends and societal norms?
          This line of lifestyle products will help you catch up with the Fancy trend and express your personal style.
          Start shopping Fancy items now!
        </Typography>
      </Paper>
    </div>
  );
}

Ya actualizaste los componentes de React, pero debes compilar la app de React para generar archivos estáticos. Ejecuta el siguiente comando para compilar la app y copiarla en el directorio público de monolith:

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

Luego, vuelve a enviar el código a tu bucket de Cloud Storage.

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

Envía los cambios con actualizaciones progresivas

Ahora puedes forzar el reinicio de todas las instancias para realizar la actualización.

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable=100%

Espera unos 30 segundos después de ejecutar el comando rolling-action restart para dar tiempo a que se procesen las instancias y, luego, comprueba el estado del grupo de instancias administrado hasta que las instancias aparezcan en la lista.

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

Una vez que aparezcan en la lista, presiona Control+S (Command+S en Macintosh) para salir del comando watch.

Ejecuta el siguiente comando para confirmar que el servicio figure como healthy:

watch -n 5 gcloud compute backend-services get-health fancy-fe-frontend --global

Resultado de ejemplo:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8080
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8080
  kind: compute#backendServiceGroupHealth

Después de que aparezcan los elementos en la lista, presiona Control+S (Command+S en Macintosh) para salir del comando watch.

Para invalidar el contenido almacenado en caché en la red de distribución de contenido y asegurarte de que se muestre contenido nuevo, ejecuta el siguiente comando:

gcloud compute url-maps invalidate-cdn-cache fancy-map \
    --path "/*"

Dirígete al sitio web a través de http://[LB_IP], donde [LB_IP] es la IP_ADDRESS que se especificó para el balanceador de cargas y que se puede encontrar con el siguiente comando:

gcloud compute forwarding-rules list --global

Ahora deberían verse los cambios en el sitio web nuevo.

b081b8e885bf0723.png

Simula una falla

Para confirmar que funcione la verificación de estado, accede a una instancia y detén los servicios. Para encontrar el nombre de una instancia, ejecuta el siguiente comando:

gcloud compute instance-groups list-instances fancy-fe-mig

Desde allí, conéctate con Secure Shell a una de las instancias, donde INSTANCE_NAME es una de las instancias de la lista:

gcloud compute ssh [INSTANCE_NAME]

En la instancia, usa supervisorctl para detener la app.

sudo supervisorctl stop nodeapp; sudo killall node

Sal de la instancia.

exit

Supervisa las operaciones de reparación.

watch -n 5 gcloud compute operations list \
--filter='operationType~compute.instances.repair.*'

Busca el siguiente resultado de ejemplo:

NAME                                                  TYPE                                       TARGET                                 HTTP_STATUS  STATUS  TIMESTAMP
repair-1568314034627-5925f90ee238d-fe645bf0-7becce15  compute.instances.repair.recreateInstance  us-central1-a/instances/fancy-fe-1vqq  200          DONE    2019-09-12T11:47:14.627-07:00

Después de notar la reparación, presiona Control+C (Command+S en Macintosh) para salir del comando de observación. En este punto, el grupo de instancias administrado vuelve a crear la instancia para repararla.

9. Limpia

Cuando esté todo listo, la forma más fácil de limpiar todas las actividades realizadas es borrar el proyecto. Si borras el proyecto, se borrarán el balanceador de cargas, las instancias, las plantillas y otros elementos creados durante el codelab para garantizar que no se produzcan cargos recurrentes inesperados. Ejecuta lo siguiente en Cloud Shell, donde PROJECT_ID es el ID completo del proyecto, no solo el nombre del proyecto.

gcloud projects delete [PROJECT_ID]

Para confirmar la eliminación, ingresa “Y” cuando se te solicite.

10. ¡Felicitaciones!

Implementaste, escalaste y actualizaste tu sitio web en Compute Engine. Ahora tienes experiencia con Compute Engine, los grupos de instancias administrados, el balanceo de cargas y las verificaciones de estado.