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 que se usa 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 detallado sobre distintos aspectos de la infraestructura, como las máquinas virtuales y el balanceador de cargas, entre otros. Hoy, implementarás una app de muestra (el sitio web de comercio electrónico de Fancy Store) para mostrar cómo se puede implementar y escalar fácilmente 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 no incurrir en facturación más allá de este instructivo. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de$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 las 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 base para tu sitio web. Clonarás el código fuente desde 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 demostrar la simplicidad de las actualizaciones en Compute Engine.

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 manualmente con los siguientes comandos dentro de 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 secuencia de comandos demore unos minutos en ejecutarse.

./setup.sh

Realiza la diligencia debida y prueba tu app. Ejecuta el siguiente comando para iniciar tu 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 aplicación, 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 terminal.

4. Crea instancias de Compute Engine

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

  1. Crea una secuencia de comandos de inicio para configurar las instancias.
  2. Clona el código fuente y súbelo a Cloud Storage.
  3. Implementa una instancia de Compute Engine para alojar los microservicios de backend.
  4. Reconfigura el código de frontend para utilizar la instancia de microservicios de backend.
  5. Implementa una instancia de Compute Engine para alojar el microservicio de frontend.
  6. Configura 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 de 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

Ahora, la línea de código de startup-script.sh debería ser similar a la siguiente:

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 aplicación como un daemon
  • Clonación del código fuente de la app desde el bucket de Cloud Storage e instalación de dependencias
  • Configuración de Supervisor, que ejecuta la app, asegúrate de que esta se reinicie si un administrador o proces la cierra o la detiene de manera inesperada, y envía el stdout y stderr de la app a syslog para que el agente de Logging los recopile.

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

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

Ahora se puede acceder en https://storage.googleapis.com/[BUCKET_NAME]/startup-script.sh. [BUCKET_NAME] representa el nombre del bucket de Cloud Storage. De forma predeterminada, este archivo solo estará visible para cuentas de servicio y usuarios autorizados, por lo que no se podrá acceder a él a través de 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’ archivo 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 que esté configurada para usar la secuencia de comandos de inicio que creaste con anterioridad y está etiquetada como una instancia de backend para que luego puedas aplicarle reglas de firewall específicas:

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 desde 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. Desde el menú Editor de código, selecciona Ver > Activa o desactiva la opción Archivos ocultos para ver el archivo .env.

e7314ceda643e16.png

Edita el archivo .env para que apunte a la dirección IP externa del backend. [BACKEND_ADDRESS] 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

Ahora que el código está configurado, puedes implementar la instancia de frontend. Ejecuta el siguiente comando para implementar la instancia de frontend con un comando similar al anterior, pero que está etiquetado como “frontend” con fines de 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

Crear reglas de firewall para permitir el acceso al puerto 8080 para el frontend y a los puertos 8081 y 8082 para el backend Los comandos de firewall usan las etiquetas que se asignan al momento de crear las instancias de 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. Para determinar la dirección, busca la IP_EXTERNA 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 cancelar el comando watch.

80dc8721dc08d7e4.png

Navega a http://[FRONTEND_ADDRESS]:8080 con una nueva pestaña del navegador web para acceder al sitio web, donde [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 usará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 única zona. Los grupos de instancias administrados mantienen la alta disponibilidad de tus apps, ya que conservan tus 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 las instancias que se usarán cuando crees nuevas instancias de máquina virtual (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 estarán configurados para tener dos instancias en cada grupo para iniciarse. Las instancias recibirán automáticamente un nombre según el “base-instance-name” especificada 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

En tu aplicación, el microservicio 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 se trata de puertos no estándar, deberás especificar 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 usa esa información, que configurarás más adelante.

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

Configura la reparación automática

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

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

Crea una verificación de estado que repara la instancia si no está en buen estado tres veces consecutivas para el frontend y el backend:

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 reglas de rutas de acceso. Eso 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 Descripción general del balanceo de cargas.

Crear balanceo de cargas de HTTP(S)

Google Cloud ofrece muchos tipos diferentes de balanceo de cargas, pero tú usarás el balanceo de cargas 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, se encriptará la solicitud 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 los protocolos HTTPS o HTTP/2, cada instancia de los servicios de backend debe tener un certificado SSL.

Crear verificaciones de estado que se usará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 usará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 qué URLs se dirigen hacia cada servicio de backend.

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

Crear un comparador de rutas de acceso para permitir que las rutas de acceso /api/orders y /api/products se enruten a 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 en el frontend para que apunte a la nueva dirección en lugar de a la dirección efímera que usaste antes y que llevaba a la instancia del backend.

En Cloud Shell, cambia a la carpeta react-app, que contiene el archivo .env que contiene 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 apunte 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 de 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 aproximadamente 30 segundos después de emitir 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

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

Confirma que el servicio esté 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

Cuando los elementos aparezcan en la lista, presiona Control+C (Command+C en Macintosh) para salir del comando watch.

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 es completamente funcional, 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 basada en el 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 agregue automáticamente instancias cuando el balanceador de cargas supere el 60% de uso y quite las instancias cuando el uso sea inferior al 60%.

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 ayudar con el escalamiento es habilitar Cloud CDN, un servicio de red de distribución de contenidos, para que proporcione almacenamiento en caché al servicio de frontend. Para hacerlo, 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 a la solicitud en la caché de Cloud CDN. Si el frontend encuentra una respuesta almacenada en caché, la envía al usuario. Esto se denomina acierto de caché.

De lo contrario, si el frontend no puede encontrar una respuesta almacenada en caché para la solicitud, envía 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 la caché pueda usarse en solicitudes posteriores.

8. Actualizar sitio web

Actualiza la plantilla de instancias

No se pueden editar las plantillas de instancias existentes. 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 cambiar 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.

Actualizar 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 de instancias, lanzarás la nueva y confirmarás que el archivo existe 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 a uno personalizado con 4 CPU virtuales y 3,840 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 configurada como None, y con INSTANCE_TEMPLATE establecido como el nuevo nombre de la plantilla (fancy-fe-new), copia el nombre de una de las máquinas enumeradas para su uso en el siguiente comando.

Control+S (Command+S en Macintosh) para salir del proceso de observación

Ejecute 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 cambies la página principal de tu sitio. Cree que debería tener más información sobre su empresa y lo que vende. En esta sección, agregarás texto a la página principal para satisfacer al equipo de marketing. Parece que uno de los desarrolladores ya creó los cambios con el archivo llamado 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 el 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 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 aproximadamente 30 segundos después de que se emita el comando de reinicio de acción progresiva 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

Cuando los elementos 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 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 los elementos aparezcan en la lista, presiona Control+S (Command+S en Macintosh) para salir del comando watch.

Para invalidar el contenido almacenado en caché dentro de la red de distribución de contenidos 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.

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í, protege el shell en 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

Supervisar 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 ver la reparación, Control+C (Command+S en Macintosh) para salir del comando watch. En este punto, el grupo de instancias administrado vuelve a crear la instancia para repararla.

9. Limpia

Una vez que esté listo, la forma más fácil de borrar 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 el siguiente comando en Cloud Shell, en el que PROJECT_ID es el ID completo del proyecto, no solo el nombre.

gcloud projects delete [PROJECT_ID]

Ingresa “Y” para confirmar la eliminación. cuando se te solicite.

10. ¡Felicitaciones!

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