En este ejemplo avanzado se muestra cómo crear una aplicación de registro que usa Node.js para el frontend y MySQL para el backend. La plantilla también crea y conecta un balanceador de carga HTTP que balancea la carga entre dos zonas, así como un escalador automático para escalar la aplicación automáticamente.
En este ejemplo, se da por hecho que conoces los contenedores Docker y los recursos de Compute Engine, en concreto el balanceo de carga HTTP, el autoescalado, los grupos de instancias gestionados y las plantillas de instancia.
Para ver más tutoriales de introducción, consulta la guía de inicio o la guía paso a paso.
Antes de empezar
- Si quieres usar los ejemplos de línea de comandos de esta guía, instala la herramienta de línea de comandos`gcloud`.
- Si quieres usar los ejemplos de API de esta guía, configura el acceso a la API.
- Tener experiencia con el balanceo de carga de HTTP de Compute Engine.
- Tener experiencia con los contenedores Docker.
Crear plantillas
En este ejemplo se inicia una implementación con varios tipos de recursos. Para empezar, crea plantillas reutilizables que definan estos recursos por separado. Más adelante, utilizarás estas plantillas en la configuración final.
Al final de este ejemplo, tendrás una implementación que contenga estos recursos:
- Una sola instancia de Compute Engine para la máquina virtual MySQL de backend.
- Una plantilla de instancia que usa una imagen de Docker.
- Dos grupos de instancias gestionados con escalado automático en dos zonas diferentes que ejecutan el servicio frontend de Node.js.
- Otros dos grupos de instancias gestionados autoescalados que sirven datos estáticos.
- Una comprobación del estado y un balanceador de carga HTTP para distribuir el tráfico entre los grupos de instancias gestionadas correspondientes.
Crear las plantillas de backend
El backend de esta aplicación es una única instancia de Compute Engine que ejecuta un contenedor de Docker de MySQL. Crea una plantilla que defina una instancia de Compute Engine
que utilice una imagen optimizada para contenedores. Ponle el nombre container_vm.[py|jinja]
al archivo:
Jinja
Python
La plantilla define una serie de variables, como containerImage
y manifest
, que se rellenarán cuando defina la configuración. Esta plantilla solo crea una instancia de máquina virtual.
Cuando usas imágenes de contenedor en instancias de Compute Engine, también debes proporcionar un archivo de manifiesto (distinto de un manifiesto de Deployment Manager) para describir a Compute Engine qué imagen de contenedor debe usar. Crea un método auxiliar llamado container_helper.[py|jinja]
para definir dinámicamente el manifiesto del contenedor:
Jinja
Python
Crear las plantillas de frontend
El frontend de esta aplicación ejecuta Node.js y permite a los usuarios publicar mensajes en la página web. Habrá dos grupos de instancias gestionados que contengan dos instancias cada uno: un grupo de instancias gestionado principal y un grupo de instancias gestionado secundario para el balanceo de carga.
Para crear estas plantillas de frontend, siga estas instrucciones.
Crea una plantilla de instancia.
Necesitas un recurso de plantilla de instancia para crear un grupo de instancias gestionado, que es un grupo de instancias de VM idénticas que se gestionan de forma centralizada. En este ejemplo se crea un grupo de instancias gestionado para las instancias de frontend de Node.js, pero primero debes crear la plantilla de instancia.
Define un archivo llamado
container_instance_template.[py|jinja]
:Jinja
Python
Crea un grupo de instancias gestionado con escalado automático.
Ahora que tienes una plantilla de instancia, puedes definir una plantilla que la use para crear un grupo de instancias gestionado con escalado automático. Crea un archivo llamado
autoscaled_group.[py|jinja]
con el siguiente contenido:Jinja
Python
Crea el archivo de esquema correspondiente:
Jinja
Python
Crea recursos con estas plantillas.
Hasta ahora, has definido plantillas base que determinan las propiedades de tus recursos. Con estas plantillas, define la configuración de tu frontend. Crea un archivo llamado
service.[py|jinja]
con el siguiente contenido:Jinja
Python
Crea el archivo de esquema correspondiente:
Jinja
Python
Vamos a desglosar lo que crea esta plantilla:
Dos grupos de instancias gestionados, uno principal y otro secundario.
La plantilla usa la plantilla
autoscaled_group.[py|jinja]
para crear un grupo de instancias gestionado con autoescalado principal y otro secundario.A continuación, la plantilla crea un servicio de backend y un comprobador de estado. Se necesita un servicio de backend para el balanceo de carga HTTP, que define la capacidad de servicio de los grupos de instancias de ese servicio de backend. En este caso, los grupos de instancias gestionados primario y secundario forman parte de este backend, y se aplican las propiedades predeterminadas del servicio de backend.
De forma predeterminada, un servicio de backend realiza el balanceo de carga en función del uso de CPU de los grupos de instancias asociados, pero también puedes balancear la carga en función de las solicitudes por segundo (RPS).
Nota: Siempre se requiere una comprobación del estado al crear un servicio de backend.
Crear una plantilla unificadora
Por último, crea una plantilla unificada que combine las plantillas de backend y de frontend. Crea un archivo llamado application.[py|jinja]
:
Jinja
Python
Crea un archivo de esquema correspondiente:
Jinja
Python
Además del frontend y el backend, la plantilla también define algunos recursos adicionales:
Un servicio estático con grupos de instancias gestionadas principales y secundarios. Este servicio estático sirve una página web ubicada en la ruta
/static
de tu aplicación.Recurso URLMap. El balanceo de carga HTTP requiere un mapa de URLs para asignar las diferentes URLs a las rutas correctas. En este caso, la ruta predeterminada, indicada por la propiedad
defaultService
, es el servicio de backend que has creado anteriormente. Si un usuario accede a/static
, el mapa de URLs asignará esa ruta al servicio estático, tal como se define en la secciónpathMatchers
.Una regla de reenvío global y un proxy HTTP de destino. Como la carga de la aplicación se equilibra entre dos zonas independientes, necesitarás una regla de reenvío global que sirva una única dirección IP externa. Además, se necesita un proxy HTTP de destino para configurar el balanceo de carga HTTP.
Una regla de cortafuegos que permite el tráfico a través del puerto 8080.
Crear una configuración
Ahora que tienes listas tus plantillas y los esquemas relacionados, puedes crear una configuración que despliegue estos recursos. Crea un archivo de configuración llamado application.yaml
con el siguiente contenido y sustituye ZONE_TO_RUN
y SECONDARY_ZONE_TO_RUN
por las zonas principal y secundaria que elijas.
Jinja
Python
Desplegar la configuración
Ahora, vamos a desplegar tus recursos. Con la CLI de Google Cloud, ejecuta el siguiente comando. También puedes sustituir advanced-configuration-l7
por el nombre de implementación que quieras. Ten en cuenta que el nombre del despliegue se usará automáticamente para nombrar los recursos.
En este ejemplo, el nombre de la implementación es advanced-configuration-l7
. Si decides cambiar el nombre de la implementación, asegúrate de usarlo en todos los ejemplos siguientes.
gcloud deployment-manager deployments create advanced-configuration-l7 --config application.yaml
La respuesta debería ser similar a la de los siguientes recursos:
Waiting for create operation-1469468950934-5387966d431f0-49b11bc4-1421b2f0...done. Create operation operation-1469468950934-5387966d431f0-49b11bc4-1421b2f0 completed successfully. NAME TYPE STATE ERRORS advanced-configuration-l7-application-fw compute.v1.firewall COMPLETED [] advanced-configuration-l7-application-l7lb compute.v1.globalForwardingRule COMPLETED [] advanced-configuration-l7-application-targetproxy compute.v1.targetHttpProxy COMPLETED [] advanced-configuration-l7-application-urlmap compute.v1.urlMap COMPLETED [] advanced-configuration-l7-backend compute.v1.instance COMPLETED [] advanced-configuration-l7-frontend-bes compute.v1.backendService COMPLETED [] advanced-configuration-l7-frontend-hc compute.v1.httpHealthCheck COMPLETED [] advanced-configuration-l7-frontend-it compute.v1.instanceTemplate COMPLETED [] advanced-configuration-l7-frontend-pri-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-frontend-pri-igm compute.v1.instanceGroupManager COMPLETED [] advanced-configuration-l7-frontend-sec-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-frontend-sec-igm compute.v1.instanceGroupManager COMPLETED [] advanced-configuration-l7-static-service-bes compute.v1.backendService COMPLETED [] advanced-configuration-l7-static-service-hc compute.v1.httpHealthCheck COMPLETED [] advanced-configuration-l7-static-service-it compute.v1.instanceTemplate COMPLETED [] advanced-configuration-l7-static-service-pri-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-static-service-pri-igm compute.v1.instanceGroupManager COMPLETED [] advanced-configuration-l7-static-service-sec-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-static-service-sec-igm compute.v1.instanceGroupManager COMPLETED []
Añadir etiquetas de servicio
A continuación, especifica las etiquetas de servicio adecuadas para tus grupos de instancias gestionadas. Las etiquetas de servicio son metadatos que utiliza el servicio de balanceo de carga para agrupar recursos.
Para añadir etiquetas de servicio, ejecuta los siguientes comandos, que coincidan con las zonas primarias y secundarias que hayas seleccionado en el archivo de configuración de la implementación:
gcloud compute instance-groups unmanaged set-named-ports advanced-configuration-l7-frontend-pri-igm \
--named-ports http:8080,httpstatic:8080 \
--zone [PRIMARY_ZONE]
gcloud compute instance-groups unmanaged set-named-ports advanced-configuration-l7-frontend-sec-igm \
--named-ports http:8080,httpstatic:8080 \
--zone [SECONDARY_ZONE]
Probar la configuración
Para probar la configuración, obtén la dirección IP externa que está sirviendo el tráfico consultando la regla de reenvío:
gcloud compute forwarding-rules list | grep advanced-configuration-l7-l7lb advanced-configuration-l7-l7lb 107.178.249.126 TCP advanced-configuration-l7-targetproxy
En este caso, la IP externa es 107.178.249.126
.
En un navegador, visita la dirección IP externa en el puerto 8080. Por ejemplo, si tu IP externa es 107.178.249.126
, la URL sería la siguiente:
http://107.178.249.126:8080
Debería mostrarse una página en blanco, que es lo esperado. A continuación, publica un mensaje en la página. Ve a la URL siguiente:
http://107.178.249.126:8080?msg=hello_world!
Verás una confirmación de que se ha añadido tu mensaje. Vuelve a la URL principal. Ahora, la página debería mostrar el siguiente mensaje:
hello_world!
También puedes visitar la página estática que has creado o comprobar el estado de tu aplicación en las siguientes URLs:
# Static web page
http://107.178.249.126:8080/static
# Health check
http://107.178.249.126:8080/_ah/health
Enhorabuena, has implementado tu configuración correctamente.
(Opcional) Crear imágenes de Docker
Docker te permite automatizar y ejecutar software en contenedores. Los contenedores te permiten aislar diferentes servicios en contenedores que pueden ejecutarse en una sola instancia de Linux.
En este ejemplo se han usado algunas imágenes Docker, pero también puedes crear tus propias versiones de estas imágenes. Puedes consultar las instrucciones para crear las imágenes de backend de MySQL y las imágenes de frontend de Node.js en la sección Crear plantillas de recursos.
Para crear la imagen Docker que sirve la página web estática, sigue estos pasos:
Crea una instancia de VM con una imagen optimizada para contenedores:
gcloud compute instances create docker-playground \ --image-family container-vm \ --image-project google-containers \ --zone us-central1-a \ --machine-type f1-micro
Conéctate a la instancia:
gcloud compute ssh --zone us-central1-a docker-playground
Crea un archivo llamado
Dockerfile
con el siguiente contenido:FROM node:latest RUN mkdir /var/www/ ADD service.js /var/www/service.js WORKDIR /var/www/ RUN npm install mysql CMD ["node", "service.js"]
Crea un archivo llamado
service.js
con el siguiente contenido:var http = require('http'); var url = require('url'); console.log('Started static node server') http.createServer(function (req, res) { reqUrl = url.parse(req.url, true); res.useChunkedEncodingByDefault = false; res.writeHead(200, {'Content-Type': 'text/html'}); if (reqUrl.pathname == '/_ah/health') { res.end('ok'); } else if (reqUrl.pathname == '/exit') { process.exit(-1) } else { res.end('static server'); } }).listen(8080, '0.0.0.0'); console.log('Static server running at http://127.0.0.1:8080/');
Compila la imagen Docker y sustituye
username
por tu nombre de usuario de Docker Hub. Si no tienes un nombre de usuario de Docker Hub, crea uno antes de compilar la imagen Docker.sudo docker build --no-cache -t username/nodejsservicestatic .
Envía las imágenes al repositorio de Docker:
sudo docker push username/nodejsservicestatic
Ahora tienes las imágenes de Docker para ejecutar Node.js y MySQL. Puedes ver estas imágenes en el repositorio buscando los nombres de las imágenes. Para probar las imágenes, puedes sustituir todas las instancias de
gcr.io/deployment-manager-examples/mysql
y
gcr.io/deployment-manager-examples/nodejsservice
por las imágenes correspondientes.
Pasos siguientes
Una vez que haya completado esta muestra, podrá hacer lo siguiente:
- Sigue desarrollando este ejemplo creando una página web más sólida o añadiendo más servicios al servidor web.
- Consulta más información sobre las configuraciones o las implementaciones.
- Prueba a crear tus propias configuraciones.