教學課程:使用Visual StudioCode開發IoT Edge模組

適用於:IoT Edge 1.4 checkmark IoT Edge 1.4

重要

支援的版本是 IoT Edge 1.4。 如果您是舊版,請參閱更新 IoT Edge

本教學課程將逐步引導您開發及部署您自己的程式代碼至IoT Edge裝置。 您可以使用 Azure IoT Edge 模組,將直接實作商業規則的程式代碼部署到 IoT Edge 裝置。 在將程式代碼部署至Linux裝置快速入門中,您已建立IoT Edge裝置,並從Azure Marketplace 部署模組。

本文包含兩個IoT Edge開發工具的步驟。

  • Azure IoT Edge 開發工具 命令行 (CLI)。 此工具是開發慣用的工具。
  • 適用於 Visual Studio Code 擴充功能的 Azure IoT Edge 工具。 延伸模組處於 維護模式

使用本文開頭的工具選取器按鈕來選取工具版本。

在本教學課程中,您會了解如何:

  • 設定您的開發電腦。
  • 使用IoT Edge工具來建立新的專案。
  • 將您的專案建置為 Docker 容器 ,並將其儲存在 Azure 容器登錄中。
  • 將您的程式代碼部署至IoT Edge裝置。

您在本教學課程中建立的 IoT Edge 模組會篩選裝置所產生的溫度數據。 只有在溫度高於指定的臨界值時,才會將訊息傳送至上游。 這種邊緣分析有助於減少與雲端中通訊和儲存的數據量。

必要條件

開發電腦:

  • 使用您自己的電腦或虛擬機。
  • 您的開發機器必須支援 巢狀虛擬化 來執行容器引擎。
  • 大部分可執行容器引擎的作業系統都可以用來開發適用於Linux裝置的IoT Edge模組。 本教學課程使用 Windows 計算機,但指出 macOS 或 Linux 上的已知差異。
  • 安裝 Visual Studio Code
  • 安裝 Azure CLI

Azure IoT Edge 裝置:

雲端資源:

如果您沒有 Azure 訂用帳戶,請在開始之前先建立 Azure 免費帳戶

提示

如需 Visual Studio Code 或 Visual Studio 2022 中互動式偵錯的指引:

本教學課程會教導Visual StudioCode的開發步驟。

重要概念

本教學課程會逐步解說IoT Edge模組的開發。 IoT Edge 模組是具有可執行程式碼的容器。 您可以將一或多個模組部署到 IoT Edge 裝置。 模組會執行特定工作,例如從感測器擷取數據、清除和分析數據,或將訊息傳送至IoT中樞。 如需詳細資訊,請參閱 瞭解 Azure IoT Edge 模組

開發IoT Edge模組時,請務必瞭解開發電腦與模組部署所在的目標IoT Edge裝置之間的差異。 您建置以儲存模組程式代碼的容器必須符合目標裝置作業系統(OS)。 例如,最常見的案例是有人在 Windows 電腦上開發模組,打算以執行 IoT Edge 的 Linux 裝置為目標。 在此情況下,容器操作系統會是Linux。 當您完成本教學課程時,請記住開發計算機OS與容器OS之間的差異

提示

如果您在 Windows 上使用適用於 Linux 的 IoT Edge,則 案例中的目標裝置 是 Linux 虛擬機,而不是 Windows 主機。

本教學課程是以使用 Linux 容器執行 IoT Edge 的裝置為目標。 只要開發機器執行 Linux 容器,您就可以使用慣用的作業系統。 建議您使用 Visual Studio Code 搭配 Linux 容器進行開發,因此本教學課程會使用。 您也可以使用 Visual Studio,雖然這兩個工具之間有不同支援。

下表列出Visual Studio Code和Visual Studio中 Linux 容器支援的開發案例

Visual Studio Code Visual Studio 2019/2022
Linux 裝置架構 Linux AMD64
Linux ARM32v7
Linux ARM64
Linux AMD64
Linux ARM32
Linux ARM64
Azure 服務 Azure Functions
Azure 串流分析
Azure Machine Learning
語言 C
C#
Java
Node.js
Python
C
C#
詳細資訊 適用於 Visual Studio Code 的 Azure IoT Edge Azure IoT Edge Tools for Visual Studio 2019
Azure IoT Edge Tools for Visual Studio 2022

安裝容器引擎

IoT Edge 模組會封裝為容器,因此您需要 開發計算機上的 Docker 相容容器管理系統 來建置和管理它們。 建議您使用 Docker Desktop 進行開發,因為它的功能支援和受歡迎程度。 Windows 上的 Docker Desktop 可讓您在 Linux 容器與 Windows 容器之間切換,以便開發不同類型的 IoT Edge 裝置模組。

使用 Docker 檔在您的開發電腦上安裝:

  • 安裝 Docker Desktop for Windows

    • 當您安裝適用於 Windows 的 Docker Desktop 時,系統會詢問您是否要使用 Linux 或 Windows 容器。 您可以隨時變更此決策。 在本教學課程中,我們會使用 Linux 容器,因為我們的模組是以 Linux 裝置為目標。 如需詳細資訊,請參閱 在 Windows 和 Linux 容器之間切換。
  • 安裝 Docker Desktop for Mac

  • 如需數個 Linux 平臺上的安裝資訊,請參閱 關於 Docker CE

    • 針對 Windows 子系統 Linux 版 (WSL),安裝適用於 Windows 的 Docker Desktop。

設定工具

安裝以 Python 為基礎的 Azure IoT Edge 開發工具 ,以建立 IoT Edge 解決方案。 有兩個選項:

重要

適用於 Visual Studio Code 的 Azure IoT Edge 工具擴充功能處於維護模式。 慣用的開發工具是命令行 (CLI) Azure IoT Edge 開發工具

使用適用於 Visual Studio Code 的 IoT 延伸模組來開發 IoT Edge 模組。 這些延伸模組提供專案範本、自動建立部署指令清單,並可讓您監視和管理 IoT Edge 裝置。 在本節中,您會安裝Visual Studio Code和IoT擴充功能,然後設定您的 Azure 帳戶,以從 Visual Studio Code 中管理 IoT 中樞 資源。

  1. 安裝 Azure IoT Edge 擴充功能。

  2. 安裝 Azure IoT 中樞擴充功能。

  3. 安裝擴充功能之後,請選取 [檢視>命令選擇區] 來開啟命令選擇區。

  4. 再次在命令選擇區中,搜尋並選取 [Azure IoT 中樞:選取 IoT 中樞。 請遵循提示來選取您的 Azure 訂用帳戶,並 IoT 中樞。

  5. 選取左側活動列中的圖示,或選取 [檢視>總管],以開啟 Visual Studio Code 的 [總管] 區段。

  6. 在總管區段底部,展開折疊的 Azure IoT 中樞 / [裝置] 功能表。 您應該會看到與透過命令選擇區選取之 IoT 中樞 相關聯的裝置和 IoT Edge 裝置。

安裝語言特定工具

安裝您所開發語言特有的工具:

建立容器登錄

在本教學課程中,您會使用 Azure IoT EdgeAzure IoT 中樞 擴充功能來建置模組,並從檔案建立容器映像。 然後將此映像推送至 儲存和管理映像的登錄 。 最後,您會從登錄部署映像,以在IoT Edge裝置上執行。

重要

Azure IoT Edge Visual Studio Code 擴充功能處於 維護模式

您可以使用任何 Docker 相容的登錄來儲存容器映像。 兩個熱門的 Docker 登錄服務是 Azure Container RegistryDocker Hub。 本教學課程使用 Azure Container Registry。

如果您還沒有容器登錄,請遵循下列步驟在 Azure 中建立新的登錄:

  1. Azure 入口網站 中,選取 [建立資源>容器>登錄]。

  2. 提供下列必要值來建立容器登錄:

    欄位
    訂用帳戶 從下拉式清單中選取訂用帳戶。
    資源群組 針對您在IoT Edge快速入門和教學課程期間建立的所有測試資源,使用相同的資源群組。 例如, IoTEdgeResources
    登錄名稱 提供唯一的名稱。
    Location 選擇接近您的位置。
    SKU 選取 [基本]
  3. 選取 [檢閱 + 建立],然後選取 [建立]。

  4. Azure 入口網站 首頁的 [資源] 區段中選取新的容器登錄,以開啟它。

  5. 在容器登錄的左窗格中,從位於 [設定] 下方的功能表中選取 [存取密鑰]。

    Screenshot of the Access Keys menu location.

  6. 使用切換按鈕啟用 管理員 使用者,並檢視容器登錄的使用者名稱和密碼

  7. 複製 [登入伺服器]、[用戶名稱] 和 [密碼] 的值,並將其儲存在方便的地方。 在本教學課程中,您會使用這些值來提供容器登錄的存取權。

建立新的模組專案

Azure IoT Edge 延伸模組提供 Visual Studio Code 中所有支援的 IoT Edge 模組語言專案範本。 這些範本具有部署工作模組以測試 IoT Edge 的所有檔案和程式碼,或提供您以自己的商業規則自定義範本的起點。

建立專案範本

IoT Edge 開發工具 可將 Azure IoT Edge 開發簡化為環境變數所驅動命令。 它可讓您開始使用IoT Edge開發容器和IoT Edge解決方案 Scaffolding 進行IoT Edge開發,其中包含預設模組和所有必要的組態檔。

  1. 使用您選擇的路徑,為您的解決方案建立目錄。 變更至您的 iotedgesolution 目錄。

    mkdir c:\dev\iotedgesolution
    cd c:\dev\iotedgesolution
    
  2. 使用 iotedgedev 解決方案 init 命令來建立解決方案,並以您選擇的開發語言設定您的 Azure IoT 中樞。

    iotedgedev solution init --template csharp
    

iotedgedev 解決方案 init 腳本會提示您完成數個步驟,包括:

  • 向 Azure 驗證
  • 選擇 Azure 訂用帳戶
  • 選擇或建立資源群組
  • 選擇或建立 Azure IoT 中樞
  • 選擇或建立 Azure IoT Edge 裝置

使用 Visual Studio Code 和 Azure IoT Edge 擴充功能。 您可以從建立解決方案開始,然後在該解決方案中產生第一個模組。 每個解決方案都可以包含多個模組。

  1. 選取 [檢視] >[命令調色盤] 。
  2. 在命令選擇區中,輸入並執行 Azure IoT Edge:新的 IoT Edge 解決方案命令
  3. 流覽至您要建立新解決方案的資料夾,然後選取 [選取 資料夾]。
  4. 輸入解決方案的名稱。
  5. 選取適用於您慣用開發語言的模組範本,作為解決方案中的第一個模組。
  6. 輸入模組的名稱。 選擇容器登錄內唯一的名稱。
  7. 提供模組映像存放庫的名稱。 Visual Studio Code 會以 localhost:5000/<您的模組名稱自動填入模組名稱>。 請使用您自己的登錄資訊加以取代。 如果您使用本機 Docker 登錄進行測試,請使用 localhost 。 如果您使用 Azure Container Registry,請使用 登錄設定中的登入伺服器 。 登入伺服器看起來像<登錄名稱>.azurecr.io。 只取代字串的localhost:5000部分,讓最終結果看起來像<登錄名稱>。azurecr.io/< 您的模組名稱。>

Visual Studio Code 會採用您提供的資訊、建立 IoT Edge 解決方案,然後將其載入至新的視窗。

建立方案之後,這些主要檔案位於方案中:

  • .vscode 資料夾包含組態檔launch.json

  • 具有每個模組子資料夾的modules資料夾。 在每個模組的子資料夾中,module.json檔案會控制模組的建置和部署方式。

  • .env 檔案會列出您的環境變數。 容器登錄的環境變數預設為 localhost:5000

  • 兩個名為 deployment.template.json 的模組部署檔案,deployment.debug.template.json 列出要部署到裝置的模組。 根據預設,此列表包含IoT Edge系統模組 (edgeAgent和edgeHub) 和範例模組,例如:

    注意

    安裝的確切模組可能取決於您所選擇的語言。

設定 IoT Edge 執行時間版本

最新的穩定IoT Edge系統模組版本為1.4。 將您的系統模組設定為1.4版。

  1. 在 Visual Studio Code 中,開啟 deployment.template.json 部署指令清單檔案。 部署指令清單是 JSON 檔,描述要設定於目標 IoT Edge 裝置上的模組。

  2. 變更系統運行時間模組映像 edgeAgentedgeHub的運行時間版本。 例如,如果您想要使用IoT Edge 執行時間1.4版,請在部署指令清單檔中變更下列幾行:

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

將您的登錄認證提供給IoT Edge代理程式

環境檔案會儲存容器登錄的認證,並與IoT Edge運行時間共用認證。 運行時間需要這些認證,才能將容器映像提取到IoT Edge裝置。

IoT Edge 擴充功能會嘗試從 Azure 提取容器登錄認證,並在環境檔案中填入這些認證。

注意

環境檔案只會在您為模組提供了映像存放庫時才會建立。 如果您接受 localhost 預設值,並且在本機進行測試和偵錯,則不需要宣告環境變數。

檢查您的認證是否存在。 如果沒有,請立即新增它們:

  1. 如果 Azure Container Registry 是您的登錄,請設定 Azure Container Registry 使用者名稱和密碼。 從容器登錄的 [設定> Access 機碼] 功能表,取得 Azure 入口網站 中的這些值。

  2. 在您的 模組解決方案中開啟 .env 檔案。

  3. 新增您從 Azure 容器登錄複製的使用者名稱和密碼值。 例如:

    CONTAINER_REGISTRY_SERVER="myacr.azurecr.io"
    CONTAINER_REGISTRY_USERNAME="myacr"
    CONTAINER_REGISTRY_PASSWORD="<registry_password>"
    
  4. 將變更儲存至 .env 檔案。

注意

本教學課程會針對適用於開發和測試案例的 Azure Container Registry 使用系統管理員登入認證。 當您準備好進行生產案例時,我們建議使用最低許可權驗證選項,例如服務主體或存放庫範圍的令牌。 如需詳細資訊,請參閱 管理容器登錄的存取權。

目標架構

您必須選取以每個解決方案為目標的架構,因為這會影響容器的建置和執行方式。 預設值為Linux AMD64。 在本教學課程中,我們會使用Ubuntu虛擬機作為IoT Edge裝置,並保留預設 amd64

如果您需要變更解決方案的目標架構,請使用下列步驟。

  1. 開啟命令選擇區並搜尋 Azure IoT Edge:設定 Edge 解決方案的預設目標平臺,或選取視窗底部側邊列中的快捷方式圖示。

  2. 在命令選擇區中,從選項清單中選取目標架構。

當您在稍後的步驟中建立容器映射時,會設定目標架構。

使用自定義程式代碼更新模組

每個範本都包含從 SimulatedTemperatureSensor 模組取得模擬感測器數據的範例程式代碼,並將它路由傳送至 IoT 中樞。 範例模組會接收訊息,然後傳遞訊息。 管線功能示範 IoT Edge 中的重要概念,也就是模組彼此通訊的方式。

每個模組都可以在其程序代碼中宣告多個輸入和輸出佇列。 在裝置上執行的IoT Edge中樞會將訊息從一個模組的輸出路由傳送至一或多個模組的輸入。 宣告輸入和輸出的特定程式代碼會因語言而異,但概念在所有模組中都相同。 如需模組之間路由的詳細資訊,請參閱 宣告路由

項目範本隨附的 C# 程式代碼範例會使用適用於 .NET 的 IoT 中樞 SDK 中的 ModuleClient 類別

  1. 在 Visual Studio Code 總管中,開啟模組>filtermodule>ModuleBackgroundService.cs。

  2. filtermodule 命名空間之前,針對稍後使用的型別新增三 個 using 語句:

    using System.Collections.Generic;     // For KeyValuePair<>
    using Microsoft.Azure.Devices.Shared; // For TwinCollection
    using Newtonsoft.Json;                // For JsonConvert
    
  3. temperatureThreshold 變數新增至 ModuleBackgroundService 類別。 此變數會設定測量溫度必須超過的值,才能將數據傳送至IoT中樞。

    static int temperatureThreshold { get; set; } = 25;
    
  4. 新增 MessageBodyMachine 和環境類別。 這些類別會定義內送訊息本文的預期架構。

    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. 尋找 ExecuteAsync 函式。 此函式會建立及設定 ModuleClient 物件,讓模組連線到本機 Azure IoT Edge 執行時間以傳送和接收訊息。 建立 ModuleClient 之後,程式代碼會從模組對應項所需的屬性讀取 temperatureThreshold 值。 程式代碼會註冊回呼,以透過名為 input1 的端點接收來自 IoT Edge 中樞的訊息。

    將 ProcessMessageAsync 方法的呼叫取代為更新端點名稱的新方法,以及輸入送達時所呼叫的方法。 此外,新增 SetDesiredPropertyUpdateCallbackAsync 方法,以更新所需的屬性。 若要進行這項變更,請使用下列程式代碼取代 ExecuteAsync 方法的最後一行

    // 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. onDesiredPropertiesUpdate 方法新增至 ModuleBackgroundService 類別。 此方法會從模組對應項接收所需屬性的更新,並更新 temperatureThreshold 變數以符合。 所有模組都有自己的模組對應項,可讓您直接從雲端設定在模組內執行的程序代碼。

    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. 新增 FilterMessages 方法。 每當模組收到來自IoT Edge中樞的訊息時,就會呼叫這個方法。 它會篩選出訊息,這些訊息會報告溫度低於透過模塊對應項設定的溫度閾值。 它也會將 MessageType 屬性新增至訊息,並將值設定為 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. 儲存 ModuleBackgroundService.cs 檔案。

  9. 在 Visual Studio Code 總管中,開啟 IoT Edge 解決方案工作區中的deployment.template.json 檔案。

  10. 由於我們已變更模組接聽的端點名稱,因此我們也需要在部署指令清單中更新路由, 讓edgeHub 將訊息傳送至新的端點。

    在$edgeHub模組對應項中尋找 routes 區段。 更新 sensorTofiltermodule 路由,以 取代input1inputFromSensor

    "sensorTofiltermodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/filtermodule/inputs/inputFromSensor\")"
    
  11. filtermodule 模組對應項新增至部署指令清單。 將下列 JSON 內容插入 modulesContent 區段底部的模組對應項後面,$edgeHub模組對應項:

       "filtermodule": {
           "properties.desired":{
               "TemperatureThreshold":25
           }
       }
    
  12. 儲存 deployment.template.json 檔案。

建置並推送您的解決方案

您已更新模組程式代碼和部署範本,以協助瞭解一些重要的部署概念。 現在,您已準備好建置模組容器映像,並將其推送至您的容器登錄。

在 Visual Studio Code 中,開啟 deployment.template.json 部署指令清單檔案。 部署指令清單描述要設定在目標 IoT Edge 裝置上的模組。 部署之前,您必須使用適當的 createOptions 值來更新 Azure Container Registry 認證和模組映射。 如需 createOption 值的詳細資訊,請參閱 如何設定 IoT Edge 模組的容器建立選項。

如果您使用 Azure Container Registry 來儲存模組映像,請將認證新增至 deployment.template.json 中的 modulesContent edgeAgent>settings>registryCredentials 區段。> 以您自己的登錄名稱取代 myacr ,並提供密碼和 登入伺服器 位址。 例如:

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

將下列字串化內容新增或取代至 每個系統 (edgeHub 和 edgeAgent) 和自定義模組 (filtermodule 和 tempSensor) 的 createOptions 值。 視需要變更值。

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

例如,filtermodule態應該類似:

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

建置模組 Docker 映像

選取 [終端>機] [新增終端機],以開啟 Visual Studio Code 整合式終端機。

dotnet publish使用 命令來建置適用於Linux和 amd64架構的容器映像。 將目錄變更為專案中的 filtermodule 目錄,然後執行 dotnet publish 命令。

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

iotedgedev 工具範本目前以 .NET 7.0 為目標。 如果您想要以不同版本的 .NET 為目標,您可以編輯 filtermodule.csproj 檔案,並變更 TargetFrameworkPackageReference 值。 例如,若要以 .NET 8.0 為目標,您的 filtermodule.csproj 檔案看起來應該像這樣:

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

使用您的容器登錄資訊、版本和架構標記 Docker 映像。 以您自己的登錄名稱取代 myacr

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

推送模組 Docker 映像

將您的容器登錄認證提供給 Docker,以便將容器映像推送至登錄中的記憶體。

  1. 使用 Azure Container Registry (ACR) 認證登入 Docker。

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

    您可能會收到建議使用 --password-stdin的安全性警告。 雖然這是生產案例的建議最佳做法,但本教學課程的範圍並不相同。 如需詳細資訊,請參閱 docker 登入 參考。

  2. 登入 Azure Container Registry。 您必須 安裝 Azure CLI 才能使用 az 命令。 此命令會要求您在 設定> Access 機碼中容器登錄中找到的使用者名稱和密碼。

    az acr login -n <ACR registry name>
    

    提示

    如果您在本教學課程中的任何時間點註銷,請重複 Docker 和 Azure Container Registry 登入步驟以繼續。

  3. 將您的模組映像推送 至本機登錄或容器登錄。

    docker push <ImageName>
    

    例如:

    # 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
    

更新部署範本

使用容器登錄映像位置更新部署範本 deployment.template.json 。 例如,如果您使用 Azure Container Registry myacr.azurecr.io ,而您的映像是 filtermodule:0.0.1-amd64,請將 filtermodule 組態更新為:

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

在 Visual Studio Code 總管中,以滑鼠右鍵按兩下 deployment.template.json 檔案,然後選取 [ 建置和推送 IoT Edge 解決方案]。

建置和推送命令會啟動三個作業。 首先,它會在名為 config 的解決方案中建立新的資料夾,以保存完整部署指令清單,內建部署範本和其他解決方案檔案中的資訊。 其次,它會執行 docker build ,根據目標架構的適當 dockerfile 來建置容器映像。 然後,它會執行 docker push ,將映像存放庫推送至容器登錄。

此程式第一次可能需要幾分鐘的時間,但下次執行命令時會更快。

選擇性:更新模組和映像

如果您變更模組程序代碼,則必須重建模組映像,並將模組映像推送至容器登錄。 使用本節中的步驟來更新組建和容器映像。 如果您未對模組程式代碼進行任何變更,則可以略過本節。

在新 建立的 config 資料夾中開啟deployment.amd64.json 檔案。 檔名會反映目標架構,因此如果您選擇不同的架構,則不同。

請注意,具有佔位元的兩個參數現在包含其適當的值。 registryCredentials 區段會從 .env 檔案提取您的登錄用戶名稱和密碼。 filtermodule 具有module.json檔案中名稱、版本和架構標籤的完整映像存放庫。

  1. filtermodule 資料夾中開啟module.json檔案。

  2. 變更模組映像的版本號碼。 例如,將修補程式版本號碼遞增為 "version": "0.0.2" ,就像您在模組程序代碼中做了一個小修正一樣。

    提示

    模組版本可啟用版本控制,並可讓您先在一組小型裝置上測試變更,再將更新部署至生產環境。 如果您在建置和推送之前未遞增模組版本,則會覆寫容器登錄中的存放庫。

  3. 將變更儲存至 module.json 檔案。

使用 0.0.2 版本標籤建置並推送更新的映像。 例如,若要建置和推送本機登錄或 Azure 容器登錄的映像,請使用下列命令:


# 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

再次以滑鼠右鍵按兩下deployment.template.json檔案,然後再次選取 [建置和推送IoT Edge解決方案]。

再次開啟deployment.amd64.json檔案。 請注意,當您再次執行組建並推送命令時,建置系統不會建立新的檔案。 相反地,相同的檔案會更新以反映變更。 filtermodule 映射現在指向容器的 0.0.2 版本。

若要進一步確認建置和推送命令的作業,請移至 Azure 入口網站 並流覽至您的容器登錄。

在您的容器登錄中,選取 [存放庫],然後選取 filtermodule。 確認這兩個版本的映像推送至登錄。

Screenshot of where to view both image versions in your container registry.

疑難排解

如果您在建置和推送模組映射時遇到錯誤,通常必須與開發計算機上的 Docker 組態有關。 使用下列檢查來檢閱您的設定:

  • 您是否 docker login 使用從容器登錄複製的認證來執行命令? 這些認證與您用來登入 Azure 的認證不同。
  • 您的容器存放庫是否正確? 它是否有正確的容器登錄名稱和正確的模組名稱? 開啟 filtermodule 資料夾中要檢查的module.json檔案。 存放庫值看起來應該像 <登錄名稱>.azurecr.io/filtermodule
  • 如果您針對模組使用的名稱與 filtermodule 不同,該名稱在整個解決方案中是否一致?
  • 您的電腦是否執行您正在建置的相同容器類型? 本教學課程適用於Linux IoT Edge裝置,因此Visual Studio Code 應該會在側邊欄中說 amd64arm32v7 ,而 Docker Desktop 應該執行 Linux 容器。

將模組部署至裝置

您已確認容器登錄中儲存了已建置的容器映像,因此是時候將它們部署至裝置了。 請確定您的 IoT Edge 裝置已啟動並執行。

使用 IoT Edge Azure CLI set-modules 命令,將模組部署至 Azure IoT 中樞。 例如,若要將 deployment.template.json 檔案中定義的模組部署至ioT Edge裝置 my-device IoT 中樞 my-iot-hub,請使用下列命令。 將中樞名稱、裝置識別碼登入 IoT 中樞 連接字串 的值取代為您自己的值。

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

提示

您可以在 Azure 入口網站 中找到您的 IoT 中樞 連接字串 包括共用存取金鑰。 移至您的 IoT 中樞 >安全性設定>共用存取原則>iothubowner。

  1. 在 Visual Studio Code 總管的 [Azure IoT 中樞] 區段底下,展開 [裝置] 以查看您的 IoT 裝置清單。

  2. 以滑鼠右鍵按下您要部署的 IoT Edge 裝置,然後選取 [ 建立單一裝置的部署]。

  3. 在檔案總管中,流覽至 config 資料夾,然後選取 deployment.amd64.json 檔案。

    請勿使用deployment.template.json檔案,檔案中沒有容器登錄認證或模組映射值。 如果您以 Linux ARM32 裝置為目標,部署指令清單的名稱會 deployment.arm32v7.json

  4. 在您的裝置下,展開 [模組 ] 以查看已部署和執行的模組清單。 選取 [重新整理] 按鈕。 您應該會看到在裝置上執行的新 tempSensorfiltermodule 模組。

    模組可能需要幾分鐘的時間才能啟動。 IoT Edge 執行時間必須接收新的部署指令清單、從容器運行時間提取模組映像,然後啟動每個新模組。

從裝置檢視訊息

範例模組程式代碼會透過其輸入佇列接收訊息,並透過其輸出佇列傳遞訊息。 部署指令清單宣告路由,會將訊息從 tempSensor 傳遞至 filtermodule,然後將訊息從 filtermodule 轉送至 IoT 中樞。 Azure IoT Edge 和 Azure IoT 中樞 擴充功能可讓您在訊息從個別裝置抵達 IoT 中樞 時看到訊息。

  1. 在 Visual Studio Code 總管中,以滑鼠右鍵按下您要監視的 IoT Edge 裝置,然後選取 [ 開始監視內建事件端點]。

  2. 觀看 Visual Studio Code 中的輸出視窗,以查看抵達 IoT 中樞的訊息。

    Screenshot showing where to view incoming device to cloud messages.

檢視裝置上的變更

如果您想要查看裝置本身發生的情況,請使用本節中的命令來檢查裝置上執行的 IoT Edge 執行時間和模組。

本節中的命令適用於IoT Edge裝置,而不是您的開發電腦。 如果您使用適用於IoT Edge裝置的虛擬機,請立即連線到該虛擬機。 在 Azure 中,移至虛擬機的概觀頁面,然後選取 連線 來存取安全殼層連線。

  • 檢視部署至裝置的所有模組,並檢查其狀態:

    iotedge list
    

    您應該會看到四個模組:兩個 IoT Edge 運行時間模組 tempSensorfiltermodule。 您應該會看到所有四個都列為執行中。

  • 檢查特定模組的記錄:

    iotedge logs <module name>
    

    IoT Edge 模組會區分大小寫。

    tempSensorfiltermodule 記錄應該會顯示正在處理的訊息。 edgeAgent 模組負責啟動其他模組,因此其記錄有實作部署指令清單的相關信息。 如果您發現模組未列出或未執行,edgeAgent 記錄可能會有錯誤。 edgeHub 模組負責模組與 IoT 中樞 之間的通訊。 如果模組已啟動並執行,但訊息未抵達IoT中樞,edgeHub記錄可能會有錯誤。

清除資源

如果您打算繼續閱讀下一篇建議的文章,您可以保留您所建立的資源和組態並重複使用它們。 您也可以繼續使用與測試裝置相同的 IoT Edge 裝置。

否則,您可以刪除本文中使用的本機設定和 Azure 資源,以避免產生費用。

刪除 Azure 資源

刪除 Azure 資源和資源群組是無法回復的動作。 請確定您不會不小心刪除錯誤的資源群組或資源。 如果您在現有資源群組內建立IoT中樞,且該資源群組具有您想要保留的資源,請只刪除IoT中樞資源本身,而不是資源群組。

若要刪除資源:

  1. 登入 Azure 入口網站,然後選取 [資源群組]。

  2. 選取包含IoT Edge測試資源的資源群組名稱。

  3. 檢閱資源群組中包含的資源清單。 如果您想要刪除所有資源群組,您可以選取 [ 刪除資源群組]。 如果您想要只刪除其中一些資源,您可以按下每個資源來個別刪除它們。

下一步

在本教學課程中,您會在開發計算機上設定 Visual Studio Code,並部署了第一個 IoT Edge 模組,其中包含程式代碼來篩選 IoT Edge 裝置所產生的原始數據。

您可以繼續進行下一個教學課程,以瞭解 Azure IoT Edge 如何協助您部署 Azure 雲端服務,以處理和分析邊緣的數據。