次の方法で共有


Learn how to deploy modules and establish routes in IoT Edge (IoT Edge にモジュールをデプロイしてルートを確立する方法)

適用対象:IoT Edge 1.5 のチェックマーク IoT Edge 1.5

重要

IoT Edge 1.5 LTS は、サポートされているリリースです。 IoT Edge 1.4 LTS は、2024 年 11 月 12 日をもってサポートが終了しています。 以前のリリースの場合は、「IoT Edge を更新する」を参照してください。

各 IoT Edge デバイスでは、$edgeAgent と $edgeHub という少なくとも 2 つのモジュールが実行されます。これらは IoT Edge ランタイムに含まれています。 IoT Edge デバイスは、異なるプロセスに対して複数のモジュールを実行できます。 配置マニフェストを使用して、インストールするモジュールと、それらを連携するように設定する方法をデバイスに指示します。

デプロイ マニフェストは、次の内容が記述された JSON ドキュメントです。

  • 3 つのコンポーネントを含む IoT Edge エージェント モジュール ツイン。
    • デバイスで実行される各モジュールのコンテナー イメージ
    • モジュール イメージを持つプライベート コンテナー レジストリを使用するための資格情報
    • 各モジュールを作成および管理する方法の手順
  • IoT Edge ハブ モジュール ツインには、モジュール間や IoT Hub へのメッセージの流れが含まれています。
  • さらに別のモジュール ツインがある場合は、その必要なプロパティ (省略可能)

すべての IoT Edge デバイスには配置マニフェストが必要です。 新しくインストールされた IoT Edge ランタイムには、有効なマニフェストが設定されるまでエラー コードが表示されます。

Azure IoT Edge のチュートリアルでは、Azure IoT Edge ポータルのウィザードを使用して配置マニフェストを作成します。 REST または IoT Hub Service SDK を使用して、プログラムで配置マニフェストを適用することもできます。 詳細については、IoT Edge のデプロイに関する記事を参照してください。

配置マニフェストの作成

配置マニフェストは、必要なプロパティで設定されたモジュール ツインの一覧です。 IoT Edge デバイスまたはデバイスのグループに、インストールするモジュールとその設定方法が示されます。 配置マニフェストには、"desired プロパティ" (必要なプロパティ) がモジュール ツインごとに記述されています。 IoT Edge デバイスは、各モジュールの 報告されたプロパティ を報告します。

すべての配置マニフェストには、 $edgeAgent$edgeHubの 2 つのモジュールが必要です。 これらのモジュールは、IoT Edge デバイスとそこで実行されるモジュールを管理する IoT Edge ランタイムの構成要素です。 これらのモジュールの詳細については、IoT Edge ランタイムとそのアーキテクチャの概要に関するページを参照してください。

2 つのランタイム モジュールに加えて、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": { ... }
  }
}

すべてのモジュールには、モジュール イメージを含む設定プロパティ、コンテナー レジストリ内のコンテナー イメージのアドレス、および起動時にイメージを設定するための createOptions があります。 詳細については、「IoT Edge モジュールのコンテナー作成オプションを構成する方法」を参照してください。

edgeHub モジュールとカスタム モジュールには、IoT Edge エージェントに管理方法を指示する 3 つのプロパティもあります。

  • 状態: モジュールが最初にデプロイされたときに実行または停止するかどうか。 必須。

  • RestartPolicy: IoT Edge エージェントが停止した場合にモジュールを再起動するタイミングとタイミング。 エラーなしでモジュールが停止した場合、モジュールは自動的に開始されません。 詳細については、Docker Docs のコンテナーの自動開始に関するページを参照してください。 必須。

  • StartupOrder: IoT Edge バージョン 1.0.10 で導入されました。 IoT Edge エージェントが最初にデプロイされたときにモジュールを開始するために使用する順序。 この順序では整数が使用されます。スタートアップ値が 0 のモジュールが最初に開始され、次に数値が大きくなります。 edgeAgent モジュールは、常に最初に起動するため、スタートアップ値がありません。 省略可能。

    IoT Edge エージェントは、スタートアップ値の順序でモジュールを起動しますが、各モジュールの開始が完了してから次のモジュールを開始するまで待機しません。

    起動順序は、一部のモジュールが他のモジュールに依存している場合に役立ちます。 たとえば、edgeHub モジュールを最初に起動して、他のモジュールの起動時にメッセージをルーティングする準備が整う場合があります。 または、データを送信するモジュールを開始する前に、ストレージ モジュールを開始することもできます。 ただし、他のモジュールの障害を処理するように、常にモジュールを設計してください。 コンテナーは、いつでも、および任意の回数で停止および再起動できます。

    モジュールのプロパティを変更すると、そのモジュールが再起動されます。 たとえば、次のプロパティを変更すると再起動が発生します。

    • モジュール イメージ
    • Docker の作成オプション
    • 環境変数
    • 再起動ポリシー
    • イメージのプル ポリシー
    • バージョン
    • 起動順序

    モジュールのプロパティが変更されていない場合、モジュールの再起動はトリガーされません。

ルートの宣言

IoT Edge ハブは、モジュール、IoT Hub、およびダウンストリーム デバイス間の通信を管理します。 $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 を使用します。

各ルートには、受信メッセージの ソース と送信メッセージの シンク が必要です。 条件は省略可能であり、メッセージをフィルター処理できます。

重要なメッセージを最初に処理するために、ルートに 優先順位 を割り当てます。 この機能は、アップストリーム接続が弱いか制限されていて、標準のテレメトリ メッセージよりも重要なデータに優先順位を付ける必要がある場合に役立ちます。

source

ソースでは、メッセージがどこから送信されるのかを指定します。 IoT Edge は、モジュールまたはダウンストリーム デバイスからメッセージをルーティングすることができます。

IoT SDK を使用すると、モジュールは ModuleClient クラスを使用して、メッセージの特定の出力キューを設定できます。 出力キューは必須ではありませんが、複数のルートを管理するのに役立ちます。 ダウンストリーム デバイスでは、IoT SDK の DeviceClient クラスを使用して、IoT Hub にメッセージを送信するのと同様に、IoT Edge ゲートウェイ デバイスにメッセージを送信します。 詳細については、「Azure IoT Hub SDK の概要と使用方法」を参照してください。

source プロパティでは、次のいずれかの値を使用できます。

source 説明
/* 任意のモジュールまたはダウンストリーム デバイスからのすべての device-to-cloud メッセージまたはツイン変更通知
/twinChangeNotifications 任意のモジュールまたはダウンストリーム デバイスから送信されるツイン変更 (reported プロパティ)
/messages/* モジュールによって (なんらかの出力を通じてまたは出力なしで) 送信される、またはダウンストリーム デバイスによって送信される device-to-cloud メッセージ
/messages/modules/* 何らかの出力と共に、または出力なしでモジュールによって送信された、デバイスからクラウドへの任意のメッセージ
/messages/modules/<moduleId>/* なんらかの出力を通じて、または出力なしで特定のモジュールによって送信される任意の device-to-cloud メッセージ
/messages/modules/<moduleId>/outputs/* なんらかの出力を通じて特定のモジュールによって送信される任意の device-to-cloud メッセージ
/messages/modules/<moduleId>/outputs/<output> 特定の出力を通じて特定のモジュールによって送信される任意の device-to-cloud メッセージ

条件

条件は、ルートの宣言では省略可能です。 ソースからシンクにすべてのメッセージを渡すには、 WHERE 句を除外します。 または、 IoT Hub クエリ言語 を使用して、条件を満たすメッセージまたはメッセージの種類をフィルター処理します。 IoT Edge のルートは、ツインのタグやプロパティに基づくメッセージのフィルタリングをサポートしません。

IoT Edge のモジュール間を移動するメッセージは、デバイスと Azure IoT Hub の間のメッセージと同じ形式を使用します。 すべてのメッセージは JSON 形式を使用し、 systemPropertiesappPropertiesおよび本文 パラメーターを持っています。

次の構文を使用して、次の 3 つのパラメーターのいずれかに関するクエリを作成します。

  • システム プロパティ: $<propertyName> または {$<propertyName>}
  • アプリケーション プロパティ: <propertyName>
  • 本文プロパティ: $body.<propertyName>

メッセージ プロパティのクエリを作成する方法の例については、「 Device-to-cloud message routes query expressions」を参照してください。

たとえば、ダウンストリーム デバイスからゲートウェイ デバイスに到着したメッセージをフィルター処理できます。 モジュールから送信されるメッセージには、connectionModuleId と呼ばれるシステム プロパティが含まれます。 ダウンストリーム デバイスから直接 IoT Hub にメッセージをルーティングし、モジュール メッセージを除外するには、次のルートを使用します。

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

シンク

シンクは、メッセージを送信する場所を定義します。 メッセージを受信できるのは、モジュールと IoT Hub だけです。 メッセージを他のデバイスにルーティングすることはできません。 シンク プロパティはワイルドカードをサポートしていません。

シンク プロパティでは、次のいずれかの値を使用できます。

シンク 説明
$upstream IoT Hub にメッセージを送信する
BrokeredEndpoint("/modules/<moduleId>/inputs/<input>") 特定のモジュールの特定の入力にメッセージを送信する

IoT Edge では、 少なくとも 1 回 の保証が提供されます。 ルートがシンクにメッセージを配信できない場合、IoT Edge ハブはメッセージをローカルに格納します。 たとえば、IoT Edge ハブが IoT Hub に接続できない場合、またはターゲット モジュールが接続されていない場合です。

IoT Edge ハブは、storeAndForwardConfiguration.timeToLiveSecsなプロパティの プロパティに設定された時間までのメッセージを格納します。

優先順位と有効期限

ルートを、ルートを定義する文字列として、またはルート文字列、優先度整数、および time-to-live 整数を持つオブジェクトとして宣言します。

オプション 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 ハブの storeAndForwardConfiguration からの値を使用します。 値には正の整数を指定できます。

優先順位キューの管理方法の詳細については、ルートの 優先順位と有効期間に関するページを参照してください。

必要なプロパティの定義または更新

配置マニフェストは、IoT Edge デバイスにデプロイされた各モジュールの必要なプロパティを設定します。 現時点でモジュール ツインにある必要なプロパティは、配置マニフェストにある必要なプロパティによってすべて上書きされます。

デプロイ マニフェストでモジュール ツインの必要なプロパティを設定しない場合、IoT Hub はモジュール ツインを変更しません。 代わりに、必要なプロパティをプログラムで設定します。

デバイス ツインを変更できるのと同じメカニズムを使用して、モジュール ツインを変更することもできます。 詳細については、モジュール ツイン開発者ガイドをご覧ください。

デプロイ マニフェストの例

次の例は、有効な配置マニフェスト ドキュメントの外観を示しています。

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

次のステップ