Compartir a través de


Tutorial: Almacenamiento de datos en el perímetro con bases de datos de SQL Server

Se aplica a:IoT Edge 1.4 marca de verificación IoT Edge 1.4

Importante

Las versiones de IoT Edge 1.5 LTS e IoT Edge 1.4 son compatibles. Si está en una versión anterior, consulte Actualización de IoT Edge.

Implemente un módulo de SQL Server para almacenar datos en un dispositivo que ejecuta Azure IoT Edge con contenedores de Linux.

Use Azure IoT Edge y SQL Server para almacenar y consultar datos en el perímetro. Azure IoT Edge tiene funcionalidades básicas de almacenamiento para almacenar en caché los mensajes si un dispositivo se queda sin conexión y, a continuación, reenvíalos cuando se restablece la conexión. Sin embargo, es posible que quiera funcionalidades de almacenamiento más avanzadas, como poder consultar datos localmente. Los dispositivos IoT Edge pueden usar bases de datos locales para realizar una informática más compleja sin tener que mantener una conexión a IoT Hub.

En este artículo se proporcionan instrucciones para implementar una base de datos de SQL Server en un dispositivo IoT Edge. Azure Functions, que se ejecuta en el dispositivo IoT Edge, estructura los datos entrantes y los envía a la base de datos. Los pasos de este artículo también se pueden aplicar a otras bases de datos que funcionan en contenedores, como MySQL o PostgreSQL.

En este tutorial, aprenderá a:

  • Uso de Visual Studio Code para crear una función de Azure
  • Implementación de una base de datos SQL en el dispositivo IoT Edge
  • Uso de Visual Studio Code para compilar módulos e implementarlos en el dispositivo IoT Edge
  • Visualización de datos generados

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

Prerrequisitos

Antes de comenzar este tutorial, debería haber pasado por el tutorial anterior para configurar el entorno de desarrollo para el desarrollo de contenedores de Linux: Desarrollo de módulos de Azure IoT Edge mediante Visual Studio Code. Al completar ese tutorial, debe cumplir los siguientes requisitos previos:

En este tutorial se usa un módulo de Azure Functions para enviar datos a SQL Server. Para desarrollar un módulo de IoT Edge con Azure Functions, instale los siguientes requisitos previos adicionales en la máquina de desarrollo:

Creación de un proyecto de función

Para enviar datos a una base de datos, necesita un módulo que pueda estructurar los datos correctamente y, a continuación, almacenarlos en una tabla.

Creación de un nuevo proyecto

En los pasos siguientes se muestra cómo crear una función de IoT Edge mediante Visual Studio Code y la extensión de Azure IoT Edge.

  1. Abre Visual Studio Code.

  2. Para abrir la paleta de comandos de Visual Studio Code, seleccione Ver>paleta de comandos.

  3. En la paleta de comandos, escriba y ejecute el comando Azure IoT Edge: Nueva solución de IoT Edge. En la paleta de comandos, proporcione la siguiente información para crear la solución:

    Campo Importancia
    Seleccionar carpeta Elija la ubicación en la máquina de desarrollo de Visual Studio Code para crear los archivos de solución.
    Proporcionar un nombre de solución Escriba un nombre descriptivo para la solución, como SqlSolution, o acepte el valor predeterminado.
    Selección de la plantilla de módulo Elija Azure Functions - C#.
    Proporcione un nombre de módulo. Asigne al módulo el nombre sqlFunction.
    Proporcionar el repositorio de imágenes de Docker para el módulo Un repositorio de imágenes incluye el nombre del registro de contenedor y el nombre de la imagen de contenedor. La imagen de contenedor se rellena previamente desde el último paso. Reemplace localhost:5000 por el valor del servidor de inicio de sesión de Su registro de contenedor de Azure. Puede recuperar el servidor de inicio de sesión en la página Información general del registro de contenedor en Azure Portal.

    La cadena final es similar al <nombre> del registro.azurecr.io/sqlfunction.

    La ventana de Visual Studio Code carga el área de trabajo de la solución de IoT Edge.

Adición de las credenciales del Registro

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

La extensión de IoT Edge intenta extraer las credenciales del registro de contenedor de Azure y las rellena en el archivo de entorno. Compruebe si las credenciales ya están incluidas. Si no es así, agréguelos ahora:

  1. En el explorador de Visual Studio Code, abra el archivo .env.
  2. Actualice los campos con los valores de nombre de usuario y contraseña que copió de su registro de contenedor de Azure.
  3. Guarde este archivo.

Nota:

En este tutorial se usan credenciales de inicio de sesión 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. Para más información, consulte Administración del acceso al registro de contenedor.

Selección de la arquitectura de destino

Debe seleccionar qué arquitectura tiene como destino cada solución, ya que el contenedor se compila y se ejecuta de forma diferente para cada tipo de arquitectura. El valor predeterminado es Linux AMD64.

  1. Abra la paleta de comandos y busque Azure IoT Edge: Establecer la plataforma de destino predeterminada para la solución perimetral o seleccione el icono de acceso directo en la barra lateral de la parte inferior de la ventana.

  2. En la paleta de comandos, seleccione la arquitectura de destino en la lista de opciones. En este tutorial, se usa una máquina virtual Ubuntu como dispositivo IoT Edge, por lo que se mantendrá el valor predeterminado amd64.

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

  1. En el explorador de Visual Studio Code, abra módulos>sqlFunction>sqlFunction.csproj.

  2. Busque el grupo de referencias de paquete y agregue uno nuevo para incluir SqlClient.

    <PackageReference Include="System.Data.SqlClient" Version="4.5.1"/>
    
  3. Guarde el archivo sqlFunction.csproj .

  4. Abra el archivo sqlFunction.cs .

  5. Reemplace todo el contenido del archivo por el código siguiente:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EdgeHub;
    using Microsoft.Azure.WebJobs.Host;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using Sql = System.Data.SqlClient;
    
    namespace Functions.Samples
    {
        public static class sqlFunction
        {
            [FunctionName("sqlFunction")]
            public static async Task FilterMessageAndSendMessage(
                [EdgeHubTrigger("input1")] Message messageReceived,
                [EdgeHub(OutputName = "output1")] IAsyncCollector<Message> output,
                ILogger logger)
            {
                const int temperatureThreshold = 20;
                byte[] messageBytes = messageReceived.GetBytes();
                var messageString = System.Text.Encoding.UTF8.GetString(messageBytes);
    
                if (!string.IsNullOrEmpty(messageString))
                {
                    logger.LogInformation("Info: Received one non-empty message");
                    // Get the body of the message and deserialize it.
                    var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
                    //Store the data in SQL db
                    const string str = "<sql connection string>";
                    using (Sql.SqlConnection conn = new Sql.SqlConnection(str))
                    {
                        conn.Open();
                        var insertMachineTemperature = "INSERT INTO MeasurementsDB.dbo.TemperatureMeasurements VALUES (CONVERT(DATETIME2,'" + messageBody.timeCreated + "', 127), 'machine', " + messageBody.machine.temperature + ");";
                        var insertAmbientTemperature = "INSERT INTO MeasurementsDB.dbo.TemperatureMeasurements VALUES (CONVERT(DATETIME2,'" + messageBody.timeCreated + "', 127), 'ambient', " + messageBody.ambient.temperature + ");";
                        using (Sql.SqlCommand cmd = new Sql.SqlCommand(insertMachineTemperature + "\n" + insertAmbientTemperature, conn))
                        {
                            //Execute the command and log the # rows affected.
                            var rows = await cmd.ExecuteNonQueryAsync();
                            logger.LogInformation($"{rows} rows were updated");
                        }
                    }
    
                    if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
                    {
                        // Send the message to the output as the temperature value is greater than the threshold.
                        using (var filteredMessage = new Message(messageBytes))
                        {
                             // Copy the properties of the original message into the new Message object.
                             foreach (KeyValuePair<string, string> prop in messageReceived.Properties)
                             {filteredMessage.Properties.Add(prop.Key, prop.Value);}
                             // Add a new property to the message to indicate it is an alert.
                             filteredMessage.Properties.Add("MessageType", "Alert");
                             // Send the message.
                             await output.AddAsync(filteredMessage);
                             logger.LogInformation("Info: Received and transferred a message with temperature above the threshold");
                        }
                    }
                }
            }
        }
        //Define the expected schema for the body of incoming messages.
        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;}
        }
    }
    
  6. En la línea 35, reemplace la cadena< de conexión sql por> la cadena siguiente. La propiedad Origen de datos hace referencia al contenedor de SQL Server, que aún no existe. La creará con el nombre SQL en la sección siguiente. Elija una contraseña segura para la palabra clave Password .

    Data Source=tcp:sql,1433;Initial Catalog=MeasurementsDB;User Id=SA;Password=<YOUR-STRONG-PASSWORD>;TrustServerCertificate=False;Connection Timeout=30;
    
  7. Guarde el archivo sqlFunction.cs .

Adición del contenedor de SQL Server

Un manifiesto de implementación declara qué módulos se instalará el entorno de ejecución de IoT Edge en el dispositivo IoT Edge. Proporcionó el código para que un módulo de función personalizado en la sección anterior, pero el módulo de SQL Server ya está compilado y disponible en el Registro de artefactos de Microsoft. Solo tiene que indicar al entorno de ejecución de IoT Edge que lo incluya y, a continuación, configúrelo en el dispositivo.

  1. En Visual Studio Code, abra la paleta de comandos seleccionando Ver>paleta de comandos.

  2. En la paleta de comandos, escriba y ejecute el comando Azure IoT Edge: Agregar módulo ioT Edge. En la paleta de comandos, proporcione la siguiente información para agregar un nuevo módulo:

    Campo Importancia
    Selección del archivo de plantilla de implementación La paleta de comandos resalta el archivo deployment.template.json en la carpeta de solución actual. Seleccione ese archivo.
    Selección de la plantilla de módulo Seleccione Módulo existente (Escriba la dirección URL de imagen completa).
    Proporcionar un nombre de módulo Escriba sql. Este nombre coincide con el nombre del contenedor declarado en la cadena de conexión del archivo sqlFunction.cs.
    Proporcionar la imagen de Docker para el módulo Escriba el siguiente URI para extraer la imagen de contenedor de SQL Server del Registro de artefactos de Microsoft. En el caso de las imágenes basadas en Ubuntu, use mcr.microsoft.com/mssql/server:latest. Para imágenes basadas en Red Hat Enterprise Linux (RHEL), use mcr.microsoft.com/mssql/rhel/server:latest.

    La imagen de contenedor de Azure SQL Edge es una versión ligera y en contenedores de SQL Server que se puede ejecutar en dispositivos IoT Edge. Está optimizado para escenarios perimetrales y se puede ejecutar en dispositivos ARM y AMD64.

  3. En la carpeta de la solución, abra el archivo deployment.template.json .

  4. Busque la sección módulos . Debería ver tres módulos. El módulo SimulatedTemperatureSensor se incluye de forma predeterminada en las nuevas soluciones y proporciona datos de prueba para usarlos con los demás módulos. El módulo sqlFunction es el módulo que creó inicialmente y actualizó con código nuevo. Por último, el módulo sql se importó desde el Registro de artefactos de Microsoft.

    Sugerencia

    El módulo de SQL Server incluye una contraseña predeterminada establecida en las variables de entorno del manifiesto de implementación. Cada vez que cree un contenedor de SQL Server en un entorno de producción, debe cambiar la contraseña de administrador del sistema predeterminada.

  5. Cierre el archivo deployment.template.json .

Compilación de la solución de IoT Edge

En las secciones anteriores, creó una solución con un módulo y, a continuación, agregó otra a la plantilla de manifiesto de implementación. Microsoft hospeda públicamente el módulo de SQL Server, pero debe incluir en contenedores el código en el módulo Functions. En esta sección, creará la solución, creará imágenes de contenedor para el módulo sqlFunction e insertará la imagen en el registro de contenedor.

  1. En Visual Studio Code, abra el terminal integrado seleccionando Ver>terminal.

  2. Inicie sesión en el registro de contenedor en Visual Studio Code para poder insertar las imágenes en el registro. Use las mismas credenciales de Azure Container Registry (ACR) que agregó al archivo .env. Escriba el siguiente comando en el terminal integrado:

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

    Es posible que vea una advertencia de seguridad que recomienda el uso del parámetro --password-stdin. Aunque su uso está fuera del ámbito de este artículo, se recomienda seguir este procedimiento recomendado. Para más información, consulte la referencia del comando docker login .

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

    El comando build and push inicia tres operaciones. En primer lugar, crea una nueva carpeta en la solución denominada config que contiene el manifiesto de implementación completo, que se basa en la información de la plantilla de implementación y otros archivos de solución. En segundo lugar, se ejecuta docker build para compilar la imagen de contenedor en función del dockerfile adecuado para la arquitectura de destino. A continuación, se 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.

    Puede comprobar que el módulo sqlFunction se insertó correctamente en el registro de contenedor. En Azure Portal, vaya al registro de contenedor. Seleccione repositorios y busque sqlFunction. Los otros dos módulos, SimulatedTemperatureSensor y sql, no se insertarán en el registro de contenedor porque sus repositorios ya están en los registros de Microsoft.

Implementación de la solución en un dispositivo

Puede establecer módulos en un dispositivo a través de IoT Hub, pero también puede acceder a IoT Hub y dispositivos a través de Visual Studio Code. En esta sección, configurará el acceso a IoT Hub y, después, usará Visual Studio Code para implementar la solución en el dispositivo IoT Edge.

  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 botón derecho en el dispositivo al que desea dirigirse con la implementación y seleccione Crear implementación para un único dispositivo.

  3. Seleccione el archivodeployment.amd64.json en la carpeta config y, a continuación, haga clic en Seleccionar manifiesto de implementación perimetral. No use el archivo deployment.template.json.

  4. En el dispositivo, expanda Módulos para ver una lista de módulos implementados y en ejecución. Haga clic en el botón Actualizar. Debería ver los nuevos módulos sql y sqlFunction que se ejecutan junto con el módulo SimulatedTemperatureSensor y los $edgeAgent y $edgeHub.

    También puede comprobar que todos los módulos están en funcionamiento en el dispositivo. En el dispositivo IoT Edge, ejecute el comando siguiente para ver el estado de los módulos.

    iotedge list
    

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

Creación de la base de datos SQL

Al aplicar el manifiesto de implementación al dispositivo, obtendrá tres módulos en ejecución. El módulo SimulatedTemperatureSensor genera datos de entorno simulados. El módulo sqlFunction toma los datos y los da formato a una base de datos. Esta sección le guía a través de la configuración de la base de datos SQL para almacenar los datos de temperatura.

Ejecute los siguientes comandos en el dispositivo IoT Edge. Estos comandos se conectan al módulo sql que se ejecuta en el dispositivo y crean una base de datos y una tabla para contener los datos de temperatura que se envían a él. Reemplace <YOUR-STRONG-PASSWORD> por la contraseña segura que eligió en la cadena de conexión.

  1. En una herramienta de línea de comandos del dispositivo IoT Edge, conéctese a la base de datos.

    sudo docker exec -it sql bash
    
  2. Abra la herramienta de comandos SQL.

    /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P '<YOUR-STRONG-PASSWORD>'
    
  3. Cree la base de datos:

    CREATE DATABASE MeasurementsDB
    ON
    (NAME = MeasurementsDB, FILENAME = '/var/opt/mssql/measurementsdb.mdf')
    GO
    
  4. Defina la tabla.

    CREATE TABLE MeasurementsDB.dbo.TemperatureMeasurements (measurementTime DATETIME2, location NVARCHAR(50), temperature FLOAT)
    GO
    

Puede personalizar el archivo docker de SQL Server para configurar automáticamente sql Server para que se implemente en varios dispositivos IoT Edge. Para obtener más información, consulte el proyecto de demostración de contenedor de Microsoft SQL Server.

Visualización de los datos locales

Una vez creada la tabla, el módulo sqlFunction comienza a almacenar datos en una base de datos local de SQL Server 2017 en el dispositivo IoT Edge.

Desde dentro de la herramienta de comandos SQL, ejecute el siguiente comando para ver los datos de tabla con formato:

SELECT * FROM MeasurementsDB.dbo.TemperatureMeasurements
GO

Visualización del contenido de la base de datos local

Limpieza de recursos

Si tiene previsto continuar con el siguiente artículo recomendado, puede mantener los recursos y las configuraciones que creó y reutilizarlos. También puede seguir usando el mismo dispositivo IoT Edge que un dispositivo de prueba.

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

Eliminación de recursos de Azure

La eliminación de recursos y grupos de recursos de Azure es irreversible. Asegúrese de no eliminar por accidente el grupo de recursos o los recursos equivocados. Si creó el centro de IoT 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 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 incluidos en el grupo de recursos. Si desea eliminar todos ellos, puede seleccionar Eliminar grupo de recursos. Si solo desea eliminar algunos de ellos, puede hacer clic en cada recurso para eliminarlos individualmente.

En este tutorial, ha creado un módulo de Azure Functions que contiene código para filtrar los datos sin procesar generados por el dispositivo IoT Edge. Cuando esté listo para compilar sus propios módulos, puede obtener más información sobre cómo desarrollar módulos de Azure IoT Edge mediante Visual Studio Code.

Pasos siguientes

Si quiere probar otro método de almacenamiento en el perímetro, lea cómo usar Azure Blob Storage en IoT Edge.