Compartir vía


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
  • 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.

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.

  1. 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" 
    
  2. 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

  1. Instale la extensión de Application Insights en la CLI de Azure.

    az extension add -n application-insights
    
  2. 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
    
  3. Copie el Result de lo generado; necesitará ese valor como su instrumentationKey más adelante.

  4. 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).

  1. 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
    
  2. 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

  1. 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
    
  2. Espere porque el proceso puede tardar unos minutos.

  3. 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.

  4. El proceso habrá creado claves de SSH y en una ubicación indicada en la respuesta.

  5. 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

  1. 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
    
  2. 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.

  3. 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

    Captura de pantalla del explorador web donde aparece la aplicación sencilla que se facilita a través de la máquina virtual de Linux en Azure.

  4. 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

  1. 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.

  2. Si se le pregunta si confirma que desea conectarse, responda y o yes para continuar.

  3. 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
    
  4. 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:
    
  5. La aplicación web se encuentra en el subdirectorio myapp. Cambie al directorio myapp y enumere el contenido:

    cd myapp && ls -l
    
  6. 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

  1. 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
    
  2. Espere hasta que se complete el comando antes de continuar.

Adición de la clave de instrumentación de supervisión

  1. 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
    
  2. Agregue la variable de entorno APPINSIGHTS_INSTRUMENTATIONKEY al principio del script de inicio. En el ejemplo siguiente, reemplace REPLACE-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"
    
  3. Todavía en el terminal SSH, guarde el archivo en el editor Nano con control + X.

  4. Si se le pide en el editor Nano, escriba Y para guardar.

  5. 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.

  1. 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 
    
  2. Reemplace el index.js original por el archivo mediante Application Insights.

    sudo npm run-script appinsights
    
  3. 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()}`)
    })
    
  4. Reinicie la aplicación con PM2 para seleccionar la siguiente variable de entorno.

    sudo npm start
    

Usar la aplicación para comprobar el registro

  1. 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
  1. 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
  1. 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
  1. 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
    
  2. El registro incluye la llamada desde el equipo local.

    grep "Hello world app listening on port 3000!" /var/log/pm2.log
    
  3. 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.

Código de ejemplo

Pasos siguientes