Azure IoT Edge に関する一般的な問題の解決策

適用対象: [はい] アイコン IoT Edge 1.1

重要

IoT Edge 1.1 のサポート終了日は、2022 年 12 月 13 日でした。 本製品、サービス、テクノロジ、または API のサポート内容については、Microsoft 製品のライフサイクルに関するページをご確認ください。 最新バージョンの IoT Edge への更新の詳細については、「 Update IoT Edge」を参照してください。

この記事では、IoT Edge ソリューションを使用するときの一般的な問題を特定して解決します。 IoT Edge デバイスからログやエラーを見つける方法については、IoT Edge デバイスのトラブルシューティングに関するページを参照してください。

プロビジョニングとデプロイ

デプロイに成功した IoT Edge モジュールがデバイスから消える

現象

IoT Edge デバイスのモジュールを設定し、モジュールが正常にデプロイされたものの、そのモジュールが数分後にはデバイスから消え、また Azure portal のデバイス情報からも消えます。 定義されていないモジュールがデバイスに表示されることもあります。

原因

デバイスが自動デプロイの対象になった場合、自動デプロイは、個々のデバイスに対するモジュールの手動設定よりも優先されます。 Azure portal の [モジュールの設定] 機能または Visual Studio Code の [Create deployment for single device] (単一デバイスのデプロイの作成) 機能は、少しの間だけ有効になります。 定義したモジュールがデバイスで起動したことを確認できます。 その後は、自動デプロイが優先されるようになり、デバイスの必要なプロパティは上書きされます。

解決策

使用するデプロイ メカニズムは、デバイスごとに 1 種類 (自動デプロイまたはデバイスの個別デプロイのどちらか一方) のみとしてください。 デバイスが複数の自動デプロイの対象となっている場合、適切なデプロイが特定のデバイスに適用されるよう、優先度またはターゲットの記述を変更することができます。 自動デプロイのターゲットの記述と一致しないよう、デバイス ツインを更新することもできます。

詳細については、「1 台のデバイスまたは多数のデバイスを対象とした IoT Edge 自動展開について」を参照してください。

Windows で IoT Edge ランタイムのログを取得できない

現象

Windows で Get-WinEvent の使用時に EventLogException が表示されます。

原因

Get-WinEvent PowerShell コマンドは、存在しているレジストリ エントリを利用して、特定の ProviderName でログを見つけます。

解決策

IoT Edge デーモンにレジストリ エントリを設定します。 次の内容の iotedge.reg ファイルを作成し、ダブルクリックするか reg import iotedge.reg コマンドを使用して Windows レジストリにインポートします。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\iotedged]
"CustomSource"=dword:00000001
"EventMessageFile"="C:\\ProgramData\\iotedge\\iotedged.exe"
"TypesSupported"=dword:00000007

DPS クライアント エラー

現象

"failed to provision with IoT Hub, and no valid device backup was found dps client error." というエラー メッセージが表示されて IoT Edge が起動に失敗します。

原因

グループ登録を使用して、IoT Hub に IoT Edge デバイスがプロビジョニングされます。 IoT Edge デバイスが異なるハブに移動されます。 その登録が DPS から削除されます。 新しいハブの DPS に新しい登録が作成されます。 デバイスの再プロビジョニングは行われません。

解決策

  1. DPS の資格情報が正しいことを確認します。
  2. sudo iotedge apply config を使用して構成を適用します。
  3. デバイスが再プロビジョニングされない場合は、sudo iotedge system restart を使用してデバイスを再起動してください。
  4. デバイスが再プロビジョニングされない場合は、sudo iotedge system reprovision を使用して強制的に再プロビジョニングを行います。

再プロビジョニングを自動的に行うには、デバイスの構成ファイルで dynamic_reprovisioning: true を設定します。 このフラグを true に設定することで、動的再プロビジョニング機能を有効にできます。 デバイスが見かけ上クラウドに再プロビジョニングされているかのような状況は、IoT Edge がそれ自身の IoT Hub 接続に特定のエラーが発生していないか監視することで検出されます。 IoT Edge は、すべての Edge モジュールと自分自身をシャットダウンすることによって応答します。 デーモンは次回起動時、新しい IoT Hub のプロビジョニング情報を受け取るために、Azure に対するこのデバイスの再プロビジョニングを試みます。

外部のプロビジョニングを使用する場合も、デーモンはシャットダウン前に、再プロビジョニング イベントについての通知を外部プロビジョニング エンドポイントに対して行います。 詳細については、「IoT Hub デバイスの再プロビジョニングの概念」を参照してください。

IoT Edge ランタイム

1 分後に IoT Edge エージェントが停止する

現象

edgeAgent モジュールが起動し、約 1 分間正常に実行された後、停止します。 ログには、IoT Edge エージェントが AMQP 経由で IoT Hub に接続を試みてから、WebSocket 経由の AMQP を使って接続を試みていることが示されています。 それが失敗すると、IoT Edge エージェントは終了します。

edgeAgent ログの例:

2017-11-28 18:46:19 [INF] - Starting module management agent.
2017-11-28 18:46:19 [INF] - Version - 1.0.7516610 (03c94f85d0833a861a43c669842f0817924911d5)
2017-11-28 18:46:19 [INF] - Edge agent attempting to connect to IoT Hub via AMQP...
2017-11-28 18:46:49 [INF] - Edge agent attempting to connect to IoT Hub via AMQP over WebSocket...

原因

ホスト ネットワーク上のネットワーク構成では、IoT Edge エージェントはネットワークに到達できません。 エージェントは、最初に AMQP (ポート 5671) で接続を試みます。 接続が失敗した場合は、WebSocket (ポート 443) が試されます。

IoT Edge ランタイムは、各モジュールが通信するネットワークをセットアップします。 Linux では、このネットワークはブリッジ ネットワークです。 Windows では、NAT を使います。 この問題は、NAT ネットワークを使う Windows コンテナーを使っている Windows デバイスで、より多く見られます。

解決策

このブリッジと NAT ネットワークに割り当てられている IP アドレスに、インターネットへのルートが存在することを確認します。 ホストでの VPN 構成が IoT Edge ネットワークをオーバーライドしている場合があります。

Edge エージェント モジュールで "空の構成ファイル" がレポートされ、デバイスでモジュールが開始しない

現象

デバイスで、デプロイにおいて定義されているモジュールの開始に問題があります。 edgeAgent のみが実行されますが、継続的に "空の構成ファイル..." が報告されます。

原因

既定では、IoT Edge は独自の分離されたコンテナー ネットワークでモジュールを開始します。 デバイスに、このプライベート ネットワーク内での DNS 名の解決に関する問題がある可能性があります。

解決策

オプション 1: コンテナー エンジン設定で DNS サーバーを設定

コンテナー エンジンの設定で環境に対して DNS サーバーを指定すると、そのエンジンによって開始されるすべてのコンテナー モジュールに適用されます。 daemon.json という名前のファイルを作成し、使用する DNS サーバーを指定します。 次に例を示します。

{
    "dns": ["1.1.1.1"]
}

この DNS サーバーは、パブリックにアクセス可能な DNS サービスに設定されます。 ただし、企業ネットワークなどの一部のネットワークには独自の DNS サーバーがインストールされており、パブリック DNS サーバーへのアクセスは許可されません。 そのため、エッジ デバイスがパブリック DNS サーバーにアクセスできない場合は、アクセス可能な DNS サーバー アドレスに置き換えます。

プラットフォームの適切な場所に daemon.json を置きます。

プラットフォーム 場所
Linux /etc/docker
Windows コンテナーを使用した Windows ホスト C:\ProgramData\iotedge-moby\config

その場所に daemon.json ファイルが既にある場合は、それに対する dns キーを追加してファイルを保存します。

コンテナー エンジンを再起動して更新を有効にします。

プラットフォーム command
Linux sudo systemctl restart docker
Windows (管理者用 PowerShell) Restart-Service iotedge-moby -Force

オプション 2: モジュールごとの IoT Edge デプロイで DNS サーバーを設定する

IoT Edge のデプロイで各モジュールの createOptions に DNS サーバーを設定できます。 次に例を示します。

"createOptions": {
  "HostConfig": {
    "Dns": [
      "x.x.x.x"
    ]
  }
}

警告

この方法を使用して間違った DNS アドレスを指定すると、edgeAgent は IoT Hub との接続を失い、問題を修正するための新しいデプロイを受信することができなくなります。 この問題を解決するには、IoT Edge ランタイムを再インストールします。 IoT Edge の新しいインスタンスをインストールする前に、以前のインストールから edgeAgent コンテナーを必ず削除してください。

この構成は、edgeAgent および edgeHub モジュールにも忘れずに設定してください。

IoT Edge エージェントがモジュールのイメージにアクセスできない (403)

現象

コンテナーの実行が失敗し、edgeAgent ログで 403 エラーが報告されます。

原因

IoT Edge エージェント モジュールに、モジュールのイメージにアクセスするためのアクセス許可がありません。

解決策

配置マニフェストで、コンテナー レジストリの資格情報が正しいことを確認します。

IoT Edge ハブが起動に失敗する

現象

edgeHub モジュールが起動に失敗します。 次のいずれかのエラーに似たメッセージがログに表示される場合があります。

One or more errors occurred.
(Docker API responded with status code=InternalServerError, response=
{\"message\":\"driver failed programming external connectivity on endpoint edgeHub (6a82e5e994bab5187939049684fb64efe07606d2bb8a4cc5655b2a9bad5f8c80):
Error starting userland proxy: Bind for 0.0.0.0:443 failed: port is already allocated\"}\n)

または

info: edgelet_docker::runtime -- Starting module edgeHub...
warn: edgelet_utils::logging -- Could not start module edgeHub
warn: edgelet_utils::logging --     caused by: failed to create endpoint edgeHub on network nat: hnsCall failed in Win32:  
        The process cannot access the file because it is being used by another process. (0x20)

原因

edgeHub モジュールがバインドしようとしているポートには、ホスト マシン上の他のプロセスが既にバインドしています。 ポート 443、5671、8883 は、ゲートウェイのシナリオで使用するためためのポートとして、IoT Edge ハブによってマップされます。 そのいずれかのポートが別のプロセスによって既にバインドされていると、モジュールは起動に失敗します。

解決策

この問題は、次の 2 つの方法で解決できます。

IoT Edge デバイスがゲートウェイ デバイスとして機能している場合、443、5671、8883 のいずれかのポートを使用しているプロセスを見つけて停止する必要があります。 ポート 443 のエラーは通常、他のプロセスが Web サーバーであることを意味します。

IoT Edge デバイスをゲートウェイとして使用する必要がなければ、ポートのバインドを edgeHub のモジュール作成オプションから削除することができます。 作成オプションは Azure portal で変更できるほか、deployment.json ファイルで直接変更することもできます。

Azure portal で次の操作を行います。

  1. IoT ハブに移動し、[デバイス管理] メニューで [デバイス] を選択します。

  2. 更新する IoT Edge デバイスを選択します。

  3. [Set Modules] \(モジュールの設定) を選択します。

  4. [ランタイムの設定] を選択します。

  5. Edge Hub モジュールの設定で、[作成オプション] テキスト ボックスの内容をすべて削除します。

  6. 変更を保存してデプロイを作成します。

deployment.json ファイルで次の操作を行います。

  1. IoT Edge デバイスに適用した deployment.json ファイルを開きます。

  2. edgeAgent の desired プロパティ セクションで、edgeHub 設定を見つけます。

    "edgeHub": {
        "settings": {
            "image": "mcr.microsoft.com/azureiotedge-hub:1.1",
            "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
        },
        "type": "docker",
        "status": "running",
        "restartPolicy": "always"
    }
    
  3. createOptions 行とその前の image 行の末尾にあるコンマを削除します。

    "edgeHub": {
        "settings": {
            "image": "mcr.microsoft.com/azureiotedge-hub:1.1"
        },
        "type": "docker",
        "status": "running",
        "restartPolicy": "always"
    }
    
  4. ファイルを保存し、再度 IoT Edge デバイスに適用します。

IoT Edge モジュールが 404 エラーで edgeHub にメッセージを送信できない

現象

カスタム IoT Edge モジュールは、404 Module not found エラーで IoT Edge ハブにメッセージを送信できません。 IoT Edge ランタイムによって、次のメッセージがログに出力されます。

Error: Time:Thu Jun  4 19:44:58 2018 File:/usr/sdk/src/c/provisioning_client/adapters/hsm_client_http_edge.c Func:on_edge_hsm_http_recv Line:364 executing HTTP request fails, status=404, response_buffer={"message":"Module not found"}u, 04 )

原因

IoT Edge ランタイムでは、セキュリティ上の理由から、edgeHub に接続するすべてのモジュールのプロセス識別が強制されます。 モジュールによって送信されているすべてのメッセージが、モジュールのメイン プロセス ID から来ていることが確認されます。 モジュールによって、最初に確立されたのと異なるプロセス ID からメッセージが送信されている場合、そのメッセージは 404 エラー メッセージで拒否されます。

解決策

バージョン 1.0.7 時点では、モジュールのすべてのプロセスが接続を承認されています。 詳しくは、1.0.7 リリース 変更ログのページをご覧ください。

1.0.7 へのアップグレードが不可能な場合は、次の手順を完了します。 カスタム IoT Edge モジュールによる edgeHub へのメッセージの送信で、常に同じプロセス ID が使用されるようにします。 たとえば、Docker ファイル内で、CMD コマンドではなく ENTRYPOINT を使用するようにします。 CMD コマンドでは、モジュールに使用されるプロセス ID とメイン プログラムを実行している bash コマンドに使用されるプロセス ID とが異なりますが、ENTRYPOINT であれば単一のプロセス ID が使用されます。

小型のデバイスでの安定性の問題

現象

Raspberry Pi のようなリソースに制約があるデバイスを、特にゲートウェイとして使用した場合、安定性の問題が発生する可能性があります。 IoT Edge ハブ モジュールでメモリ不足例外が発生したり、ダウンストリームのデバイスが接続に失敗したり、数時間後にデバイスからテレメトリ メッセージを送信できなくなったりするなどの症状が発生します。

原因

IoT Edge ハブは IoT Edge ランタイムの一部であり、既定でパフォーマンスに対して最適化され、メモリの大部分を割り当てようとします。 この最適化は、制約のある Edge デバイスには適していないため、安定性の問題が発生する可能性があります。

解決策

IoT Edge ハブに対して、環境変数 OptimizeForPerformancefalse に設定します。 環境変数を設定するには、次の 2 つの方法があります。

Azure portal で次の操作を行います。

IoT Hub で、IoT Edge デバイスを選択し、[デバイスの詳細] ページから [モジュールの設定]>[ランタイムの設定] の順に選択します。 OptimizeForPerformance という IoT Edge ハブ モジュール用の環境変数を、false に設定して作成します。

false に設定された OptimizeForPerformance

デプロイ マニフェストで:

"edgeHub": {
  "type": "docker",
  "settings": {
    "image": "mcr.microsoft.com/azureiotedge-hub:1.1",
    "createOptions": <snipped>
  },
  "env": {
    "OptimizeForPerformance": {
      "value": "false"
    }
  },

セキュリティ デーモンを正常に開始できませんでした

現象

セキュリティ デーモンが起動に失敗し、モジュール コンテナーが作成されません。 edgeAgentedgeHub、およびその他のカスタム モジュールは、IoT Edge サービスによって開始されません。 aziot-edged ログで、次のエラーが表示されます。

  • デーモンを正常に開始できませんでした。管理サービスを開始できませんでした
  • 原因: path/var/run/iotedge/mgmt.sock でエラーが発生しました
  • 原因: アクセス許可が拒否されました (os エラー 13)

原因

CentOS 7 を除くすべての Linux ディストリビューションの場合、IoT Edge の既定の構成は systemd ソケット アクティブ化を使用することです。 構成ファイルを変更してソケットのアクティブ化を使用せずに URL を /var/run/iotedge/*.sock のままにすると、アクセス許可エラーが発生します。これは、iotedge ユーザーが /var/run/iotedge に書き込むことができず、ソケット自体のロックを解除してマウントできないためです。

解決策

ソケットのアクティブ化がサポートされているディストリビューションでは、ソケットのアクティブ化を無効にする必要はありません。 ただし、ソケットのアクティブ化をまったく使用しない場合は、ソケットを /var/lib/iotedge/ に配置します。

  1. systemd が不必要に起動しないように、systemctl disable iotedge.socket iotedge.mgmt.socket を実行してソケット ユニットを無効にします
  2. connect セクションと listen セクションの両方で /var/lib/iotedge/*.sock を使用するように iotedge 構成を変更します
  3. 既にモジュールがある場合は、古い /var/run/iotedge/*.sock マウントがあるので、それらを docker rm -f します。

OS 不一致のためモジュールを起動できませんでした

症状

edgeHub モジュールは、IoT Edge バージョン 1.1 では起動に失敗します。

原因

Windows モジュールは、ホスト上の Windows バージョンと互換性のないバージョンの Windows を使用します。 IoT Edge Windows バージョン 1809 ビルド 17763 がモジュール イメージの基本レイヤーとして必要ですが、別のバージョンが使用されています。

解決策

「ホストとコンテナー イメージの不一致のトラブルシューティング」で、さまざまな Windows オペレーティング システムのバージョンを確認します。 オペレーティング システムが異なる場合は、IoT Edge Windows バージョン 1809 ビルド 17763 に更新し、そのモジュールに使用されている Docker イメージを再構築します。

ネットワーク

IoT Edge セキュリティ デーモンが無効なホスト名で失敗する

現象

IoT Edge Security Manager のログを確認しようとするとエラーが発生し、次のメッセージが出力されます。

Error parsing user input data: invalid hostname. Hostname cannot be empty or greater than 64 characters

原因

IoT Edge ランタイムは、64 文字未満のホスト名のみをサポートできます。 通常、物理マシンに長いホスト名は付いていませんが、これは仮想マシンではより一般的な問題です。 特に、Azure でホストされる Windows 仮想マシンのために自動生成されるホスト名は長くなる傾向があります。

解決策

このエラーが発生したときは、仮想マシンの DNS 名を構成し、setup コマンドでその DNS 名をホスト名として設定することで、エラーを解決できます。

  1. Azure Portal で、目的の仮想マシンの概要ページに移動します。

  2. DNS 名の下の [構成] を選択します。 仮想マシンに既に構成済みの DNS 名がある場合は、新しいものを構成する必要はありません。

    仮想マシンの DNS 名を構成する

  3. [DNS 名ラベル] に値を指定し、[保存] を選択します。

  4. 新しい DNS 名をコピーします。名前は <DNSnamelabel>.<vmlocation>.cloudapp.azure.com の形式である必要があります。

  5. 仮想マシン内で、次のコマンドを使用して、実際の DNS 名によって IoT Edge ランタイムを設定します。

    • Linux の場合:

      sudo nano /etc/iotedge/config.yaml
      
    • Windows の場合:

      notepad C:\ProgramData\iotedge\config.yaml
      

IoT Edge モジュールによって接続エラーが報告されます

現象

ランタイム モジュールなど、クラウド サービスに直接接続する IoT Edge モジュールは想定どおりに動作を停止し、接続またはネットワークの障害に関するエラーを返します。

原因

コンテナーでは、IP パケット転送がなければインターネットに接続できず、クラウド サービスと通信できません。 Docker では IP パケット転送が既定で有効になっていますが、無効になった場合、クラウド サービスに接続するモジュールは正常に機能しません。 詳細については、Docker ドキュメントの「コンテナ通信の理解」を参照してください。

解決策

IP パケット転送を次の手順で有効にします。

Windows の場合:

  1. Run アプリケーションを起動します。

  2. テキスト ボックスに「regedit」と入力し、[OK] を選択します。

  3. [レジストリ エディター] ウィンドウで HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters を参照します。

  4. IPEnableRouter パラメーターを探します。

    1. パラメーターが存在する場合、パラメーターの値を 1 に設定します。

    2. パラメーターが存在しない場合、次の設定で新しいパラメーターとして追加します。

      設定
      名前 IPEnableRouter
      Type REG_DWORD
      1
  5. [レジストリ エディター] ウィンドウを閉じます。

  6. システムを再起動して変更を適用します。

Linux の場合:

  1. sysctl.conf ファイルを開きます。

    sudo nano /etc/sysctl.conf
    
  2. 次の行をファイルに追加します。

    net.ipv4.ip_forward=1
    
  3. ファイルを保存して閉じます。

  4. ネットワーク サービスと docker サービスを再起動し、変更を適用します。

次のステップ

IoT Edge プラットフォームのバグを発見したと思われる場合は、 改善を続けられるように問題を報告してください。

その他に質問がある場合は、サポート リクエストを作成して対応を要請してください。