Creación de una máquina virtual Express.js con la CLI de Azure
En este tutorial, creará una máquina virtual Linux para una aplicación de Express.js. La máquina virtual se configura con un archivo de configuración cloud-init e incluye NGINX y un repositorio de GitHub para una aplicación de Express.js. Podrá conectarse a la máquina virtual mediante SSH, cambiar la aplicación web para incluir el registro de seguimientos y ver la aplicación de servidor de Express.js pública en un explorador web.
Este tutorial incluye las siguientes tareas:
- Inicio de sesión en Azure con la CLI de Azure
- Creación de un recurso de máquina virtual Linux de Azure con la CLI de Azure
- Apertura del puerto público 80
- Instalación de la aplicación web de Express.js de demostración desde un repositorio de GitHub
- Instalación de las dependencias de la aplicación web
- Inicio de la aplicación web
- Creación de un recurso de Azure Monitor con la CLI de Azure
- Conexión a la máquina virtual con SSH
- Instalación de la biblioteca cliente del SDK de Azure con npm
- Adición del código de la biblioteca cliente de Application Insights para crear el seguimiento personalizado
- Ver la aplicación web en el explorador
- Solicitud de la ruta
/trace
para generar el seguimiento personalizado en el registro de Application Insights - Visualización del recuento de seguimientos recopilados en el registro con la CLI de Azure
- Visualización de la lista de seguimientos con Azure Portal
- Solicitud de la ruta
- Eliminación de los recursos con la CLI de Azure
Requisitos previos
- Una cuenta de usuario y una suscripción de Azure: cree una suscripción gratuita.
- SSH para conectarse a la máquina virtual: use Azure Cloud Shell o un terminal moderno, como el shell Bash, que incluye SSH.
Use el entorno de Bash en Azure Cloud Shell. Para más información, consulte Inicio rápido para Bash en Azure Cloud Shell.
Si prefiere ejecutar comandos de referencia de la CLI localmente, instale la CLI de Azure. Si utiliza Windows o macOS, considere la posibilidad de ejecutar la CLI de Azure en un contenedor Docker. Para más información, vea Ejecución de la CLI de Azure en un contenedor de Docker.
Si usa una instalación local, inicie sesión en la CLI de Azure mediante el comando az login. Siga los pasos que se muestran en el terminal para completar el proceso de autenticación. Para ver otras opciones de inicio de sesión, consulte Inicio de sesión con la CLI de Azure.
En caso de que se le solicite, instale las extensiones de la CLI de Azure la primera vez que la use. Para más información sobre las extensiones, consulte Uso de extensiones con la CLI de Azure.
Ejecute az version para buscar cuál es la versión y las bibliotecas dependientes que están instaladas. Para realizar la actualización a la versión más reciente, ejecute az upgrade.
1. Creación de un recurso de Application Insights para páginas web
Cree un grupo de recursos de Azure para todos los recursos de Azure y un recurso de Azure Monitor para recopilar los archivos de registro de la aplicación web en la nube de Azure. Al crear un grupo de recursos podrá encontrar fácilmente los recursos y eliminarlos cuando haya terminado. Azure Monitor es el nombre del servicio de Azure, mientras que Application Insights es el nombre de la biblioteca cliente que usa el tutorial.
De forma opcional, si tiene más de una suscripción, use az account set para crear la suscripción predeterminada antes de completar los comandos restantes.
az account set \ --subscription "ACCOUNT NAME OR ID"
Cree un grupo de recursos de Azure con az group create. Use el nombre
rg-demo-vm-eastus
:az group create \ --location eastus \ --name rg-demo-vm-eastus
Creación de un recurso de Azure Monitor con la CLI de Azure
Instale la extensión de Application Insights en la CLI de Azure.
az extension add -n application-insights
Use el comando siguiente para crear un recurso de supervisión, con az monitor app-insights component create:
az monitor app-insights component create \ --app demoWebAppMonitor \ --location eastus \ --resource-group rg-demo-vm-eastus \ --query instrumentationKey --output table
Copie el Result de lo generado; necesitará ese valor como su
instrumentationKey
más adelante.Deje el terminal abierto, ya que lo usará en el paso siguiente.
2. Creación de una máquina virtual Linux con la CLI de Azure
Se usa un archivo de configuración cloud-init para crear el servidor proxy inverso de NGINX y el servidor de Express.js. NGINX se usa para reenviar el puerto de Express.js (3000) al puerto público (80).
Cree un archivo local llamado
cloud-init-github.txt
y guarde el contenido siguiente en el archivo, o bien guarde el archivo del repositorio en el equipo local. El archivo con formato cloud-init debe existir en la misma carpeta que la ruta de acceso del terminal para los comandos de la CLI de Azure.#cloud-config package_upgrade: true packages: - nginx write_files: - owner: www-data:www-data path: /etc/nginx/sites-available/default content: | server { listen 80 default_server; server_name _; location / { # First, try if the file exists locally, otherwise request it from the app try_files $uri @app; } location @app { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } runcmd: # install Node.js - 'curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -' - 'sudo apt-get install -y nodejs' # clone GitHub Repo into myapp directory - 'cd /home/azureuser' - git clone "https://github.com/Azure-Samples/js-e2e-vm" myapp # Start app - 'cd myapp && npm install && npm start' # restart NGINX - systemctl restart nginx
Revise la sección
runcmd
del archivo para comprender lo que hace.runcmd
tiene varias tareas:- Descargar Node.js e instalarlo
- Clonar el repositorio Express.js de ejemplo de GitHub en el directorio
myapp
- Instalar las dependencias de la aplicación
- Iniciar la aplicación de Express.js con PM2
Creación de un recurso de máquina virtual
Escriba el comando de la CLI de Azure az vm create en un terminal para crear un recurso de Azure de una máquina virtual Linux. El comando crea la máquina virtual a partir del archivo cloud-init y genera las claves SSH automáticamente. El comando en ejecución muestra dónde se almacenan las claves.
az vm create \ --resource-group rg-demo-vm-eastus \ --name demo-vm \ --location eastus \ --public-ip-sku Standard \ --image UbuntuLTS \ --admin-username azureuser \ --generate-ssh-keys \ --custom-data cloud-init-github.txt
Espere porque el proceso puede tardar unos minutos.
Guarde el valor de publicIpAddress de la respuesta, ya que es necesario para ver la aplicación web en un explorador y conectarse a la máquina virtual. Si pierde esta dirección IP, use el comando de la CLI de Azure, az vm list-ip-addresses para obtenerla de nuevo.
El proceso habrá creado claves de SSH y en una ubicación indicada en la respuesta.
Vaya a esa ubicación y cree el archivo
authorized_keys
:cd <SSH-KEY-LOCATION> && cat id_rsa >> authorized_keys
Apertura del puerto de la máquina virtual
Cuando se crea por primera vez, la máquina virtual no tiene puertos abiertos. Abra el puerto 80 con el siguiente comando de la CLI de Azure, az vm open-port, para que la aplicación web esté disponible públicamente:
az vm open-port \
--port 80 \
--resource-group rg-demo-vm-eastus \
--name demo-vm
Ir al sitio web
Use la dirección IP pública en un explorador web para asegurarse de que la máquina virtual está disponible y en ejecución. Cambie la dirección URL para usar el valor de
publicIpAddress
.http://YOUR-VM-PUBLIC-IP-ADDRESS
Si se produce un error de puerta de enlace en el recurso, inténtelo de nuevo en un minuto, la aplicación web puede tardar un minuto en iniciarse.
La aplicación web de la máquina virtual devuelve la siguiente información:
- Nombre de la máquina virtual
- Dirección IP del cliente
- Fecha y hora actuales
El archivo de código inicial de la aplicación web tiene una sola ruta, que pasa mediante el proxy NGINX.
const os = require('os'); const express = require('express') const app = express() app.use('/public', express.static('public')) app.get('/', function (req, res) { const clientIP = req.headers['x-forwarded-for']; const msg = `HostName: ${os.hostname()}<br>ClientIP: ${clientIP}<br>DateTime: ${new Date()}<br><img width='200' height='200' src='/public/leaves.jpg' alt='flowers'>` console.log(msg) res.send(msg) }) app.listen(3000, function () { console.log(`Hello world app listening on port 3000! ${Date.now()}`) })
3. Conexión a una máquina virtual de Linux con SSH
En esta sección del tutorial, usará SSH en un terminal para conectarse a la máquina virtual. SSH es una herramienta común que se proporciona con muchos shells modernos, incluido Azure Cloud Shell.
Conexión con SSH y cambio de la aplicación web
Conéctese a la máquina virtual remota con el siguiente comando.
Reemplace
YOUR-VM-PUBLIC-IP
por la dirección IP pública de su propia máquina virtual.ssh azureuser@YOUR-VM-PUBLIC-IP
En este proceso se supone que el cliente SSH puede encontrar las claves SSH, creadas como parte de la creación de la máquina virtual y ubicadas en el equipo local.
Si se le pregunta si confirma que desea conectarse, responda
y
oyes
para continuar.Use el comando siguiente para saber dónde se encuentra en la máquina virtual. Debe estar en la carpeta raíz de azureuser:
/home/azureuser
.pwd
Una vez completada la conexión, el símbolo del sistema del terminal debería cambiar para indicar el nombre de usuario y el nombre de recurso de la máquina virtual remota.
azureuser@demo-vm:
La aplicación web se encuentra en el subdirectorio
myapp
. Cambie al directoriomyapp
y enumere el contenido:cd myapp && ls -l
Debería ver contenido como si representara el repositorio de GitHub clonado en la máquina virtual y los archivos del paquete npm:
-rw-r--r-- 1 root root 891 Nov 11 20:23 cloud-init-github.txt -rw-r--r-- 1 root root 1347 Nov 11 20:23 index-logging.js -rw-r--r-- 1 root root 282 Nov 11 20:23 index.js drwxr-xr-x 190 root root 4096 Nov 11 20:23 node_modules -rw-r--r-- 1 root root 84115 Nov 11 20:23 package-lock.json -rw-r--r-- 1 root root 329 Nov 11 20:23 package.json -rw-r--r-- 1 root root 697 Nov 11 20:23 readme.md
Instalación del SDK de supervisión
En el terminal SSH que está conectado a la máquina virtual, instale la biblioteca cliente de Azure SDK para Application Insights.
sudo npm install --save applicationinsights
Espere hasta que se complete el comando antes de continuar.
Adición de la clave de instrumentación de supervisión
En el terminal SSH, que está conectado a la máquina virtual, use el editor Nano para abrir el archivo
package.json
.sudo nano package.json
Agregue la variable de entorno
APPINSIGHTS_INSTRUMENTATIONKEY
al principio del script de inicio. En el ejemplo siguiente, reemplaceREPLACE-WITH-YOUR-KEY
por el valor de la clave de instrumentación."start": "APPINSIGHTS_INSTRUMENTATIONKEY=REPLACE-WITH-YOUR-KEY pm2 start index.js --watch --log /var/log/pm2.log"
Todavía en el terminal SSH, guarde el archivo en el editor Nano con control + X.
Si se le pide en el editor Nano, escriba Y para guardar.
Si se le pide en el editor Nano, acepte el nombre de archivo cuando se le solicite.
Detener la máquina virtual para cambiar la aplicación
La biblioteca cliente de Azure está ahora en el directorio node_modules y la clave se pasa a la aplicación como una variable de entorno. En el paso siguiente se usa Application Insights mediante programación.
Detenga PM2, que es un administrador de procesos de producción para aplicaciones de Node.js, con los siguientes comandos:
sudo npm run-script stop
Reemplace el
index.js
original por el archivo mediante Application Insights.sudo npm run-script appinsights
La biblioteca cliente y el código de registro se facilitan automáticamente.
const express = require('express') const app = express() const os = require('os'); console.log(JSON.stringify(process.env)); const AppInsights = require('applicationinsights'); if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) { console.log(`AppInsights configured with key ${process.env.APPINSIGHTS_INSTRUMENTATIONKEY}`); } else{ console.log(`AppInsights not configured`); } AppInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY) .setAutoDependencyCorrelation(true) .setAutoCollectRequests(true) .setAutoCollectPerformance(true, true) .setAutoCollectExceptions(true) .setAutoCollectDependencies(true) .setAutoCollectConsole(true) .setUseDiskRetryCaching(true) .setSendLiveMetrics(false) .setDistributedTracingMode(AppInsights.DistributedTracingModes.AI) .start(); const AppInsightsClient = AppInsights.defaultClient; app.get('/trace', (req, res) => { const clientIP = req.headers['x-forwarded-for']; const msg = `trace route ${os.hostname()} ${clientIP} ${new Date()}`; console.log(msg) if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) { AppInsightsClient.trackPageView(); AppInsightsClient.trackTrace({ message: msg }) AppInsightsClient.flush(); } else { msg += ' AppInsights not configured'; } res.send(`${msg}`) }) app.get('/', function (req, res) { const clientIP = req.headers['x-forwarded-for']; const msg = `root route ${os.hostname()} ${clientIP} ${new Date()}` console.log(msg) res.send(msg) }) app.listen(3000, function () { console.log(`Hello world app listening on port 3000! ${os.hostname()}`) })
Reinicie la aplicación con PM2 para seleccionar la siguiente variable de entorno.
sudo npm start
Usar la aplicación para comprobar el registro
En un explorador web, pruebe la aplicación con la nueva ruta
trace
:http://YOUR-VM-PUBLIC-IP-ADDRESS/trace
El explorador muestra la respuesta
trace route demo-vm YOUR-CLIENT-IP VM-DATE-TIME
con la dirección IP.
Visualización del registro de NGINX
La máquina virtual (VM) recopila los registros de NGINX, que están disponibles para ver.
Service | Ubicación del registro |
---|---|
NGINX | /var/log/nginx/access.log |
- Todavía en el terminal SSH, consulte el registro de la máquina virtual para el servicio de proxy NGINX con el siguiente comando para ver el registro:
cat /var/log/nginx/access.log
- El registro incluye la llamada desde el equipo local.
"GET /trace HTTP/1.1" 200 10 "-"
Visualización del registro de PM2
La máquina virtual recopila los registros de PM2, que están disponibles para ver.
Service | Ubicación del registro |
---|---|
PM2 | /var/log/pm2.log |
Consulte el registro de la máquina virtual para el servicio PM2, que es la aplicación web de Node de Express.js. En el mismo shell de Bash, use el siguiente comando para ver el registro:
cat /var/log/pm2.log
El registro incluye la llamada desde el equipo local.
grep "Hello world app listening on port 3000!" /var/log/pm2.log
El registro también incluye las variables de entorno, incluida la clave de ApplicationInsights, que se pasan en el script de inicio de npm. Utilice el siguiente comando grep para comprobar que la clave está en las variables de entorno.
grep APPINSIGHTS_INSTRUMENTATIONKEY /var/log/pm2.log
Esto muestra el registro de PM2 con el valor de
APPINSIGHTS_INSTRUMENTATIONKEY
resaltado en un color diferente.
Registro de máquinas virtuales y registro en la nube
En esta aplicación, el uso de console.log
escribe solo los mensajes en los registros de PM2 que se encuentran en la máquina virtual. Si elimina los registros o la máquina virtual, perderá esa información.
Si desea conservar los registros más allá de la duración de la máquina virtual, use Application Insights.
5. Limpieza de recursos
Una vez que haya terminado el tutorial, deberá eliminar el grupo de recursos que incluye todos los recursos para asegurarse de que no se le facturará por ningún uso adicional.
En el mismo terminal, use el comando de la CLI de Azure az group delete para eliminar el grupo de recursos:
az group delete --name rg-demo-vm-eastus -y
Este comando tarda unos minutos.
Solución de problemas
Si tiene problemas, use la tabla siguiente para saber cómo resolver el problema:
Problema | Solución |
---|---|
Error de puerta de enlace incorrecta 502 | Esto podría indicar que el archivo index.js o package.js tienen un error. Consulte los registros de PM2 en /var/log/pm2.log para más información. El error más reciente se encuentra en la parte inferior del archivo. Si no sabe con seguridad si esos archivos son los correctos, detenga e inicie PM2 mediante los scripts npm en package.json . |