共用方式為


了解如何在 IoT Edge 中部署模組及建立路由

適用於:IoT Edge 1.5 檢查標記 IoT Edge 1.5

重要

IoT Edge 1.5 LTS 是 支援的版本。 自 2024 年 11 月 12 日起,IoT Edge 1.4 LTS 已結束生命週期。 如果您是舊版,請參閱更新 IoT Edge

每個 IoT Edge 裝置會至少執行兩個模組:$edgeAgent 和 $edgeHub;這兩個模組都是 IoT Edge 執行階段的一部分。 IoT Edge 裝置可以針對不同的進程執行多個模組。 使用部署指令清單來告知裝置要安裝哪些模組,以及如何設定模組以一起運作。

部署資訊清單是 JSON 文件,描述:

  • IoT Edge 代理程式模組對應項,其包含三個元件:
    • 裝置上執行之每個模組的容器映像
    • 使用具有模組映像的私人容器登錄的認證
    • 如何建立和管理每個模組的指示
  • IoT Edge hub 模組孿生,包括模組之間以及模組與 IoT 中樞之間的訊息流動方式
  • 任何額外模組雙子的所需屬性(可選)

所有 IoT Edge 裝置都需要部署指令清單。 新安裝的 IoT Edge 運行時會顯示錯誤碼,直到使用有效的指令清單進行設定為止。

在 Azure IoT Edge 教學課程中,您會使用 Azure IoT Edge 入口網站中的精靈來建置部署指令清單。 您也可以使用 REST 或 IoT 中樞服務 SDK,以程式設計方式套用部署指令清單。 如需詳細資訊,請參閱了解 IoT Edge 部署

建立部署資訊清單

部署清單是一個設定模組對應項所需屬性的清單。 它會告訴IoT Edge裝置或裝置群組要安裝哪些模組,以及如何加以設定。 部署資訊清單包含每個模組對應項的「所需屬性」。 IoT Edge 裝置會報告每個模組 的報告屬性

每個部署指令清單都需要兩個模組: $edgeAgent$edgeHub。 這些模組是 IoT Edge 執行階段的一部分,IoT Edge 執行階段負責管理 IoT Edge 裝置與在其上執行的模組。 如需這些模組的詳細資訊,請參閱了解 IoT Edge 執行階段及其架構

除了兩個運行時間模組之外,您還可以在IoT Edge裝置上新增最多50個額外的模組來執行。

只有 IoT Edge 運行時($edgeAgent$edgeHub)的部署清單是有效的。

部署指令清單會使用此結構:

{
  "modulesContent": {
    "$edgeAgent": { // required
      "properties.desired": {
        // desired properties of the IoT Edge agent
        // includes the image URIs of all deployed modules
        // includes container registry credentials
      }
    },
    "$edgeHub": { //required
      "properties.desired": {
        // desired properties of the IoT Edge hub
        // includes the routing information between modules and to IoT Hub
      }
    },
    "module1": {  // optional
      "properties.desired": {
        // desired properties of module1
      }
    },
    "module2": {  // optional
      "properties.desired": {
        // desired properties of module2
      }
    }
  }
}

設定模組

定義 IoT Edge 執行階段在您部署中安裝模組的方式。 IoT Edge 代理程式是一項執行階段元件,負責管理 IoT Edge 裝置的安裝、更新及狀態回報。 因此,$edgeAgent模組對應項具有所有模組的組態和管理資訊。 此資訊也包括 IoT Edge 代理程式本身的設定參數。

$EdgeAgent 屬性遵循此結構:

{
  "modulesContent": {
    "$edgeAgent": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "runtime": {
          "settings":{
            "registryCredentials":{
              // let the IoT Edge agent use container images that aren't public
            }
          }
        },
        "systemModules": {
          "edgeAgent": {
            // configuration and management details
          },
          "edgeHub": {
            // configuration and management details
          }
        },
        "modules": {
          "module1": {
            // configuration and management details
          },
          "module2": {
            // configuration and management details
          }
        }
      }
    },
    "$edgeHub": { ... },
    "module1": { ... },
    "module2": { ... }
  }
}

IoT Edge 代理程式架構 1.1 版是使用 IoT Edge 1.0.10 版發行,可讓您設定模塊啟動順序。 針對執行 1.0.10 或更新版本的任何 IoT Edge 部署,使用架構 1.1 版。

模組設定和管理

IoT Edge 代理程式所需的屬性清單可讓您定義在 IoT Edge 裝置上執行的模組,以及其設定和管理方式。

如需瞭解哪些屬性可以或必須納入,請參閱 IoT Edge 代理程式和 IoT Edge 中樞屬性的完整所需屬性清單。

例如:

{
  "modulesContent": {
    "$edgeAgent": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "runtime": { ... },
        "systemModules": {
          "edgeAgent": { ... },
          "edgeHub": { ... }
        },
        "modules": {
          "module1": {
            "version": "1.0",
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "startupOrder": 2,
            "settings": {
              "image": "myacr.azurecr.io/module1:latest",
              "createOptions": "{}"
            }
          },
          "module2": { ... }
        }
      }
    },
    "$edgeHub": { ... },
    "module1": { ... },
    "module2": { ... }
  }
}

每個模組都有 settings 屬性,包含模組 映像、容器登錄中的映像位址,以及任何在啟動時用於設置映像的 createOptions。 如需詳細資訊,請參閱如何設定 IoT Edge 模組的容器建立選項

edgeHub 模組和自訂模組也有三個屬性,可告知 IoT Edge 代理程式如何管理模組:

  • 狀態:模組第一次部署時是否執行或停止。 必要。

  • RestartPolicy:IoT Edge 代理程式在停止時重新啟動模組的時機和時機。 如果模組停止且沒有任何錯誤,則不會自動啟動。 如需詳細資訊,請參閱 Docker Docs - 自動啟動容器。 必要。

  • StartupOrder在 IoT Edge 1.0.10 版中引進。 IoT Edge 代理程式在第一次部署時用來啟動模組的順序。 順序會使用整數,其中具有啟動值為 0 的模組會先啟動,然後接著較高的數位。 edgeAgent 模組一律會先啟動,因此沒有啟動值。 選擇性。

    IoT Edge 代理程式會依啟動值的順序啟動模組,但不會等待每個模組完成開始,再開始下一個模組。

    如果某些模組相依於其他模組,啟動順序會有所説明。 例如,您可能希望edgeHub模組先啟動,以便準備好在其他模組啟動時路由訊息。 或者,您可能想要先啟動記憶體模組,再啟動將數據傳送至該模組的模組。 總是設計模組以能夠處理其他模組的故障。 容器可以隨時停止並重新啟動,且可以重複多次。

    注意

    變更模組的屬性會重新啟動該模組。 例如,如果您變更下列屬性,系統就會重新啟動:

    • 模組映像
    • Docker 建立選項
    • 環境變數
    • 重新啟動原則
    • 映像提取原則
    • 版本
    • 啟動順序

    如果未變更模組屬性,則不會觸發模組重新啟動。

宣告路由

IoT Edge 中樞會管理模組、IoT 中樞和下游裝置之間的通訊。 $edgeHub模組對應項具有稱為 路由 的所需屬性,可定義訊息在部署內移動的方式。 您可以在相同的部署中設定多個路由。

使用下列語法宣告 $edgeHub 所需屬性中的路由:

{
  "modulesContent": {
    "$edgeAgent": { ... },
    "$edgeHub": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "routes": {
          "route1": "FROM <source> WHERE <condition> INTO <sink>",
          "route2": {
            "route": "FROM <source> WHERE <condition> INTO <sink>",
            "priority": 0,
            "timeToLiveSecs": 86400
          }
        },
        "storeAndForwardConfiguration": {
          "timeToLiveSecs": 10
        }
      }
    },
    "module1": { ... },
    "module2": { ... }
  }
}

IoT Edge 1.0.10 版發行的 IoT Edge 中樞架構第 1 版,可讓您設定路由優先順序和存留時間。 針對執行 1.0.10 或更新版本的任何 IoT Edge 部署,使用架構 1.1 版。

每個路由都需要一個用於連入訊息的 來源 以及一個用於傳出訊息的 匯入端條件是選擇性的,可讓您篩選訊息。

優先順序 指派給路由,以先處理重要的訊息。 當上游連線弱式或有限時,此功能可協助您將重要數據優先於標準遙測訊息。

來源

來源會指定訊息來自於何處。 IoT Edge 可路由來自模組或下游裝置的訊息。

透過IoT SDK,模組可以使用ModuleClient類別為其訊息設定特定的輸出佇列。 輸出佇列並非必要,但有助於管理多個路由。 下游裝置使用IoT SDK中的DeviceClient類別,將訊息傳送至IoT Edge閘道裝置,就像將訊息傳送至IoT中樞一樣。 如需詳細資訊,請參閱了解和使用 Azure IoT 中樞 SDK

source 屬性可以使用下列任何值:

來源 描述
/* 所有來自任何模組或下游裝置的裝置到雲端訊息或對應項變更通知
/twinChangeNotifications 任何來自任何模組或下游裝置的對應項變更 (報告屬性)
/messages/* 任何由模組或下游裝置透過部分或無輸出傳送的裝置到雲端訊息
/messages/modules/* 由模組透過部分或無輸出傳送的任何裝置到雲端訊息
/messages/modules/<moduleId>/* 任何由特定模組透過部分或無輸出傳送的裝置到雲端訊息
/messages/modules/<moduleId>/outputs/* 任何由特定模組透過部分輸出傳送的裝置到雲端訊息
/messages/modules/<moduleId>/outputs/<output> 任何由特定模組透過特定輸出傳送的裝置到雲端訊息

狀況

條件在路由宣告中是選擇性項目。 若要將所有訊息從來源傳遞至接收端,請留空 WHERE 子句。 或使用 IoT中樞查詢語言 來篩選符合條件的訊息或訊息類型。 IoT Edge 路由不支援根據對應項標籤或屬性來篩選訊息。

在IoT Edge中的模組之間行動的訊息,會使用與裝置與 Azure IoT 中樞之間的訊息相同的格式。 所有訊息都會使用 JSON 格式,並具有 systemPropertiesappProperties主體 參數。

使用下列語法,針對這三個參數中的任何一個建置查詢:

  • 系統屬性:$<propertyName>{$<propertyName>}
  • 應用程式屬性:<propertyName>
  • 主體屬性:$body.<propertyName>

如需如何建立訊息屬性查詢的範例,請參閱 裝置到雲端訊息路由查詢表達式

例如,您可能想要篩選從下游裝置抵達閘道裝置的訊息。 來自模組的訊息包含稱為 connectionModuleId 的系統屬性。 若要將來自下游裝置的訊息直接路由傳送至IoT中樞並排除模組訊息,請使用下列路由:

FROM /messages/* WHERE NOT IS_DEFINED($connectionModuleId) INTO $upstream

接收

匯流排定義訊息的傳送地點。 只有模組與 IoT 中樞能接收訊息。 您無法將訊息路由傳送至其他裝置。 sink 屬性不支援通配符。

接收屬性可以使用下列任何值:

接收 描述
$upstream 將訊息傳送到 IoT 中樞
BrokeredEndpoint("/modules/<moduleId>/inputs/<input>") 將訊息傳送到特定模組的特定輸入

IoT Edge 提供至少一次 保證。 IoT Edge 中樞會將訊息儲存在本機,若路由無法傳送訊息至目的端。 例如,如果 IoT Edge 中樞無法連接到 IoT 中樞,或者目標模組未連接。

IoT Edge 中樞會將訊息儲存,直到在 storeAndForwardConfiguration.timeToLiveSecs屬性設定的時間為止。

優先順序和存留時間

將路由宣告為定義路由的字串,或宣告為具有路由字元串、優先順序整數和存留時間整數的物件。

選項 1

"route1": "FROM <source> WHERE <condition> INTO <sink>",

選項 2 (在 IoT Edge 1.0.10 版中引進 IoT Edge 中樞架構 1.1 版)

"route2": {
  "route": "FROM <source> WHERE <condition> INTO <sink>",
  "priority": 0,
  "timeToLiveSecs": 86400
}

優先順序 值的範圍從 0 到 9,其中 0 是最高優先順序。 訊息會依其端點排入佇列。 特定端點的所有優先順序 0 訊息都會在相同端點的任何優先順序 1 訊息之前處理。 如果相同端點的多個路由具有相同的優先順序,訊息會依照訊息到達的順序進行處理。 如果您未設定優先順序,路由會使用最低優先順序。

timeToLiveSecs 屬性會使用來自 IoT Edge 中心的 存儲與轉發配置 的值,除非您直接加以設定。 此值可為任何正整數。

如需如何管理優先順序佇列的詳細資訊,請參閱 路由優先順序和存留時間

定義或更新所需屬性

部署指令清單會針對部署到IoT Edge裝置的每個模組設定所需的屬性。 部署資訊清單中的所需屬性會覆寫目前在模組對應項中的任何所需屬性。

如果您未在部署指令清單中設定模組對應項所需的屬性,IoT 中樞就不會變更模組對應項。 相反地,以程式設計方式設定所需的屬性。

可讓您變更裝置對應項的相同機制也可讓您變更模組對應項。 如需詳細資訊,請參閱模組對應項開發人員指南

部署資訊清單範例

下列範例顯示有效的部署指令清單文件外觀。

{
  "modulesContent": {
    "$edgeAgent": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "runtime": {
          "type": "docker",
          "settings": {
            "minDockerVersion": "v1.25",
            "loggingOptions": "",
            "registryCredentials": {
              "ContosoRegistry": {
                "username": "myacr",
                "password": "<password>",
                "address": "myacr.azurecr.io"
              }
            }
          }
        },
        "systemModules": {
          "edgeAgent": {
            "type": "docker",
            "settings": {
              "image": "mcr.microsoft.com/azureiotedge-agent:1.5",
              "createOptions": "{}"
            }
          },
          "edgeHub": {
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "startupOrder": 0,
            "settings": {
              "image": "mcr.microsoft.com/azureiotedge-hub:1.5",
              "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
            }
          }
        },
        "modules": {
          "SimulatedTemperatureSensor": {
            "version": "1.5",
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "startupOrder": 2,
            "settings": {
              "image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.5",
              "createOptions": "{}"
            }
          },
          "filtermodule": {
            "version": "1.0",
            "type": "docker",
            "status": "running",
            "restartPolicy": "always",
            "startupOrder": 1,
            "env": {
              "tempLimit": {"value": "100"}
            },
            "settings": {
              "image": "myacr.azurecr.io/filtermodule:latest",
              "createOptions": "{}"
            }
          }
        }
      }
    },
    "$edgeHub": {
      "properties.desired": {
        "schemaVersion": "1.1",
        "routes": {
          "sensorToFilter": {
            "route": "FROM /messages/modules/SimulatedTemperatureSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/filtermodule/inputs/input1\")",
            "priority": 0,
            "timeToLiveSecs": 1800
          },
          "filterToIoTHub": {
            "route": "FROM /messages/modules/filtermodule/outputs/output1 INTO $upstream",
            "priority": 1,
            "timeToLiveSecs": 1800
          }
        },
        "storeAndForwardConfiguration": {
          "timeToLiveSecs": 100
        }
      }
    }
  }
}

下一步