Condividi tramite


Esercitazione: Sviluppare moduli IoT Edge usando Visual Studio Code

Applica a:IoT Edge 1.5 segno di spunta IoT Edge 1.5

Importante

IoT Edge 1.5 LTS è la versione supportata. IoT Edge 1,4 LTS ha raggiunto la fine della vita il 12 novembre 2024. Se si usa una versione precedente, vedere Update IoT Edge.

Questa esercitazione illustra come sviluppare e distribuire il codice in un dispositivo IoT Edge. Azure IoT Edge moduli consentono di distribuire codice che esegue la logica di business direttamente nel dispositivo IoT Edge. Nella guida introduttiva Distribuisci il codice su un dispositivo Linux, hai configurato un dispositivo IoT Edge e distribuito un modulo dall'Azure Marketplace.

Questo articolo descrive i passaggi per due strumenti di sviluppo IoT Edge:

  • Azure IoT Edge Dev Tool interfaccia a riga di comando (CLI), che è preferibile per lo sviluppo.
  • Estensione Azure IoT Edge per Visual Studio Code, disponibile in modalità di manutenzione.

Usare il pulsante del selettore dello strumento all'inizio di questo articolo per scegliere lo strumento.

In questa esercitazione verranno illustrate le procedure per:

  • Configurare il computer di sviluppo
  • Usare gli strumenti di IoT Edge per creare un nuovo progetto
  • Compilare il progetto come contenitore Docker e archiviarlo in un registro contenitori Azure
  • Distribuire il codice in un dispositivo IoT Edge

Il modulo IoT Edge creato in questa esercitazione filtra i dati relativi alla temperatura generati dal dispositivo. Invia messaggi a monte solo se la temperatura supera una soglia impostata. Questo tipo di analisi sul perimetro consente di ridurre la quantità di dati inviati e archiviati nel cloud.

Prerequisiti

Un computer di sviluppo:

  • Usare il proprio computer o una macchina virtuale.
  • Assicurarsi che il computer di sviluppo supporti la virtualizzazione annidata per eseguire un motore di contenitori.
  • È possibile usare la maggior parte dei sistemi operativi che eseguono un motore di contenitori per sviluppare moduli IoT Edge per dispositivi Linux. Questa esercitazione usa un computer Windows, ma indica anche le differenze note in macOS o Linux.
  • Installare Visual Studio Code
  • Installare il Azure CLI.

Un dispositivo Azure IoT Edge:

Risorse cloud:

Se non si ha un account Azure, creare un account free prima di iniziare.

Suggerimento

Per indicazioni sul debug interattivo in Visual Studio Code o Visual Studio 2022:

Questa esercitazione illustra i passaggi di sviluppo per Visual Studio Code.

Concetti chiave

Questa esercitazione illustra lo sviluppo di un modulo IoT Edge. Un modulo IoT Edge è un contenitore con codice eseguibile. È possibile distribuire uno o più moduli in un dispositivo IoT Edge. I moduli eseguono attività specifiche, ad esempio l'inserimento di dati da sensori, la pulizia e l'analisi dei dati o l'invio di messaggi a un IoT Hub. Per ulteriori informazioni, vedere Comprendere i moduli di Azure IoT Edge.

Quando si sviluppano moduli IoT Edge, è necessario comprendere la differenza tra il computer di sviluppo e il dispositivo di destinazione IoT Edge in cui viene distribuito il modulo. Il contenitore compilato per contenere il codice del modulo deve corrispondere al sistema operativo del dispositivo di destinazione. Ad esempio, lo scenario più comune è lo sviluppo di un modulo in un computer Windows per impostare come destinazione un dispositivo Linux che esegue IoT Edge. In tal caso, il sistema operativo del contenitore è Linux. Mentre si procede con questa esercitazione, tenere presente la differenza tra sistema operativo del computer di sviluppo e sistema operativo del contenitore.

Suggerimento

Se si usa IoT Edge per Linux in Windows, il dispositivo di destinazione nello scenario è la macchina virtuale Linux, non l'host Windows.

Questa esercitazione è destinata ai dispositivi che eseguono IoT Edge con contenitori Linux. Usare il sistema operativo preferito purché il computer di sviluppo esegua contenitori Linux. Visual Studio Code è consigliabile per lo sviluppo con contenitori Linux, quindi questa esercitazione lo usa. È anche possibile usare Visual Studio, anche se esistono differenze nel supporto tra i due strumenti.

La tabella seguente elenca gli scenari di sviluppo supportati per i contenitori Linux in Visual Studio Code e Visual Studio.

Visual Studio Code Visual Studio 2019/2022
Architettura dei dispositivi Linux Linux AMD64
Linux ARM32v7
Linux ARM64
Linux AMD64
Linux ARM32
Linux ARM64
Azure services Azure Functions
Azure Stream Analytics
Azure Machine Learning
Lingue C
C#
Java
Node.js
Python
C
C#
Ulteriori informazioni Azure IoT Edge per Visual Studio Code Azure IoT Edge Tools for Visual Studio 2019
Azure IoT Edge Tools per Visual Studio 2022

Installare il motore per i contenitori

IoT Edge moduli vengono inseriti come contenitori, quindi è necessario un sistema di gestione dei contenitori compatibile con Docker nel computer di sviluppo per compilarli e gestirli. Docker Desktop è una scelta comune per lo sviluppo perché offre un forte supporto per le funzionalità. Docker Desktop in Windows consente di passare tra contenitori Linux e contenitori Windows, in modo da poter sviluppare moduli per diversi tipi di dispositivi IoT Edge.

Usare la documentazione di Docker per installare Docker nel computer di sviluppo:

  • Installare Docker Desktop per Windows. Quando si installa Docker Desktop per Windows, viene chiesto se si vogliono usare contenitori Linux o Windows. È possibile modificare questa impostazione in qualsiasi momento. Questa esercitazione usa contenitori Linux perché i moduli hanno come destinazione i dispositivi Linux. Per altre informazioni, vedere Switch tra contenitori Windows e Linux.

  • Install Docker Desktop for Mac (Installare Docker Desktop per Mac)

  • Leggere l'articolo About Docker CE (Informazioni su Docker CE) per informazioni sull'installazione in diverse piattaforme Linux. Per il Windows Subsystem for Linux (WSL), installare Docker Desktop per Windows.

Configurare gli strumenti

Installare Python Azure IoT Edge Dev Tool per creare la soluzione IoT Edge. È possibile procedere in due modi:

Importante

Gli strumenti Azure IoT Edge per l'estensione Visual Studio Code si trovano in modalità maintenance. Lo strumento di sviluppo preferito è la riga di comando (CLI) Azure IoT Edge Dev Tool.

Usare le estensioni IoT per Visual Studio Code per sviluppare moduli IoT Edge. Queste estensioni offrono modelli di progetto, automatizzano la creazione del manifesto della distribuzione e consentono di monitorare e gestire i dispositivi IoT Edge. In questa sezione si installano Visual Studio Code e l'estensione IoT, quindi si configura l'account Azure per gestire le risorse IoT Hub dall'interno di Visual Studio Code.

  1. Installare Azure IoT Edge estensione.
  2. Installare Azure IoT Hub estensione.
  3. Dopo aver installato le estensioni, aprire il riquadro comandi selezionando Visualizza > riquadro comandi.
  4. Nel riquadro comandi cercare e selezionare Azure IoT Hub: Selezionare IoT Hub. Seguire le istruzioni per selezionare la sottoscrizione Azure e IoT Hub.
  5. Aprire la sezione Explorer di Visual Studio Code selezionando l'icona nella barra delle attività o selezionando View > Explorer.
  6. Nella parte inferiore della sezione Explorer espandere il menu compresso Azure IoT Hub/Devices. Vengono visualizzati i dispositivi e i dispositivi IoT Edge associati all'IoT Hub selezionata tramite la command palette.

Installare strumenti specifici del linguaggio

Installare strumenti specifici per il linguaggio in cui si sta sviluppando:

Creare un registro contenitori

In questa esercitazione si usano le estensioni Azure IoT Edge e Azure IoT Hub per compilare un modulo e creare un'immagine del contenitore dai file. Quindi esegui il push di questa immagine in un registro che archivia e gestisce le immagini. Infine, si distribuisce l'immagine dal registro per l'esecuzione nel dispositivo IoT Edge.

Importante

L'estensione Azure IoT Edge Visual Studio Code è in modalità maintenance.

È possibile usare qualsiasi registro compatibile con Docker per inserire le immagini dei contenitori. Due servizi comuni del Registro di sistema Docker sono Azure Container Registry e Docker Hub. Questa esercitazione usa Azure Container Registry.

Se non si ha già un registro contenitori, seguire questa procedura per crearne uno nuovo in Azure:

  1. Nel portale Azure selezionare Crea una risorsa>Containers>Container Registry.

  2. Specificare i valori necessari seguenti per creare il registro contenitori:

    Campo valore
    Abbonamento Selezionare una sottoscrizione nell'elenco a discesa.
    Gruppo di risorse Usare lo stesso gruppo di risorse per tutte le risorse di test create durante le guide introduttive e le esercitazioni IoT Edge, ad esempio IoTEdgeResources.
    Nome registro Specificare un nome univoco.
    Location Scegliere una località vicina.
    Codice articolo (SKU) Selezionare Basic.
  3. Selezionare Rivedi + crea, quindi Crea.

  4. Selezionare il nuovo registro contenitori nella sezione Resources della home page del portale di Azure per aprirlo.

  5. Nel riquadro sinistro del registro contenitori selezionare Chiavi di accesso dal menu disponibile in Impostazioni.

    Screenshot del percorso del menu Chiavi di accesso.

  6. Abilitare l'utente amministratore con l'interruttore e visualizzare il nome utente e la password per il registro contenitori.

  7. Copiare i valori di Server di accesso, Nome utente e Password e conservarli in una posizione pratica. Questi valori verranno usati durante l'esercitazione per fornire l'accesso al registro contenitori.

Creare un nuovo progetto di modulo

L'estensione Azure IoT Edge offre modelli di progetto per tutte le lingue dei moduli IoT Edge supportate in Visual Studio Code. Questi modelli includono tutti i file e il codice necessari per distribuire un modulo funzionante per testare IoT Edge oppure fornire un punto di partenza per personalizzare il modello con la propria logica di business.

Creare un modello di progetto

Lo strumento di sviluppo IoT Edge semplifica lo sviluppo di Azure IoT Edge, con comandi basati su variabili di ambiente. Consente di iniziare a sviluppare con IoT Edge utilizzando il Dev Container IoT Edge e lo scaffolding della soluzione IoT Edge, che include un modulo predefinito e tutti i file di configurazione necessari.

  1. Crea una directory per la tua soluzione nel percorso desiderato. Passa alla directory iotedgesolution.

    mkdir c:\dev\iotedgesolution
    cd c:\dev\iotedgesolution
    
  2. Usare il comando iotedgedev solution init per creare una soluzione e configurare il Azure IoT Hub nel linguaggio di sviluppo preferito:

    iotedgedev solution init --template csharp
    

Il iotedgedev solution init comando richiede di completare diversi passaggi, tra cui:

  • Eseguire l'autenticazione per Azure
  • Scegliere una sottoscrizione Azure
  • Scegliere o creare un gruppo di risorse
  • Scegliere o creare un Azure IoT Hub
  • Scegliere o creare un dispositivo Azure IoT Edge

Usare Visual Studio Code e l'estensione Azure IoT Edge. Per iniziare, creare una soluzione, quindi generare il primo modulo in tale soluzione. Ogni soluzione può includere più moduli.

  1. Selezionare Visualizza> Riquadro comandi.
  2. Nel riquadro comandi immettere ed eseguire il comando Azure IoT Edge: Nuova soluzione IoT Edge.
  3. Passare alla cartella in cui si vuole creare la nuova soluzione, quindi selezionare Seleziona cartella.
  4. Immettere un nome per la soluzione.
  5. Selezionare un modello di modulo per fare in modo che il linguaggio di sviluppo preferito sia il primo modulo nella soluzione.
  6. Immettere un nome per il modulo. Scegliere un nome univoco all'interno del registro contenitori.
  7. Immettere il nome del repository di immagini del modulo. Visual Studio Code popola automaticamente il nome del modulo con localhost:5000/<nome del modulo>. Sostituire tale valore con le proprie informazioni di registro. Utilizzare localhost se si utilizza un registro Docker locale per il testing. Se si usa Azure Container Registry, usare Server di accesso dalle impostazioni del registro. Il server di accesso ha un nome simile a <nome registro>.azurecr.io. Sostituire solo la parte localhost:5000 della stringa, in modo che il risultato finale assomigli a <nome del registro>.azurecr.io/<nome del modulo>.

Visual Studio Code accetta le informazioni fornite, crea una soluzione IoT Edge e quindi la carica in una nuova finestra.

Dopo aver creato la soluzione, questi file principali si trovano nella soluzione:

  • La cartella vscode include il file di configurazione launch.json.

  • La cartella modules include sottocartelle per ogni modulo. In ogni sottocartella il file module.json controlla la modalità di compilazione e distribuzione dei moduli.

  • Il file .env elenca le variabili di ambiente. La variabile di ambiente per il registro contenitori è localhost:5000 per impostazione predefinita.

  • Due file di distribuzione del modulo, deployment.template.json e deployment.debug.template.json, elencare i moduli da distribuire nel dispositivo. Per impostazione predefinita, l'elenco include i moduli di sistema IoT Edge (edgeAgent e edgeHub) e i moduli di esempio, ad esempio:

    Note

    I moduli esatti installati possono dipendere dalla lingua scelta.

Impostare la versione del runtime IoT Edge

La versione più recente del modulo di sistema stabile IoT Edge è la 1.5. Impostare i moduli di sistema sulla versione 1.5.

  1. In Visual Studio Code aprire il file manifesto della distribuzione deployment.template.json. Il manifesto deployment è un documento JSON che descrive i moduli da configurare nel dispositivo IoT Edge di destinazione.

  2. Modificare la versione di runtime per le immagini del modulo di runtime di sistema edgeAgent e edgeHub. Ad esempio, se si vuole usare il runtime IoT Edge versione 1.5, modificare le righe seguenti nel file manifesto della distribuzione:

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

Specificare le credenziali del registro per l'agente IoT Edge

Il file di ambiente archivia le credenziali per il registro contenitori e le condivide con il runtime di IoT Edge. Il runtime richiede queste credenziali per eseguire il pull delle immagini del contenitore nel dispositivo IoT Edge.

L'estensione IoT Edge cerca di recuperare le credenziali del registro di contenitori da Azure e di inserirle nel file di ambiente.

Note

Il file dell'ambiente viene creato solo se si specifica un repository di immagini per il modulo. Se sono state accettate le impostazioni predefinite di localhost per testare ed eseguire il debug in locale, non è necessario dichiarare le variabili di ambiente.

Controllare se le credenziali esistono. In caso contrario, aggiungerle:

  1. Se Azure Container Registry è il tuo registro, imposta un nome utente e una password per Azure Container Registry. Ottieni questi valori dal menu Settings>Chiavi di accesso nel portale di Azure.

  2. Aprire il file con estensione env nella soluzione del modulo.

  3. Aggiungere i valori username e password copiati dal registro contenitori Azure. Ad esempio:

    CONTAINER_REGISTRY_SERVER="myacr.azurecr.io"
    CONTAINER_REGISTRY_USERNAME="myacr"
    CONTAINER_REGISTRY_PASSWORD="<registry_password>"
    
  4. Salvare le modifiche al file .env.

Note

Questa esercitazione usa le credenziali di amministratore per Azure Container Registry utili per scenari di sviluppo e test. Quando si è pronti per gli scenari di produzione, è consigliabile usare un'opzione di autenticazione con privilegi minimi, ad esempio entità servizio o token con ambito repository. Per altre informazioni, vedere Gestire l'accesso al registro contenitori.

Architettura di destinazione

Selezionare l'architettura di destinazione con ogni soluzione, perché influisce sul modo in cui viene compilato ed eseguito il contenitore. L'impostazione predefinita è Linux AMD64. Per questa esercitazione, usare una macchina virtuale Ubuntu come dispositivo IoT Edge e mantenere il valore predefinito amd64.

Se è necessario modificare l'architettura di destinazione per la soluzione, seguire questa procedura.

  1. Aprire il riquadro comandi e cercare Azure IoT Edge: Imposta piattaforma di destinazione predefinita per la soluzione Edge oppure selezionare l'icona di scelta rapida nella barra laterale nella parte inferiore della finestra.
  2. Nel riquadro comandi selezionare l'architettura di destinazione nell'elenco di opzioni.

L'architettura di destinazione viene impostata quando si crea l'immagine del contenitore in un passaggio successivo.

Aggiornare il modulo con il codice personalizzato

Ogni modello include codice di esempio che accetta dati del sensore simulati dal modulo SimulatedTemperatureSensor e li indirizza al IoT Hub. Il modulo di esempio riceve i messaggi e li passa. La funzionalità della pipeline mostra un concetto importante in IoT Edge: come i moduli comunicano tra loro.

Ogni modulo può avere più code di input e di output dichiarate nel suo codice. L'hub IoT Edge in esecuzione nel dispositivo instrada i messaggi dall'output di un modulo all'input di uno o più moduli. Il codice specifico per la dichiarazione di input e output varia tra le lingue, ma il concetto è lo stesso per tutti i moduli. Per altre informazioni sul routing tra moduli, vedere Dichiarare le route.

Il codice C# di esempio fornito con il modello di progetto usa la classe ModuleClient dall'SDK di IoT Hub per .NET.

  1. Nell'esplora risorse di Visual Studio Code, apri modules > filtermodule > ModuleBackgroundService.cs.

  2. Prima del filtermodule namespace, aggiungere tre using istruzioni per i tipi usati in un secondo momento:

    using System.Collections.Generic;     // For KeyValuePair<>
    using Microsoft.Azure.Devices.Shared; // For TwinCollection
    using Newtonsoft.Json;                // For JsonConvert
    
  3. Aggiungere la temperatureThreshold variabile alla ModuleBackgroundService classe . Questa variabile imposta il valore che la temperatura misurata deve superare affinché i dati vengano inviati al IoT Hub.

    static int temperatureThreshold { get; set; } = 25;
    
  4. Aggiungere le classi MessageBody, Machine, e Ambient. Queste classi definiscono lo schema previsto per il corpo dei messaggi in arrivo.

    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. Trovare la funzione ExecuteAsync. Questa funzione crea e configura un oggetto ModuleClient che consente al modulo di connettersi al runtime Azure IoT Edge locale per inviare e ricevere messaggi. Dopo aver creato ModuleClient, il codice legge il temperatureThreshold valore dalle proprietà desiderate del modulo gemello. Il codice registra un callback per ricevere messaggi da un hub IoT Edge tramite un endpoint denominato input1.

    Sostituire la chiamata del metodo ProcessMessageAsync con una nuova chiamata che aggiorna il nome dell'endpoint e il metodo chiamato quando l'input arriva. Aggiungere anche un SetDesiredPropertyUpdateCallbackAsync metodo per gli aggiornamenti alle proprietà desiderate. Per apportare questa modifica, sostituire l'ultima riga del ExecuteAsync metodo con il codice seguente:

    // 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. Aggiungere il OnDesiredPropertiesUpdate metodo alla ModuleBackgroundService classe . Questo metodo riceve gli aggiornamenti sulle proprietà desiderate dal modulo gemello e aggiorna la temperatureThreshold variabile in modo che corrisponda. Tutti i moduli hanno un modulo gemello che consente di configurare il codice in esecuzione all'interno di un modulo direttamente dal cloud.

    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. Aggiungere il FilterMessages metodo . Questo metodo viene chiamato ogni volta che il modulo riceve un messaggio dall'hub IoT Edge. Filtra i messaggi con un valore della temperatura inferiore alla soglia relativa alla temperatura configurata tramite il modulo gemello. Aggiunge anche la MessageType proprietà al messaggio con il valore impostato su Alert:

    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. Salvare il file ModuleBackgroundService.cs.

  9. In Esplora Visual Studio Code aprire il file deployment.template.json nell'area di lavoro della soluzione IoT Edge.

  10. Poiché è stato modificato il nome dell'endpoint su cui il modulo è in ascolto, è anche necessario aggiornare le route nel manifesto della distribuzione in modo che edgeHub invii messaggi al nuovo endpoint.

    Trova la routes sezione nella $edgeHub modulo gemello. Aggiornare la sensorTofiltermodule route per sostituire input1 con inputFromSensor:

    "sensorTofiltermodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/filtermodule/inputs/inputFromSensor\")"
    
  11. Aggiungere il modulo gemello filtermodule al manifesto della distribuzione. Inserire il contenuto JSON seguente nella parte inferiore della modulesContent sezione, dopo il modulo gemello $edgeHub :

       "filtermodule": {
           "properties.desired":{
               "TemperatureThreshold":25
           }
       }
    
  12. Salvare il file deployment.template.json .

Compilare ed eseguire il push della soluzione

Sono stati aggiornati il codice dei moduli e il modello di distribuzione per comprendere alcuni concetti chiave relativi alla distribuzione. Ora è possibile compilare l'immagine del contenitore del modulo ed eseguirne il push nel Registro Container.

In Visual Studio Code aprire il file manifesto della distribuzione deployment.template.json. Il manifesto deployment descrive i moduli da configurare nel dispositivo IoT Edge di destinazione. Prima della distribuzione, è necessario aggiornare le credenziali di Azure Container Registry e le immagini del modulo con i valori createOptions appropriati. Per altre informazioni sui valori di createOptions, vedere Come configurare le opzioni di creazione del contenitore per i moduli IoT Edge.

Se si usa un Azure Container Registry per archiviare l'immagine del modulo, aggiungere le credenziali alla sezione modulesContent > edgeAgent > settings > registryCredentials in deployment.template.json. Sostituire myacr con il proprio nome del Registro di sistema e specificare la password e l'indirizzo del server di accesso. Ad esempio:

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

Aggiungere o sostituire il seguente contenuto stringificato nel valore createOptions per ogni sistema (edgeHub e edgeAgent) e moduli personalizzati (filtermodule e tempSensor) elencati. Modificare i valori, se necessario:

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

Ad esempio, la filtermodule configurazione dovrebbe essere simile 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\"}]}}}"
}

Immagine Docker del modulo di compilazione

Aprire il terminale integrato Visual Studio Code selezionando Terminal > Nuovo terminale.

Usare il comando dotnet publish per compilare l'immagine del contenitore per l'architettura Linux e amd64. Passare alla directory filtermodule nel progetto ed eseguire il comando dotnet publish.

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

Attualmente, il modello di strumento iotedgedev è destinato a .NET 7.0, che ha raggiunto la fine del supporto a maggio 2024. Aggiornare il progetto alla destinazione .NET 8.0 (LTS, supportato fino a novembre 2026) modificando il file filtermodule.csproj e modificando i valori TargetFramework e PackageReference. Il file filtermodule.csproj sarà simile al seguente:

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

Contrassegnare l'immagine Docker con le informazioni, la versione e l'architettura del registro contenitori. Sostituire myacr con il proprio nome del Registro di sistema:

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

Immagine Docker del modulo push

Fornire a Docker le credenziali del Registro Container, per consentire il push dell'immagine del contenitore da archiviare nel registro.

  1. Accedere a Docker con le credenziali di Azure Container Registry (ACR):

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

    Potrebbe venire visualizzato un avviso di sicurezza in cui si consiglia l'uso di --password-stdin. Anche se è una procedura consigliata per gli scenari di produzione, non rientra nell'ambito di questa esercitazione. Per l'autenticazione del registro dei contenitori in ambiente di produzione, utilizzare un principal del servizio o token specifici per il repository anziché le credenziali di amministratore. Per ulteriori informazioni, vedere Gestire l'accesso al registro contenitori e il riferimento sul login di Docker.

  2. Accedere al Azure Container Registry. È necessario installare Azure CLI per usare il comando az. Questo comando richiede il nome utente e la password trovati nel registro contenitori in Impostazioni > Chiavi di accesso:

    az acr login -n <ACR registry name>
    

    Suggerimento

    Se ti disconnetti in qualsiasi momento durante questa esercitazione, ripeti i passaggi di accesso di Docker e Azure Container Registry per continuare.

  3. Esegui il push dell'immagine del modulo nel registro locale o nel registro dei contenitori:

    docker push <ImageName>
    

    Ad esempio:

    # 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
    

Aggiornare il modello di distribuzione

Aggiornare il modello di distribuzione deployment.template.json con il percorso dell'immagine del registro contenitori. Ad esempio, se si usa un Azure Container Registry myacr.azurecr.io e l'immagine è filtermodule:0.0.1-amd64, aggiornare la configurazione filtermodule in:

"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\"}]}}}"
    }
}

Nell'Esplora di Visual Studio Code, fare clic con il pulsante destro del mouse sul file deployment.template.json e selezionare Compila e Invia Soluzione IoT Edge.

Il comando di creazione e push avvia tre operazioni. Prima di tutto, crea una nuova cartella nella soluzione denominata config che contiene il manifesto completo della distribuzione, basato sulle informazioni del modello di distribuzione e di altri file della soluzione. In secondo luogo, esegue docker build per creare l'immagine del contenitore in base al documento dockerfile appropriato per l'architettura di destinazione. Infine, esegue docker push per eseguire il push del repository di immagini nel registro contenitori.

Questo processo potrebbe richiedere alcuni minuti la prima volta, ma è più veloce la volta successiva che si eseguono i comandi.

Facoltativo: aggiornare il modulo e l'immagine

Se si apportano modifiche al codice del modulo, è necessario ricompilare ed eseguire il push dell'immagine del modulo nel registro contenitori. Usare la procedura descritta in questa sezione per aggiornare l'immagine di compilazione e contenitore. È possibile ignorare questa sezione se non sono state apportate modifiche al codice del modulo.

Aprire il file deployment.amd64.json nella nuova cartella config creata. Il nome del file riflette l'architettura di destinazione, quindi è diverso se si sceglie un'architettura diversa.

Si noti che i due parametri contenenti i segnaposto contengono ora i valori appropriati. La registryCredentials sezione contiene il nome utente e la password del Registro di sistema estratti dal file con estensione env . Il filtermodule contiene il repository di immagini completo con il nome, la versione e il tag di architettura dal file module.json.

  1. Aprire il file module.json nella cartella filtermodule.

  2. Modificare il numero di versione per l'immagine del modulo. Incrementare ad esempio il numero di versione della patch a "version": "0.0.2", come se fosse stata apportata una piccola correzione nel codice del modulo.

    Suggerimento

    Le versioni del modulo abilitano il controllo della versione e consentono di testare le modifiche in un piccolo set di dispositivi prima di distribuire gli aggiornamenti nell'ambiente di produzione. Se non si incrementa la versione del modulo prima della compilazione e del push, si sovrascrive il repository nel Registro Container.

  3. Salvare le modifiche nel file module.json.

Compilare ed eseguire il push dell'immagine aggiornata con un tag di versione 0.0.2. Ad esempio, per compilare ed eseguire il push dell'immagine per il registro locale o un registro contenitori Azure, usare i comandi seguenti:

# 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

Fare di nuovo clic con il pulsante destro del mouse sul file deployment.template.json e selezionare Build e Push IoT Edge Solution di nuovo.

Aprire di nuovo il file deployment.amd64.json. Si noti che il sistema di compilazione non crea un nuovo file quando si esegue di nuovo il comando di compilazione e push. Invece, lo stesso file viene aggiornato per riflettere le modifiche. L'immagine filtermodule ora punta alla versione 0.0.2 del contenitore.

Per verificare ulteriormente le operazioni del comando di build e push, aprire il portale di Azure e navigare nel registro dei contenitori. Nel Registro Container selezionare Repository e quindi filtermodule. Verificare che venga eseguito il push di entrambe le versioni dell'immagine nel registro.

Screenshot della posizione in cui visualizzare entrambe le versioni delle immagini nel registro contenitori.

Risolvere problemi

Se si verificano errori durante la compilazione e il push dell'immagine del modulo, spesso il problema è legato alla configurazione di Docker nel computer di sviluppo. Usare le indicazioni seguenti per esaminare la configurazione:

  • È stato eseguito il comando docker login usando le credenziali copiate dal Registro Container? Queste credenziali sono diverse da quelle usate per accedere a Azure.
  • Il repository di contenitori è corretto? Il nome del Registro Container e quello del modulo sono corretti? Aprire il file module.json nella cartella filtermodule da controllare. Il valore del repository deve essere simile a <nome del registro>.azurecr.io/filtermodule.
  • Se è stato usato un nome diverso da filterModule per il modulo, il nome è coerente in tutta la soluzione?
  • Il computer esegue contenitori dello stesso tipo di quelli che si stanno compilando? Questa esercitazione è destinata ai dispositivi Linux IoT Edge, pertanto Visual Studio Code deve indicare amd64 o arm32v7 nella barra laterale e i contenitori Linux devono essere in esecuzione su Docker Desktop.

Distribuire i moduli nel dispositivo

Si è verificato che le immagini dei contenitori di cui è stata eseguita la compilazione sono archiviate nel Registro Container, quindi è possibile eseguirne la distribuzione in un dispositivo. Assicurarsi che il dispositivo IoT Edge sia operativo.

Usare il comando set-modules IoT Edge Azure CLI per distribuire i moduli nel Azure IoT Hub. Ad esempio, per distribuire i moduli definiti nel file deployment.template.json nel file IoT Hub my-iot-hub per il dispositivo IoT Edge my-device, usare il comando seguente. Sostituire hub-name, device-id e login IoT Hub connection string con valori personalizzati.

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>"

Suggerimento

Trovare il IoT Hub connection string, inclusa la chiave di accesso condiviso, nel portale di Azure. Passare al IoT Hub e selezionare Impostazioni di sicurezza > Criteri di accesso condiviso > iothubowner.

  1. Nella sezione Visual Studio Code Explorer, nella sezione Azure IoT Hub espandere Devices per visualizzare l'elenco dei dispositivi IoT.

  2. Fare clic con il pulsante destro del mouse sul dispositivo IoT Edge in cui si vuole eseguire la distribuzione, quindi selezionare Crea distribuzione per dispositivo singolo.

  3. In Esplora file passare alla cartella config e quindi selezionare il file deployment.amd64.json.

    Non usare il file deployment.template.json, nel quale non sono presenti le credenziali del Registro Container o i valori delle immagini dei moduli. Se si usa un dispositivo Linux ARM32, il nome del manifesto della distribuzione è deployment.arm32v7.json.

  4. Nel dispositivo espandere Moduli per visualizzare un elenco di moduli distribuiti ed in esecuzione. Selezionare il pulsante Aggiorna. Verranno visualizzati i nuovi moduli tempSensor e filtermodule in esecuzione nel dispositivo.

    L'avvio dei moduli può richiedere alcuni minuti. Il runtime IoT Edge riceve il nuovo manifesto di distribuzione, scarica le immagini dei moduli dal sistema di runtime dei container e quindi avvia ogni nuovo modulo.

Visualizzare i messaggi dal dispositivo

Il codice del modulo di esempio ottiene i messaggi tramite la coda di input e li invia tramite la relativa coda di output. Il manifesto della distribuzione configura le route che inviano messaggi a filtermodule da tempSensor e quindi inoltra i messaggi da filtermodule a IoT Hub. Le estensioni Azure IoT Edge e Azure IoT Hub consentono di visualizzare i messaggi quando arrivano a IoT Hub dal dispositivo.

  1. In Esplora di Visual Studio Code selezionare il dispositivo IoT Edge che desideri monitorare, quindi selezionare Avvia monitoraggio dell'endpoint eventi predefinito.

  2. Guarda la finestra di output in Visual Studio Code per visualizzare i messaggi arrivati all'IoT Hub.

    Screenshot della finestra di output di Visual Studio Code che mostra i messaggi da dispositivo a cloud in arrivo.

Visualizzare le modifiche nel dispositivo

Per vedere cosa accade nel dispositivo, usare i comandi in questa sezione per esaminare il runtime e i moduli di IoT Edge in esecuzione nel dispositivo.

Questi comandi sono per il dispositivo IoT Edge, non per il computer di sviluppo. Se stai usando una macchina virtuale per il tuo dispositivo IoT Edge, connettiti ora. In Azure passare alla pagina di panoramica della macchina virtuale e selezionare Connetti per accedere alla connessione secure shell.

  • Visualizzare tutti i moduli distribuiti nel dispositivo e controllarne lo stato:

    iotedge list
    

    Vengono visualizzati quattro moduli: i due moduli di runtime IoT Edge, tempSensor e filtermodule. Tutti e quattro i moduli devono essere indicati come in esecuzione.

  • Esaminare i log per un modulo specifico:

    iotedge logs <module name>
    

    I nomi dei moduli sono sensibili alle maiuscole e minuscole.

    I log tempSensor e filtermodule mostrano i messaggi che stanno elaborando. Il modulo edgeAgent avvia gli altri moduli, quindi i log contengono informazioni sul manifesto della distribuzione. Se un modulo non è elencato o non è in esecuzione, controllare la presenza di errori nei log edgeAgent. Il modulo edgeHub gestisce la comunicazione tra i moduli e IoT Hub. Se i moduli sono in esecuzione ma i messaggi non arrivano al IoT Hub, controllare la presenza di errori nel edgeHub.

Pulire le risorse

Se si vuole continuare con l'articolo consigliato successivo, mantenere le risorse e le configurazioni create e riutilizzarle. È anche possibile continuare a usare lo stesso dispositivo IoT Edge di un dispositivo di test. In caso contrario, per evitare addebiti, eliminare la configurazione locale e le risorse Azure usate in questo articolo.

Eliminare Azure risorse

Non è possibile annullare l'eliminazione di Azure risorse e gruppi di risorse. Assicurarsi di non eliminare accidentalmente il gruppo di risorse sbagliato o le risorse errate. Se è stato creato il IoT Hub all'interno di un gruppo di risorse esistente con risorse da conservare, eliminare solo la risorsa IoT Hub stessa, non il gruppo di risorse.

Per eliminare le risorse:

  1. Accedere al portale di Azure e quindi selezionare Gruppi di risorse.
  2. Selezionare il nome del gruppo di risorse che contiene le risorse di test IoT Edge.
  3. Esaminare l'elenco delle risorse contenute nel gruppo di risorse. Per eliminarli tutti, è possibile selezionare Elimina gruppo di risorse. Se si vogliono eliminare solo alcuni di essi, selezionare ogni risorsa per eliminarle singolarmente.

Passaggi successivi

In questa esercitazione si configurano Visual Studio Code nel computer di sviluppo e si distribuisce il primo modulo IoT Edge con codice che filtra i dati non elaborati generati dal dispositivo IoT Edge.

Continuare con le esercitazioni successive per imparare a usare Azure IoT Edge che consente di distribuire i servizi cloud di Azure per elaborare e analizzare i dati al perimetro.