共用方式為


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

適用於: IoT Edge 1.5 核取記號 IoT Edge 1.5 IoT Edge 1.4 核取記號 IoT Edge 1.4

重要

IoT Edge 1.5 LTS 和 IoT Edge 1.4 LTS 為支援的版本。 IoT Edge 1.4 LTS 於 2024 年 11 月 12 日結束生命週期。 如果您是舊版,請參閱更新 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 Tools 來建立新專案。
  • 將專案建置為 Docker 容器,並儲存在 Azure Container Registry。
  • 將程式碼部署至 IoT Edge 裝置。

您於此教學課程中建立的 IoT Edge 模組,能夠篩選由您裝置所產生的溫度資料。 它只有在溫度超過指定的閾值時,才會將訊息往上游傳送。 這類於邊緣所進行的分析,對於減少針對雲端所傳輸及儲存的資料量相當有幫助。

必要條件

開發機器:

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

Azure IoT Edge 裝置:

雲端資源:

  • 在 Azure 中擁有免費或標準層的 IoT 中樞

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

提示

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

本教學課程會教授 Visual Studio Code 的開發步驟。

重要概念

本教學課程會逐步引導您開發 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#
詳細資訊 Azure IoT Edge for Visual Studio Code 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 文件以便安裝在開發機器上:

設定工具

安裝以 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. 在容器登錄的左窗格中,從 [設定] 底下的功能表選取 [存取金鑰]

    螢幕擷取畫面:[存取金鑰] 選單位置。

  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: New IoT Edge Solution
  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.jsondeployment.debug.template.json 的模組部署檔案會列出要部署至裝置的模組清單。 依預設,清單會包含 IoT Edge 系統模組 (edgeAgent 和 edgeHub) 和兩個範例模組,例如:

    注意

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

設定 IoT Edge 執行階段版本

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

  1. 在 Visual Studio Code 中,開啟 deployment.template.json 部署資訊清單檔。 部署資訊清單是一份 JSON 文件,其中描述要在目標 IoT Edge 裝置上設定的模組。

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

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

對 IoT Edge 代理程式提供登錄認證

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

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

注意

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

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

  1. 如果您的登錄是 Azure Container Registry,請設定 Azure Container Registry 使用者名稱和密碼。 從 Azure 入口網站內容器登錄的 [設定]>[存取金鑰] 選單取得這些值。

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

  3. 新增您從 Azure Container Registry 複製過來的 [使用者名稱] 和 [密碼] 值。 例如:

    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# 程式碼會使用 IoT Hub SDK for .NET 所提供的 ModuleClient 類別

  1. 在 Visual Studio Code 總管中,開啟 [modules]>[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. 新增 [MessageBody]、[Machine] 和 [Ambient] 類別。 這些類別會定義內送郵件本文的預期結構描述。

    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 屬性新增至該訊息。

    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 模組對應項中尋找路由區段。 更新 sensorTofiltermodule 路由,以 inputFromSensor 取代 input1:

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

       "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]>[設定]>[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 login 參考。

  2. 登入 Azure Container Registry。 您需要安裝 Azure CLI,才能使用 az 命令。 這個命令會要求您提供使用者名稱和密碼,您可以在 [設定]>[存取金鑰] 的容器登錄中找到這些資訊。

    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]。 確認映像的這兩個版本皆會推送至登錄。

螢幕擷取畫面:在容器登錄中檢視這兩個映像版本的位置。

疑難排解

如果您在建置和推送模組映像時遇到錯誤,原因往往與開發機器上的 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,請使用下列命令。 取代 hub-namedevice-id 的值,並使用您自己的值登入 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 中樞的訊息。

    螢幕擷取畫面:顯示可檢視雲端訊息傳入裝置的位置。

檢視裝置上的變更

如果您要查看裝置本身發生了什麼事情,請使用本節中的命令來檢查正在裝置上執行的 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 雲端服務,以在邊緣處理和分析資料。