Compartir a través de


Tutorial: Desarrollo de módulos de IoT Edge mediante Visual Studio Code

Se aplica a:Marca de verificación de IoT Edge 1.5 IoT Edge 1.5

Importante

IoT Edge 1.5 LTS es la versión compatible. IoT Edge 1.4 LTS finaliza su ciclo de vida el 12 de noviembre de 2024. Si está usando una versión anterior, consulte Actualización de IoT Edge.

En este tutorial se muestra cómo desarrollar e implementar el código en un dispositivo IoT Edge. Los módulos de Azure IoT Edge permiten implementar código que ejecuta la lógica de negocios directamente en el dispositivo IoT Edge. En el inicio rápido Implementación de código en un dispositivo Linux, configuras un dispositivo perimetral IoT e implementas un módulo desde el Marketplace de Azure.

En este artículo se describen los pasos para dos herramientas de desarrollo de IoT Edge:

  • La herramienta de línea de comandos (CLI) de Azure IoT Edge Dev Tool es la preferida para el desarrollo.
  • Extensión de herramientas de Azure IoT Edge para Visual Studio Code, que está en modo de mantenimiento.

Use el botón del selector de herramientas al principio de este artículo para elegir la herramienta.

En este tutorial, aprenderá a:

  • Configuración de la máquina de desarrollo
  • Uso de las herramientas de IoT Edge para crear un nuevo proyecto
  • Compilación del proyecto como contenedor de Docker y almacénelo en un registro de contenedor de Azure
  • Implementación del código en un dispositivo IoT Edge

El módulo de IoT Edge que se crea en este tutorial filtra los datos de temperatura que genera el dispositivo. Envía mensajes ascendentes solo si la temperatura está por encima de un umbral establecido. Este tipo de análisis en la periferia ayuda a reducir la cantidad de datos enviados y almacenados en la nube.

Requisitos previos

Una máquina de desarrollo:

  • Use su propio equipo o una máquina virtual.
  • Asegúrese de que la máquina de desarrollo admite la virtualización anidada para ejecutar un motor de contenedor.
  • Puede usar la mayoría de los sistemas operativos que ejecutan un motor de contenedor para desarrollar módulos de IoT Edge para dispositivos Linux. En este tutorial se usa un equipo Windows, pero se indican las diferencias conocidas en macOS o Linux.
  • Instalación de Visual Studio Code
  • Instale la CLI de Azure.

Un dispositivo de Azure IoT Edge:

Recursos en la nube:

  • Use una instancia gratuita o de nivel estándar de Azure IoT Hub.

Si no tiene una cuenta de Azure, cree una cuenta gratuita antes de comenzar.

Sugerencia

Para obtener instrucciones sobre la depuración interactiva en Visual Studio Code o Visual Studio 2022:

En este tutorial se describen los pasos de desarrollo de Visual Studio Code.

Conceptos clave

En este tutorial se explica el desarrollo de un módulo de IoT Edge. Un módulo loT Edge es un contenedor con código ejecutable. Implemente uno o varios módulos en un dispositivo IoT Edge. Los módulos realizan tareas específicas, como la ingesta de datos de sensores, la limpieza y el análisis de datos, o el envío de mensajes a ioT Hub. Para más información, consulte Información sobre los módulos Azure IoT Edge.

Al desarrollar módulos de IoT Edge, comprenda la diferencia entre la máquina de desarrollo y el dispositivo IoT Edge de destino donde se implementa el módulo. El contenedor que compila para contener el código del módulo debe coincidir con el sistema operativo (SO) del dispositivo de destino. Por ejemplo, el escenario más común es desarrollar un módulo en un equipo Windows para tener como destino un dispositivo Linux que ejecuta IoT Edge. En ese caso, el sistema operativo contenedor es Linux. A medida que avance en este tutorial, tenga en cuenta la diferencia entre el sistema operativo de la máquina de desarrollo y el sistema operativo del contenedor.

Sugerencia

Si usa IoT Edge para Linux en Windows, el dispositivo de destino en su escenario es la máquina virtual Linux, no el host de Windows.

Este tutorial va dirigido a dispositivos de destino que ejecutan IoT Edge con contenedores de Linux. Use su sistema operativo preferido siempre que la máquina de desarrollo ejecute contenedores de Linux. Se recomienda Visual Studio Code para desarrollar con contenedores de Linux, por lo que este tutorial lo usa. También se puede usar Visual Studio, aunque hay diferencias en lo relativo a la compatibilidad entre ambas herramientas.

En la tabla siguiente se enumeran los escenarios de desarrollo admitidos para contenedores de Linux en Visual Studio Code y Visual Studio.

Código de Visual Studio Visual Studio 2019/2022
Arquitectura de dispositivos Linux Linux AMD64
Linux ARM32v7
Linux ARM64
Linux AMD64
Linux ARM32
Linux ARM64
Servicios de Azure Comprobación de
Azure Stream Analytics
Azure Machine Learning
Idiomas C
C#
Java
Node.js
Pitón
C
C#
Más información Azure IoT Edge para Visual Studio Code Azure IoT Edge Tools para Visual Studio 2019
Azure IoT Edge Tools para Visual Studio 2022

Instalación de un motor de contenedor

Los módulos IoT Edge se empaquetan como contenedores, por lo que necesita un sistema de administración de contenedores compatible con Docker en la máquina de desarrollo para compilarlos y administrarlos. Docker Desktop es una opción popular para el desarrollo porque tiene una sólida compatibilidad con características. Docker Desktop en Windows le permite cambiar entre contenedores de Linux y contenedores de Windows, por lo que puede desarrollar módulos para distintos tipos de dispositivos IoT Edge.

Use la documentación de Docker para instalar Docker en la máquina de desarrollo:

Herramientas de configuración

Instalar la herramienta de desarrollo de Azure IoT Edge basada en Python para crear la solución de IoT Edge. Tiene dos opciones:

Importante

La extensión de Herramientas de Azure IoT Edge para Visual Studio Code está en modo de mantenimiento. La herramienta de desarrollo preferida es la línea de comandos (CLI) Azure IoT Edge Dev Tool.

Use las extensiones de IoT para Visual Studio Code para desarrollar módulos IoT Edge. Estas extensiones ofrecen plantillas de proyecto, automatizan la creación del manifiesto de implementación y permiten supervisar y administrar dispositivos IoT Edge. En esta sección, se instalan Visual Studio Code y la extensión de IoT y luego se configurar una cuenta de Azure para administrar recursos de IoT Hub desde dentro de Visual Studio Code.

  1. Instalar la extensión de Azure IoT Edge.

  2. Instalar la extensión de Azure IoT Hub.

  3. Después de instalar las extensiones, abra la paleta de comandos seleccionando Ver>paleta de comandos.

  4. En la paleta de comandos, busque y seleccione Azure IoT Hub: Seleccione IoT Hub. Siga las instrucciones para seleccionar su suscripción de Azure y el centro de IoT.

  5. Abra la sección del explorador de Visual Studio Code seleccionando el icono de la barra de actividad o seleccionando Ver>explorador.

  6. En la parte inferior de dicha sección, expanda el menú Azure IoT Hub / Devices (Azure IoT Hub/Dispositivos). Verá los dispositivos y los dispositivos IoT Edge asociados al IoT Hub que seleccionó a través de la paleta de comandos.

Instalación de herramientas específicas del lenguaje

Instale las herramientas específicas del lenguaje en el que vaya a trabajar:

Creación de un Registro de contenedor

En este tutorial, puede usar las extensiones de Azure IoT Edge y Azure IoT Hub a fin de generar un módulo y crear una imagen de contenedor a partir de los archivos. Después, insertará esta imagen en un Registro donde se almacenan y administran las imágenes. Por último, implementará la imagen en el Registro para que se ejecute en el dispositivo IoT Edge.

Importante

La extensión de Visual Studio Code de Azure IoT Edge está en modo de mantenimiento.

Puede usar cualquier registro compatible con Docker para almacenar las imágenes de contenedor. Dos de los servicios de registro de Docker más conocidos son Azure Container Registry y Docker Hub. En este tutorial, utilizaremos Azure Container Registry.

Si no dispone de un registro de contenedores, siga estos pasos para crear uno nuevo en Azure:

  1. En Azure Portal, seleccione Crear un recurso>Contenedores>Container Registry.

  2. Especifique los siguientes valores obligatorios para crear el registro de contenedor:

    Campo Importancia
    Suscripción Seleccione una suscripción en la lista desplegable.
    Grupo de recursos Utilice el mismo grupo de recursos para todos los recursos de prueba que se crean en los inicios rápidos y tutoriales de IoT Edge. Por ejemplo, IoTEdgeResources.
    Nombre de registro Especifique un nombre único.
    Ubicación Elija una ubicación cercana a usted.
    Código de referencia Seleccione Básica.
  3. Seleccione Revisar y crear y, a continuación, Crear.

  4. Seleccione el nuevo registro de contenedor en la sección Recursos de la página principal de Azure Portal para abrirlo.

  5. En el panel izquierdo del registro de contenedor, seleccione Claves de acceso en el menú ubicado en Configuración.

    Captura de pantalla de la ubicación del menú Claves de acceso.

  6. Habilite Usuario administrador con el botón de alternancia para ver el Nombre de usuario y la Contraseña para el registro de contenedor.

  7. Copie los valores de Servidor de inicio de sesión, Nombre de usuario y Contraseña, y guárdelos en cualquier lugar que le resulte práctico. Dichos valores se usan en todo el tutorial para proporcionar acceso al registro de contenedor.

Creación de un nuevo proyecto de módulo

La extensión de Azure IoT Edge ofrece plantillas de proyecto para todos los lenguajes del módulo IoT Edge admitidos que haya en Visual Studio Code. Estas plantillas incluyen todos los archivos y el código que necesita para implementar un módulo de trabajo para probar IoT Edge o proporcionar un punto de partida para personalizar la plantilla con su propia lógica de negocios.

Creación de una plantilla de proyecto

La herramienta de desarrollo de IoT Edge simplifica el desarrollo de Azure IoT Edge con comandos controlados por variables de entorno. Ayuda a comenzar con el desarrollo de IoT Edge utilizando el contenedor de desarrollo IoT Edge y el esqueleto de la solución IoT Edge, que incluye un módulo predeterminado y todos los archivos de configuración necesarios.

  1. Cree un directorio para la solución en la ruta de acceso que desee. Cambie al directorio iotedgesolution.

    mkdir c:\dev\iotedgesolution
    cd c:\dev\iotedgesolution
    
  2. Use el comando iotedgedev solution init para crear una solución y configurar Azure IoT Hub en el lenguaje de desarrollo que prefiera.

    iotedgedev solution init --template csharp
    

El script de inicialización de la solución iotedgedev le pide que complete varios pasos, entre los que se incluyen:

  • Autentíquese en Azure
  • Elegir una suscripción de Azure
  • Elegir o crear un grupo de recursos
  • Elegir o crear una instancia de Azure IoT Hub
  • Elegir o crear un dispositivo de Azure IoT Edge

Utilice Visual Studio Code y la extensión de Azure IoT Edge. Empiece por crear una solución y, a continuación, genere el primer módulo de esa solución. Cada solución puede incluir varios módulos.

  1. Seleccione Ver>Paleta de comandos.
  2. En la paleta de comandos, escriba y ejecute el comando Azure IoT Edge: New IoT Edge solution (Nueva solución de IoT Edge).
  3. Vaya a la carpeta donde desea crear la nueva solución y, a continuación, seleccione Seleccionar carpeta.
  4. Escriba un nombre para la solución.
  5. Seleccione una plantilla de módulo para que su lenguaje de desarrollo preferido sea el primer módulo de la solución.
  6. Escriba un nombre para el módulo. Elija un nombre que sea único dentro del registro de contenedor.
  7. Escriba el nombre del repositorio de imágenes del módulo. Visual Studio Code rellena automáticamente el nombre del módulo como localhost:5000/<nombre del módulo>. Reemplácelo por su propia información de registro. Utilice localhost si usa un registro de Docker local para realizar pruebas. Si va a usar Azure Container Registry, utilice el servidor de inicio de sesión de la configuración del registro. El servidor de inicio de sesión se parece al <nombre del registro>.azurecr.io. Reemplace solo la sección localhost:5000 de la cadena para que el resultado final se parezca a <nombre del registro>.azurecr.io/ <nombre del módulo> .

Visual Studio Code toma la información que le ha proporcionado, crea una solución IoT Edge y la carga en una nueva ventana.

Después de crear la solución, estos archivos principales se encuentran en la solución:

  • La carpeta .vscode incluye el archivo de configuración launch.json.

  • La carpeta modules tiene subcarpetas para cada módulo. En cada subcarpeta, el archivo module.json controla cómo se compilan e implementan los módulos.

  • El archivo .env enumera las variables de entorno. La variable de entorno para el registro de contenedor es localhost:5000 de forma predeterminada.

  • Dos archivos de implementación de módulos, deployment.template.json y deployment.debug.template.json, enumere los módulos que se van a implementar en el dispositivo. De forma predeterminada, la lista incluye los módulos del sistema IoT Edge (edgeAgent y edgeHub) y módulos de ejemplo como:

    Nota

    Los módulos exactos instalados pueden depender del idioma que prefiera.

Establecimiento de la versión del entorno de ejecución de IoT Edge

La versión más reciente del módulo del sistema de IoT Edge estable es la 1.5. Establezca los módulos del sistema en la versión 1.5.

  1. En Visual Studio Code, abra el archivo de manifiesto deployment.template.json. El manifiesto de implementación es un documento JSON que describe los módulos que se van a configurar en los dispositivos IoT Edge de destino.

  2. Cambie la versión en tiempo de ejecución de las imágenes edgeAgent y edgeHub del módulo en tiempo de ejecución del sistema. Por ejemplo, si quiere usar la versión 1.5 del entorno de ejecución de IoT Edge, cambie las líneas siguientes en el archivo de manifiesto de implementación:

    "systemModules": {
        "edgeAgent": {
    
            "image": "mcr.microsoft.com/azureiotedge-agent:1.5",
    
        "edgeHub": {
    
            "image": "mcr.microsoft.com/azureiotedge-hub:1.5",
    

Especificación de la credenciales del registro para el agente de IoT Edge

El archivo del entorno almacena las credenciales del registro de contenedor y las comparte con el runtime de IoT Edge. El entorno de ejecución necesita estas credenciales para extraer las imágenes de contenedor e insertarlas en el dispositivo IoT Edge.

La extensión de IoT Edge intenta extraer de Azure las credenciales del registro del contenedor y rellenar con ellas el archivo de entorno.

Nota

Solo se crea el archivo de entorno si proporciona un repositorio de imágenes para el módulo. Si aceptó los valores predeterminados de localhost para probar y depurar localmente, no es necesario declarar las variables de entorno.

Compruebe si existen sus credenciales. Si no lo están, agréguelas ahora:

  1. Si Azure Container Registry es su registro, establezca un nombre de usuario y una contraseña de Azure Container Registry. Obtenga estos valores en el menú Configuración>Claves de acceso del registro de contenedor de Azure Portal.

  2. Abra el archivo .env en la solución del módulo.

  3. Agregue los valores de nombre de usuario y contraseña que ha copiado del registro de contenedor de Azure. Por ejemplo:

    CONTAINER_REGISTRY_SERVER="myacr.azurecr.io"
    CONTAINER_REGISTRY_USERNAME="myacr"
    CONTAINER_REGISTRY_PASSWORD="<registry_password>"
    
  4. Guarde los cambios en el archivo .env.

Nota

En este tutorial se usan credenciales de administrador para Azure Container Registry que son convenientes para escenarios de desarrollo y prueba. Cuando esté listo para escenarios de producción, se recomienda una opción de autenticación con privilegios mínimos, como las entidades de servicio o los tokens de ámbito de repositorio. Para más información, consulte Administración del acceso al registro de contenedor.

Arquitectura de destino

Seleccione la arquitectura de destino con cada solución, ya que esto afecta a cómo se compila y ejecuta el contenedor. La opción predeterminada es Linux AMD64. En este tutorial, use una máquina virtual Ubuntu como dispositivo IoT Edge y mantenga el valor predeterminado amd64.

Si necesita cambiar la arquitectura de destino de la solución, siga estos pasos.

  1. Abra la paleta de comandos y busque Azure IoT Edge: Set Default Target Platform for Edge Solution (Establecer la plataforma de destino predeterminada para la solución perimetral), o bien seleccione el icono de acceso directo en la barra lateral en la parte inferior de la ventana.

  2. En la paleta de comandos, seleccione la arquitectura de destino en la lista de opciones.

La arquitectura de destino se establece al crear la imagen de contenedor en un paso posterior.

Actualización del módulo con código personalizado

Cada plantilla incluye código de ejemplo que toma datos de sensor simulados del módulo SimulatedTemperatureSensor y los enruta a IoT Hub. El módulo de ejemplo recibe mensajes y los pasa. La funcionalidad de canalización muestra un concepto importante en IoT Edge: cómo se comunican los módulos entre sí.

Cada módulo puede tener varias colas de entrada y salida declaradas en su código. El centro de IoT Edge que se ejecuta en el dispositivo enruta los mensajes de la salida de un módulo a la entrada de uno o varios módulos. El código específico para declarar entradas y salidas varía entre idiomas, pero el concepto es el mismo para todos los módulos. Para más información acerca del enrutamiento entre módulos, consulte Declaración de rutas.

El código de C# de ejemplo que acompaña a la plantilla del proyecto usa la clase ModuleClient del SDK de IoT Hub para .NET.

  1. En el explorador de Visual Studio Code, abra módulos>filtermodule>ModuleBackgroundService.cs.

  2. En la parte superior del espacio de nombres filtermodule, agregue tres instrucciones using para los tipos que se usarán más adelante en:

    using System.Collections.Generic;     // For KeyValuePair<>
    using Microsoft.Azure.Devices.Shared; // For TwinCollection
    using Newtonsoft.Json;                // For JsonConvert
    
  3. Agregue la variable temperatureThreshold a la clase ModuleBackgroundService. Esta variable establece el valor que debe superar la temperatura medida para que los datos se envíen a IoT Hub.

    static int temperatureThreshold { get; set; } = 25;
    
  4. Agregue las clases MessageBody, Machine y Ambient. Estas clases definen el esquema esperado para el cuerpo de los mensajes entrantes.

    class MessageBody
    {
        public Machine machine {get;set;}
        public Ambient ambient {get; set;}
        public string timeCreated {get; set;}
    }
    class Machine
    {
        public double temperature {get; set;}
        public double pressure {get; set;}
    }
    class Ambient
    {
        public double temperature {get; set;}
        public int humidity {get; set;}
    }
    
  5. Busque la función ExecuteAsync. Esta función crea y configura un objeto ModuleClient, que permite al módulo conectarse al entorno de ejecución de Azure IoT Edge local para enviar y recibir mensajes. Después de crear ModuleClient, el código lee el valor temperatureThreshold en las propiedades deseadas del módulo gemelo. El código registra una devolución de llamada para recibir mensajes desde un centro de IoT Edge mediante el punto de conexión llamado input1.

    Reemplace la llamada al método ProcessMessageAsync por uno nuevo que actualice el nombre del punto de conexión y el método al que se llama cuando llega la entrada. Además, agregue un método SetDesiredPropertyUpdateCallbackAsync para las actualizaciones de las propiedades deseadas. Para realizar este cambio, reemplace la última línea del método ExecuteAsync con el siguiente código:

    // Register a callback for messages that are received by the module.
    // await _moduleClient.SetInputMessageHandlerAsync("input1", PipeMessage, cancellationToken);
    
    // Read the TemperatureThreshold value from the module twin's desired properties
    var moduleTwin = await _moduleClient.GetTwinAsync();
    await OnDesiredPropertiesUpdate(moduleTwin.Properties.Desired, _moduleClient);
    
    // Attach a callback for updates to the module twin's desired properties.
    await _moduleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertiesUpdate, null);
    
    // Register a callback for messages that are received by the module. Messages received on the inputFromSensor endpoint are sent to the FilterMessages method.
    await _moduleClient.SetInputMessageHandlerAsync("inputFromSensor", FilterMessages, _moduleClient);
    
  6. Agregue el método onDesiredPropertiesUpdate a la clase ModuleBackgroundService. Este método recibe las actualizaciones sobre las propiedades que se quieren del módulo gemelo y actualiza la variable temperatureThreshold para que coincida. Todos los módulos tienen su propio módulo gemelo, que le permite configurar el código que se ejecuta dentro de un módulo directamente desde la nube.

    static Task OnDesiredPropertiesUpdate(TwinCollection desiredProperties, object userContext)
    {
        try
        {
            Console.WriteLine("Desired property change:");
            Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
    
            if (desiredProperties["TemperatureThreshold"]!=null)
                temperatureThreshold = desiredProperties["TemperatureThreshold"];
    
        }
        catch (AggregateException ex)
        {
            foreach (Exception exception in ex.InnerExceptions)
            {
                Console.WriteLine();
                Console.WriteLine("Error when receiving desired property: {0}", exception);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error when receiving desired property: {0}", ex.Message);
        }
        return Task.CompletedTask;
    }
    
  7. Agregue el método FilterMessages. Se llama a este método cada vez que el módulo recibe un mensaje del centro de IoT Edge. Filtra los mensajes que informan de temperaturas por debajo del umbral de temperatura que se establecen mediante el módulo gemelo. También agrega la propiedad MessageType al mensaje con el valor establecido en Alerta.

    async Task<MessageResponse> FilterMessages(Message message, object userContext)
    {
        var counterValue = Interlocked.Increment(ref _counter);
        try
        {
            ModuleClient moduleClient = (ModuleClient)userContext;
            var messageBytes = message.GetBytes();
            var messageString = Encoding.UTF8.GetString(messageBytes);
            Console.WriteLine($"Received message {counterValue}: [{messageString}]");
    
            // Get the message body.
            var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
            if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
            {
                Console.WriteLine($"Machine temperature {messageBody.machine.temperature} " +
                    $"exceeds threshold {temperatureThreshold}");
                using (var filteredMessage = new Message(messageBytes))
                {
                    foreach (KeyValuePair<string, string> prop in message.Properties)
                    {
                        filteredMessage.Properties.Add(prop.Key, prop.Value);
                    }
    
                    filteredMessage.Properties.Add("MessageType", "Alert");
                    await moduleClient.SendEventAsync("output1", filteredMessage);
                }
            }
    
            // Indicate that the message treatment is completed.
            return MessageResponse.Completed;
        }
        catch (AggregateException ex)
        {
            foreach (Exception exception in ex.InnerExceptions)
            {
                Console.WriteLine();
                Console.WriteLine("Error in sample: {0}", exception);
            }
            // Indicate that the message treatment is not completed.
            var moduleClient = (ModuleClient)userContext;
            return MessageResponse.Abandoned;
        }
        catch (Exception ex)
        {
            Console.WriteLine();
            Console.WriteLine("Error in sample: {0}", ex.Message);
            // Indicate that the message treatment is not completed.
            ModuleClient moduleClient = (ModuleClient)userContext;
            return MessageResponse.Abandoned;
        }
    }
    
  8. Guarde el archivo ModuleBackgroundService.cs.

  9. En el explorador de Visual Studio Code, abra el archivo deployment.template.json en el área de trabajo de la solución de IoT Edge.

  10. Puesto que hemos cambiado el nombre del punto de conexión en el que el módulo escucha, también es necesario actualizar las rutas en el manifiesto de implementación para que edgeHub envíe mensajes al nuevo punto de conexión.

    Busque la sección routes en el módulo gemelo $edgeHub. Actualice la ruta sensorTofiltermodule para reemplazar input1 por inputFromSensor:

    "sensorTofiltermodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/filtermodule/inputs/inputFromSensor\")"
    
  11. Agregue el módulo gemelo de filtermodule al manifiesto de implementación. Inserte el siguiente contenido JSON en la parte inferior de la sección modulesContent, después del módulo gemelo $edgeHub:

       "filtermodule": {
           "properties.desired":{
               "TemperatureThreshold":25
           }
       }
    
  12. Guarde el archivo deployment.template.json.

Compilación e inserción de la solución

Actualizó el código del módulo y la plantilla de implementación para ayudar a conocer algunos conceptos clave de la implementación. Ya está listo para que compilar la imagen de contenedor del módulo e insertarla en el registro de contenedor.

En Visual Studio Code, abra el archivo de manifiesto de implementación deployment.template.json. El manifiesto de implementación describe los módulos que se van a configurar en los dispositivos IoT Edge de destino. Antes de la implementación, debe actualizar las credenciales de Azure Container Registry y las imágenes del módulo con los valores de createOptions adecuados. Para más información sobre los valores de createOption, consulte Configuración de las opciones de creación de contenedores para módulos de IoT Edge.

Si usa un Azure Container Registry para almacenar la imagen del módulo, agregue sus credenciales a la sección modulesContent>edgeAgent>configuración>registryCredentials en deployment.template.json. Reemplace myacr por su propio nombre del registro y proporcione la contraseña y la dirección del servidor de inicio de sesión. Por ejemplo:

"registryCredentials": {
    "myacr": {
        "username": "myacr",
        "password": "<your_acr_password>",
        "address": "myacr.azurecr.io"
    }
}

Agregue o reemplace el siguiente contenido con cadenas para el valor createOptions en cada sistema (edgeHub y edgeAgent) y módulo personalizado (filtermodule y tempSensor) que aparece enumerado. Cambie los valores si es necesario.

"createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"

Por ejemplo, la configuración filtermodule debería ser similar a:

"filtermodule": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
   "image": "myacr.azurecr.io/filtermodule:0.0.1-amd64",
   "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
}

Imagen de Docker del módulo de compilación

Abra el terminal integrado de Visual Studio Code seleccionando Terminal>Nuevo terminal.

Use el comando dotnet publish para compilar la imagen de contenedor para la arquitectura Linux y amd64. Cambie el directorio al directorio filtermodule del proyecto y ejecute el comando dotnet publish.

dotnet publish --os linux --arch x64 /t:PublishContainer

Actualmente, la plantilla de herramientas iotedgedev tiene como destino .NET 7.0. Si desea tener como destino una versión diferente de .NET, edite el archivo filtermodule.csproj y cambie los valores de TargetFramework y PackageReference. Por ejemplo, para tener como destino .NET 8.0, el archivo filtermodule.csproj debería tener este aspecto:

<Project Sdk="Microsoft.NET.Sdk.Worker">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.42.0" />
        <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
    </ItemGroup>
</Project>

Etiquete la imagen de Docker con la arquitectura, la versión y la información del registro de contenedor. Reemplace myacr por su propio nombre de registro.

docker tag filtermodule myacr.azurecr.io/filtermodule:0.0.1-amd64

Imagen de Docker del módulo de inserción

Especifique las credenciales del registro de contenedor a Docker para que pueda insertar la imagen de contenedor para que se almacene en el registro.

  1. Inicie sesión en Docker con las credenciales de Azure Container Registry (ACR).

    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    Podría recibir una advertencia de seguridad en la que se recomiende el uso de --password-stdin. Aunque ese es un procedimiento recomendado para escenarios de producción, está fuera del ámbito de este tutorial. Para más información, consulte la referencia de docker login.

  2. Inicie sesión en Azure Container Registry. Es necesario Instalar la CLI de Azure para usar el comando az. Este comando solicita el nombre de usuario y la contraseña que se encuentran en el registro de contenedor en Configuración>Claves de acceso.

    az acr login -n <ACR registry name>
    

    Sugerencia

    Si cierra la sesión en cualquier momento de este tutorial, repita los pasos de inicio de sesión de Docker y Azure Container Registry para continuar.

  3. Inserte la imagen del módulo en el registro local o en un registro de contenedor.

    docker push <ImageName>
    

    Por ejemplo:

    # Push the Docker image to the local registry
    
    docker push localhost:5000/filtermodule:0.0.1-amd64
    
    # Or push the Docker image to an Azure Container Registry. Replace myacr with your Azure Container Registry name.
    
    az acr login --name myacr
    docker push myacr.azurecr.io/filtermodule:0.0.1-amd64
    

Actualizar la plantilla de implementación

Actualice la plantilla de implementación deployment.template.json con la ubicación de la imagen del registro de contenedor. Por ejemplo, si usa myacr.azurecr.io de Azure Container Registry y la imagen es filtermodule:0.0.1-amd64, actualice la configuración de filtermodule a:

"filtermodule": {
    "version": "1.0",
    "type": "docker",
    "status": "running",
    "restartPolicy": "always",
    "settings": {
        "image": "myacr.azurecr.io/filtermodule:0.0.1-amd64",
        "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
    }
}

En el explorador de Visual Studio Code, haga clic con el botón derecho en el archivo deployment.template.json y seleccione Build and Push IoT Edge solution (Compilar e insertar solución IoT Edge).

El comando de compilación e inserción inicia tres operaciones. En primer lugar, se crea una nueva carpeta en la solución denominada config que contiene los archivos del manifiesto de la implementación completa, con la información de la plantilla de implementación y otros archivos de la solución. En segundo lugar, ejecuta docker build para generar la imagen de contenedor basándose en el Dockerfile adecuado para la arquitectura de destino. A continuación, ejecuta docker push para insertar el repositorio de imágenes en el registro de contenedor.

Este proceso puede tardar varios minutos la primera vez, pero es más rápido la próxima vez que ejecute los comandos.

Opcional: actualizar el módulo y la imagen

Si realiza cambios en el código del módulo, debe volver a generar e insertar la imagen del módulo en el registro de contenedor. Siga los pasos de esta sección para actualizar la compilación y la imagen de contenedor. Puede omitir esta sección si no ha realizado ningún cambio en el código del módulo.

Abra el archivo deployment.amd64.json en la carpeta de configuración recién creada. El nombre de archivo refleja la arquitectura de destino, así que es diferente si ha elegido una otra arquitectura.

Tenga en cuenta que los dos parámetros que tenían marcadores de posición ahora contienen los valores adecuados. La sección registryCredentials tiene el nombre de usuario y la contraseña del registro que se extrajeron del archivo .env. filtermodule tiene el repositorio de imágenes completo con el nombre, la versión y la etiqueta de arquitectura del archivo module.json.

  1. Abra el archivo module.json de la carpeta filtermodule.

  2. Cambie el número de versión de la imagen del módulo. Por ejemplo, incremente el número de versión de la revisión a "version": "0.0.2" como si hubiera hecho una pequeña corrección en el código del módulo.

    Sugerencia

    Las versiones de los módulos permiten el control de versiones y le permiten probar los cambios en un pequeño conjunto de dispositivos antes de implementar actualizaciones en la producción. Si no incrementa la versión del módulo antes de la compilación e inserción, entonces sobrescribirá el repositorio en el registro de contenedor.

  3. Guarde los cambios en el archivo module.json.

Compile e inserte la imagen actualizada con una etiqueta de versión 0.0.2. Por ejemplo, para compilar e insertar la imagen del registro local o un registro de contenedor de Azure, use los siguientes comandos:


# Build the container image for Linux and amd64 architecture.

dotnet publish --os linux --arch x64

# For local registry:
# Tag the image with version 0.0.2, x64 architecture, and the local registry.

docker tag filtermodule localhost:5000/filtermodule:0.0.2-amd64

# For Azure Container Registry:
# Tag the image with version 0.0.2, x64 architecture, and your container registry information. Replace **myacr** with your own registry name.

docker tag filtermodule myacr.azurecr.io/filtermodule:0.0.2-amd64

Vuelva a hacer clic con el botón derecho en el archivo deployment.template.json y seleccione Build and Push IoT Edge solution (Compilar e insertar solución IoT Edge) de nuevo.

Vuelva a abrir el archivo deployment.amd64.json de nuevo. Observe que el sistema de compilación no crea un nuevo archivo al ejecutar de nuevo el comando de compilación e inserción. Más bien, el mismo archivo se actualiza para reflejar los cambios. La imagen de filtermodule ahora apunta a la versión 0.0.2 del contenedor.

Para comprobar mejor lo que hizo el comando de compilación e inserción, vaya a Azure Portal y navegue al registro de contenedor.

En el registro de contenedor, seleccione Repositorios y después filtermodule. Compruebe que ambas versiones de la imagen se insertan en el registro.

Captura de pantalla de dónde ver ambas versiones de imagen en el registro de contenedor.

Solución de problemas

Si encuentra errores al compilar e insertar la imagen del módulo, a menudo tiene que ver con la configuración de Docker en la máquina de desarrollo. Utilice las siguientes comprobaciones para revisar la configuración:

  • ¿Ha ejecutado el comando docker login mediante las credenciales que copió del registro de contenedor? Estas credenciales son diferentes a las que se utilizan para iniciar sesión en Azure.
  • ¿Es el repositorio de contenedor correcto? ¿Tiene el nombre correcto del registro de contenedor y el nombre correcto del módulo? Abra el archivo module.json de la carpeta filtermodule para comprobar. El valor del repositorio debería ser similar a <nombre del registro>.azurecr.io/filtermodule.
  • Si utilizó un nombre diferente a filtermodule para el módulo, ¿es coherente ese nombre en toda la solución?
  • ¿La máquina funciona con el mismo tipo de contenedores que está creando? Este tutorial es para dispositivos IoT Edge de Linux, por lo que Visual Studio Code debería indicar amd64 o arm32v7 en la barra lateral y Docker Desktop debe ejecutar contenedores Linux.

Implementación de módulos en el dispositivo

Ha verificado que hay imágenes de contenedor creadas y almacenadas en el registro de contenedor, por lo que es el momento de implementarlas en un dispositivo. Asegúrese de que el dispositivo IoT Edge está en funcionamiento.

Use el comando IoT Edge Azure CLI set-modules para implementar los módulos en Azure IoT Hub. Por ejemplo, para implementar los módulos definidos en el archivo deployment.template.json en el centro de IoT my-iot-hub para el dispositivo de IoT Edge my-device, use el siguiente comando. Sustituya los valores de cadena de conexión de loT Hub hub-name, device-id y login por los suyos propios.

az iot edge set-modules --hub-name my-iot-hub --device-id my-device --content ./deployment.template.json --login "HostName=my-iot-hub.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=<SharedAccessKey>"

Sugerencia

Busque la cadena de conexión de IoT Hub, incluida la clave de acceso compartido, en Azure Portal. Vaya a IoT Hub >Configuración de seguridad>Directivas de acceso compartido>iothubowner.

  1. En el explorador de Visual Studio Code, en la sección Azure IoT Hub, expanda Dispositivos para ver la lista de dispositivos IoT.

  2. Haga clic con el dispositivo IoT Edge que desea implementar y seleccione Create Deployment for IoT Edge device (Crear una implementación para un dispositivo individual).

  3. En el Explorador de archivos, vaya a la carpeta config y seleccione el archivo deployment.amd64.json.

    No utilice el archivo deployment.template.json, que no contiene todas las credenciales del registro de contenedor o los valores de imagen del módulo. Si tiene como destino un dispositivo LINUX ARM32, el nombre del manifiesto de implementación es deployment.arm32v7.json.

  4. En el dispositivo, expanda Módulos para ver una lista de módulos implementados y en ejecución. Seleccione el botón actualizar. Debería ver los nuevos módulos tempSensor y filtermodule que se ejecutan en el dispositivo.

    Los módulos pueden tardar unos minutos en iniciarse. El entorno de ejecución de IoT Edge recibe su nuevo manifiesto de implementación, extrae las imágenes del módulo del entorno de ejecución del contenedor y, a continuación, inicia cada módulo nuevo.

Visualización de los mensajes desde el dispositivo

El código del módulo de ejemplo obtiene mensajes a través de su cola de entrada y los envía a través de su cola de salida. El manifiesto de implementación configura rutas que envían mensajes a filtermodule desde tempSensor, y luego reenvía mensajes desde filtermodule al IoT Hub. Las extensiones de Azure IoT Edge y Azure IoT Hub le permiten ver los mensajes a medida que llegan a IoT Hub desde el dispositivo.

  1. En el explorador de Visual Studio Code, seleccione el dispositivo IoT Edge que quiere supervisar y, a continuación, seleccione Iniciar supervisión del punto de conexión de eventos integrado.

  2. Vea la ventana de salida en Visual Studio Code para ver los mensajes que llegan a IoT Hub.

    Captura de pantalla de la ventana de salida de Visual Studio Code en la que se muestran los mensajes entrantes del dispositivo a la nube.

Visualización de los cambios en el dispositivo

Para ver lo que sucede en el dispositivo, use los comandos de esta sección para inspeccionar el entorno de ejecución y los módulos de IoT Edge que se ejecutan en el dispositivo.

Estos comandos son para el dispositivo IoT Edge, no para la máquina de desarrollo. Si usa una máquina virtual para el dispositivo IoT Edge, conéctese a ella ahora. En Azure, vaya a la página de información general de la máquina virtual y seleccione Conectar para acceder a la conexión de Secure Shell.

  • Vea todos los módulos implementados en el dispositivo y compruebe su estado:

    iotedge list
    

    Verá cuatro módulos: los dos módulos de tiempo de ejecución de IoT Edge, tempSensor y filtermodule. Los cuatro deben aparecer enumerados como en funcionamiento.

  • Inspeccione los registros para un módulo específico:

    iotedge logs <module name>
    

    Los nombres de módulo distinguen entre mayúsculas y minúsculas.

    Los registros tempSensor y filtermodule muestran los mensajes que están procesando. El módulo edgeAgent inicia los demás módulos, por lo que sus registros tienen información sobre el manifiesto de implementación. Si un módulo no aparece o no se está ejecutando, compruebe si hay errores en los registros de edgeAgent. El módulo edgeHub administra la comunicación entre los módulos y IoT Hub. Si los módulos se están ejecutando, pero los mensajes no llegan a IoT Hub, compruebe si hay errores en los registros de EdgeHub.

Limpieza de recursos

Si desea continuar con el siguiente artículo recomendado, mantenga los recursos y las configuraciones que creó y reutilícelas. También puede seguir usando el mismo dispositivo de IoT Edge como dispositivo de prueba.

De lo contrario, elimine las configuraciones locales y los recursos de Azure que usó en este artículo para evitar cargos.

Eliminación de recursos de Azure

La eliminación de los recursos de Azure y de los grupos de recursos es un proceso irreversible. Asegúrese de no eliminar por accidente el grupo de recursos o los recursos equivocados. Si creó ioT Hub dentro de un grupo de recursos existente que tiene recursos que desea conservar, elimine solo el propio recurso de IoT Hub, no el grupo de recursos.

Para eliminar los recursos:

  1. Inicie sesión en Azure Portal y después seleccione Grupos de recursos.

  2. Seleccione el nombre del grupo de recursos que contiene los recursos de prueba de IoT Edge.

  3. Revise la lista de recursos que contiene el grupo de recursos. Si desea eliminar todos ellos, puede seleccionar Eliminar grupo de recursos. Si desea eliminar solo algunos de ellos, puede seleccionar cada recurso para eliminarlos individualmente.

Pasos siguientes

En este tutorial, configurará Visual Studio Code en la máquina de desarrollo e implementará el primer módulo de IoT Edge con código que filtra los datos sin procesar generados por el dispositivo IoT Edge.

Continúe con los siguientes tutoriales para obtener información sobre cómo Azure IoT Edge le permite implementar servicios en la nube de Azure para procesar y analizar datos en el perímetro.