[Azure IoT Edge 常見問題的解決方案]

警告

本文參考 CentOS,這是接近生命週期結束 (EOL) 狀態的 Linux 發行版本。 請據此考慮您的使用方式和規劃。 如需詳細資訊,請參閱 CentOS 生命週期結束指導

適用於: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解決方案時的常見問題。 如果您需要如何從IoT Edge裝置尋找記錄和錯誤的資訊,請參閱 針對IoT Edge裝置進行疑難解答。

布建和部署

IoT Edge 模組部署成功,然後從裝置消失

徵兆

設定IoT Edge裝置的模組之後,模組會成功部署,但在幾分鐘後,模組會從裝置和 Azure 入口網站中的裝置詳細數據中消失。 除了定義的模組之外,其他模組也可能出現在裝置上。

原因

如果自動部署是以裝置為目標,則會優先於手動設定單一裝置的模組。 Visual Studio Code 中設定模組功能 Azure 入口網站 或建立單一裝置功能的部署會暫時生效。 您會看到您定義的模組在裝置上啟動。 然後,自動部署的優先順序會啟動並覆寫裝置所需的屬性。

解決方案

每個裝置只能使用一種部署機制,即自動部署或個別裝置部署。 如果您有多個以裝置為目標的自動部署,您可以變更優先順序或目標描述,以確保正確的部署適用於指定的裝置。 您也可以更新裝置對應項,使其不再符合自動部署的目標描述。

如需詳細資訊,請參閱 瞭解單一裝置或大規模IoT Edge自動部署。

IoT Edge 執行階段

IoT Edge 代理程式會在一分鐘后停止

徵兆

edgeAgent 模組會啟動並成功執行約一分鐘,然後停止。 記錄指出 IoT Edge 代理程式嘗試透過 AMQP 連線到 IoT 中樞,然後嘗試透過 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)。 如果連線失敗,它會嘗試 WebSockets (埠 443)。

IoT Edge 執行時間會為每個模組設定要通訊的網路。 在Linux上,此網路是網橋網路。 在 Windows 上,它會使用 NAT。 此問題在使用 NAT 網路的 Windows 容器的 Windows 裝置上更為常見。

解決方案

請確定指派給此網橋/NAT 網路的IP位址有因特網的路由。 有時候主機上的 VPN 設定會覆寫 IoT Edge 網路。

Edge 代理程式模組報告「空白的組態檔」,且裝置上未啟動任何模組

徵兆

  • 裝置無法啟動部署中定義的模組。 只有edgeAgent正在執行,但會報告空的組態檔...

  • 當您在裝置上執行sudo iotedge check時,它會報告容器引擎未設定為 DNS 伺服器設定,這可能會影響 IoT 中樞 的連線能力。如需最佳做法,請參閱 https://aka.ms/iotedge-prod-checklist-dns

原因

  • 根據預設,IoT Edge 會在自己的隔離容器網路中啟動模組。 此專用網內的 DNS 名稱解析可能會發生問題。
  • 如果使用IoT Edge的嵌入式管理單元安裝,Docker 組態檔是不同的位置。 請參閱解決方案選項 3。

解決方案

選項 1:在容器引擎設定中設定 DNS 伺服器

在容器引擎設定中指定環境的 DNS 伺服器,這會套用至引擎啟動的所有容器模組。 建立名為 daemon.json的檔案,然後指定要使用的 DNS 伺服器。 例如:

{
    "dns": ["1.1.1.1"]
}

此 DNS 伺服器會設定為可公開存取的 DNS 服務。 不過,某些網路,例如公司網路,已安裝自己的 DNS 伺服器,而且不允許存取公用 DNS 伺服器。 因此,如果您的邊緣裝置無法存取公用 DNS 伺服器,請將它取代為可存取的 DNS 伺服器位址。

放在daemon.json/etc/docker裝置上的目錄中。

如果位置已經包含檔案 daemon.json ,請將 dns 金鑰新增至該檔案並儲存盤案。

重新啟動容器引擎,更新才會生效。

sudo systemctl restart docker

選項 2:在每個模組的 IoT Edge 部署中設定 DNS 伺服器

您可以在 IoT Edge 部署中設定每個模組 createOptionsDNS 伺服器。 例如:

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

警告

如果您使用此方法並指定錯誤的 DNS 位址,edgeAgent 會失去與 IoT 中樞 的連線,且無法接收新的部署來修正此問題。 若要解決此問題,您可以重新安裝IoT Edge執行時間。 安裝 IoT Edge 的新實例之前,請務必從先前的安裝中移除任何 edgeAgent 容器。

請務必為 edgeAgentedgeHub 模組設定此組態。

選項3:傳遞Docker組態檔的位置以檢查命令

如果 IoT Edge 安裝為貼齊,請使用 --container-engine-config-file 參數來指定 Docker 組態檔的位置。 例如,如果 Docker 組態檔位於 /var/snap/docker/current/config/daemon.json,請執行下列命令: iotedge check --container-engine-config-file '/var/snap/docker/current/config/daemon.json'

目前,即使您已設定組態檔位置,警告訊息仍會繼續出現在iotedge檢查輸出中。 檢查報告錯誤,因為IoT Edge嵌入式管理單元沒有 Docker 嵌入式管理單元的讀取許可權。 如果您使用 iotedge 檢查 發行程式,您可以使用 參數來隱藏警告訊息 --ignore container-engine-dns container-engine-logrotate

具有 LTE 連線的 Edge 代理程式模組會報告「空白邊緣代理程式設定」,並導致「暫時性網路錯誤」

徵兆

使用 LTE 連線設定的裝置在部署中定義模組時發生問題。 edgeAgent 無法連線到 IoT 中樞,並報告發生空的邊緣代理程式設定暫時性網路錯誤。

原因

某些網路有封包額外負荷,這會使預設 Docker 網路 MTU (1500) 太高,並導致封包分散導致無法存取外部資源。

解決方案

  1. 檢查 Docker 網路的 MTU 設定。

    docker network inspect <network name>

  2. 檢查裝置上實體網路適配器的 MTU 設定。

    ip addr show eth0

注意

Docker 網路的 MTU 不能高於您裝置的 MTU。 如需詳細資訊,請連絡您的 ISP。

如果您看到 Docker 網路和裝置有不同的 MTU 大小,請嘗試下列因應措施:

  1. 建立新的網路。 例如,

    docker network create --opt com.docker.network.driver.mtu=1430 test-mtu

    在此範例中,裝置的 MTU 設定為 1430。 因此,Docker 網路的 MTU 會設定為 1430。

  2. 停止並移除 Azure 網路。

    docker network rm azure-iot-edge

  3. 重新建立 Azure 網路。

    docker network create --opt com.docker.network.driver.mtu=1430 azure-iot-edge

  4. 拿掉所有容器,然後重新啟動 aziot-edged 服務。

    sudo iotedge system stop && sudo docker rm -f $(docker ps -aq -f "label=net.azure-devices.edge.owner=Microsoft.Azure.Devices.Edge.Agent") && sudo iotedge config apply

Edge 代理程式無法存取模組的映像 (403)

徵兆

容器無法執行, edgeAgent 記錄會報告 403 錯誤。

原因

IoT Edge 代理程式模組沒有存取模組映像的許可權。

解決方案

請確定您的容器登錄認證是正確的裝置部署指令清單。

IoT Edge 代理程式進行過多的身分識別呼叫

徵兆

IoT Edge 代理程式會對 Azure IoT 中樞 進行過多的身分識別呼叫。

原因

裝置部署指令清單設定錯誤會導致裝置上的部署失敗。 IoT Edge 代理程式重試邏輯會繼續重試部署。 每次重試都會進行身分識別呼叫,直到部署成功為止。 例如,如果部署指令清單指定的模組 URI 不存在於容器登錄中或輸入錯誤,IoT Edge 代理程式就會重試部署,直到部署指令清單更正為止。

解決方案

確認 Azure 入口網站 中的部署指令清單。 更正任何錯誤,並將指令清單重新部署至裝置。

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)

Or

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模組嘗試系結的埠。 IoT Edge 中樞會對應埠 443、5671 和 8883,以用於閘道案例。 如果另一個進程已經系結其中一個埠,模組就無法啟動。

解決方案

您可以透過兩種方式解決此問題:

如果 IoT Edge 裝置作為閘道裝置運作,則必須尋找並停止使用埠 443、5671 或 8883 的程式。 埠 443 的錯誤通常表示其他進程是網頁伺服器。

如果您不需要使用IoT Edge裝置作為閘道,則可以從edgeHub的模組建立選項中移除埠系結。 您可以在 Azure 入口網站 或直接在deployment.json檔案中變更建立選項。

在 Azure 入口網站中:

  1. 流覽至您的IoT中樞,然後選取 [裝置管理] 功能表下的 [裝置]。

  2. 選取您要更新的IoT Edge裝置。

  3. 選取 [設定模組]

  4. 選取 [執行階段設定]

  5. 在Edge Hub模組設定中,從 [容器建立選項] 文本框中刪除所有專案。

  6. 選取 [ 套用 ] 以儲存變更並建立部署。

在deployment.json檔案中:

  1. 開啟您套用至 IoT Edge 裝置的deployment.json檔案。

  2. edgeHub在edgeAgent所需屬性區段中尋找設定:

      "edgeHub": {
          "restartPolicy": "always",
          "settings": {
             "image": "mcr.microsoft.com/azureiotedge-hub:1.5",
             "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
          },
          "status": "running",
          "type": "docker"
       }
    
  3. 移除這 createOptions 一行,並在行尾 image 的逗號前面:

      "edgeHub": {
          "restartPolicy": "always",
          "settings": {
          "image": "mcr.microsoft.com/azureiotedge-hub:1.5",
          "status": "running",
          "type": "docker"
    }
    
  4. 選取 [建立 ] 以再次將它套用至 IoT Edge 裝置。

IoT Edge 模組因發生 404 錯誤而無法將訊息傳送給 edgeHub

徵兆

自定義 IoT Edge 模組無法將訊息傳送至 IoT Edge 中樞,併發生 404 Module not found 錯誤。 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的所有模組強制執行進程識別。 它會驗證模組所傳送的所有訊息都來自模組的主要進程標識碼。 如果模組從與最初建立的進程標識碼不同的進程標識碼傳送訊息,則會拒絕具有 404 錯誤訊息的訊息。

解決方案

從 1.0.7 版開始,所有模塊進程都會獲得連線的授權。 如需詳細資訊,請參閱 1.0.7 版變更記錄

如果無法升級至 1.0.7,請完成下列步驟。 請確定自定義 IoT Edge 模組一律使用相同的進程識別碼,將訊息傳送至 edgeHub。 例如,請務必取代 ENTRYPOINTCMD Docker 檔案中的 命令。 命令 CMD 會導致模組的一個進程標識碼,以及執行主要程式之bash命令的另一個進程標識碼,但 ENTRYPOINT 會導致單一進程標識碼。

在較小的裝置上發生穩定性問題

徵兆

您可能會在Raspberry Pi等資源限制裝置上遇到穩定性問題,特別是當做閘道使用時。 徵兆包括IoT Edge中樞模組中的記憶體不足例外狀況、下游裝置無法連線,或裝置在幾個小時後無法傳送遙測訊息。

原因

IoT Edge 中樞是 IoT Edge 運行時間的一部分,預設會針對效能進行優化,並嘗試配置大量的記憶體區塊。 此優化不適合限制邊緣裝置,而且可能會導致穩定性問題。

解決方案

針對IoT Edge中樞,將環境變數 OptimizeForPerformance 設定為 false。 有兩種方式可以設定環境變數:

在 Azure 入口網站中:

  1. 在 IoT 中樞 中,選取 IoT Edge 裝置,然後從裝置詳細數據頁面選取 [設定模組>運行時間 設定]。

  2. 針對名為 OptimizeForPerformance 的 IoT Edge 中樞模組建立環境變數,其類型為 True/False,其設定為 False

  3. 選取 [ 套用 ] 以儲存變更,然後選取 [ 檢閱 + 建立]。

    環境變數現在位於 edgeHub 部署指令清單的屬性中:

       "edgeHub": {
          "env": {
                "OptimizeForPerformance": {
                   "value": false
                }
          },
          "restartPolicy": "always",
          "settings": {
                "image": "mcr.microsoft.com/azureiotedge-hub:1.5",
                "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
          },
          "status": "running",
          "type": "docker"
       }
    
  4. 選取 [建立] 以儲存您的變更並部署模組。

安全性精靈無法成功啟動

徵兆

安全性精靈無法啟動,且未建立模組容器。 edgeAgentIoT Edge 服務不會啟動、 edgeHub 和其他自訂模組。 在記錄中 aziot-edged ,您會看到此錯誤:

  • 精靈無法成功啟動:無法啟動管理服務
  • 原因:路徑 /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. 執行 systemctl disable iotedge.socket iotedge.mgmt.socket 以停用套接字單元,讓 systemd 不會不必要地啟動它們
  2. 變更 iotedge 組態以在 connectlisten 區段中使用/var/lib/iotedge/*.sock
  3. 如果您已經有模組,則會有舊的 /var/run/iotedge/*.sock 掛接,因此 docker rm -f 它們。

網路

IoT Edge 安全性精靈因主機名稱無效而失敗

徵兆

嘗試檢查 IoT Edge 安全性管理員記錄失敗,並列印下列訊息:

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

原因

IoT Edge 運行時間只能支援少於 64 個字元的主機名。 實體機器通常沒有很長的主機名,但此問題在虛擬機上比較常見。 針對 Azure 中裝載的 Windows 虛擬機自動產生的主機名,尤其是很長的時間。

解決方案

當您看到此錯誤時,您可以藉由設定虛擬機的 DNS 名稱,然後在安裝程式命令中將 DNS 名稱設定為主機名來解決此問題。

  1. 在 Azure 入口網站 中,流覽至虛擬機的概觀頁面。

  2. 選取 [DNS 名稱] 底下的 [未設定],或選取現有的 DNS 名稱,以開啟組態面板。 如果您的虛擬機已設定 DNS 名稱,則不需要設定新的名稱。

    如何開啟 DNS 名稱組態面板的螢幕快照。

  3. 如果您還沒有 DNS 名稱標籤,請提供值,然後選取 [儲存]。

  4. 複製新的 DNS 名稱,其格式應為:
    <DNSnamelabel>。<vmlocation.cloudapp.azure.com>

  5. 在IoT Edge裝置上,開啟組態檔。

    sudo nano /etc/aziot/config.toml
    
  6. 將的值 hostname 取代為您的 DNS 名稱。

  7. 儲存並關閉檔案,然後將變更套用至 IoT Edge。

    sudo iotedge config apply
    

IoT Edge模組報告連線錯誤

徵兆

直接連線到雲端服務的IoT Edge模組,包括運行時間模組、如預期般停止運作,並傳回連線或網路失敗的錯誤。

原因

容器依賴IP封包轉送,才能連線到因特網,以便與雲端服務通訊。 預設會在 Docker 中啟用 IP 封包轉送,但如果它已停用,則連線到雲端服務的任何模組將無法如預期般運作。 如需詳細資訊,請參閱 瞭解 Docker 檔中的容器通訊

解決方案

使用下列步驟來啟用IP封包轉送。

  1. 開啟 sysctl.conf 檔案。

    sudo nano /etc/sysctl.conf
    
  2. 在檔案中新增以下一行。

    net.ipv4.ip_forward=1
    
  3. 儲存並關閉檔案。

  4. 重新啟動網路服務和 Docker 服務以套用變更。

閘道後方的 IoT Edge 無法執行 HTTP 要求並啟動 edgeAgent 模組

徵兆

IoT Edge 運行時間使用有效的組態檔,但無法啟動 edgeAgent 模組。 命令 iotedge list 會傳回空的清單。 記錄中的 IoT Edge 執行時間報告 Could not perform HTTP request

原因

網關後方的IoT Edge裝置會從組態檔欄位中指定的 parent_hostname 父 IoT Edge 裝置取得其模組映像。 此錯誤 Could not perform HTTP request 表示下游裝置無法透過 HTTP 連線到其父裝置。

解決方案

請確定父 IoT Edge 裝置可以從下游 IoT Edge 裝置接收連入要求。 針對來自下游裝置的要求,開啟連接埠 443 和 6617 上的流量。

閘道後方的 IoT Edge 無法執行 HTTP 要求並啟動 edgeAgent 模組

徵兆

IoT Edge 精靈使用有效的組態檔,但無法啟動edgeAgent模組。 命令 iotedge list 會傳回空的清單。 IoT Edge 精靈記錄報告 Could not perform HTTP request

原因

網關後方的IoT Edge裝置會從組態檔欄位中指定的 parent_hostname 父 IoT Edge 裝置取得其模組映像。 此錯誤 Could not perform HTTP request 表示下游裝置無法透過 HTTP 連線到其父裝置。

解決方案

請確定父 IoT Edge 裝置可以從下游 IoT Edge 裝置接收連入要求。 針對來自下游裝置的要求,開啟連接埠 443 和 6617 上的流量。

從一個IoT中樞移轉至另一個IoT中樞時,網關後方的IoT Edge無法連線

徵兆

嘗試將IoT Edge裝置階層從一個IoT中樞移轉至另一個中樞時,最上層的IoT Edge裝置可以連線到 IoT 中樞,但下游 IoT Edge 裝置無法連線。 記錄報告 Unable to authenticate client downstream-device/$edgeAgent with module credentials

原因

當移轉至新的IoT中樞時,下游裝置的認證未正確更新。 因此, edgeAgent 模組 edgeHub 已設定為 具有驗證類型 none (如果未明確設定,則為預設值)。 在連線期間,下游裝置上的模組會使用舊認證,導致驗證失敗。

解決方案

移轉至新的IoT中樞時(假設不使用 DPS),請依照下列步驟執行:

  1. 請遵循 本指南,將裝置身分 識別從舊的IoT中樞匯出並匯入到新的裝置身分識別
  2. 重新設定新IoT中樞中的所有IoT Edge部署和設定
  3. 重新設定新IoT中樞中的所有父子裝置關聯性
  4. 更新每個裝置以指向新的 IoT 中樞主機名稱 (iothub_hostnameconfig.toml[provisioning]
  5. 如果您選擇在裝置匯出期間排除驗證金鑰,請使用新 IoT 中樞所提供的新金鑰重新設定每個裝置(device_id_pk在 中config.toml[provisioning.authentication]
  6. 請先重新啟動最上層的父Edge裝置,確定裝置已啟動並執行
  7. 依層級從上到下重新啟動階層層級中的每個裝置

IoT Edge 在與 IoT 中樞 相距遠時,訊息輸送量較低

徵兆

遠距 Azure IoT 中樞 的 Azure IoT Edge 裝置的訊息輸送量低於預期。

原因

裝置與 IoT 中樞之間的高延遲可能會導致低於預期的訊息輸送量。 IoT Edge 會使用預設訊息批次大小 10。 這會限制在單一批次中傳送的訊息數目,這會增加裝置與 IoT 中樞 之間的往返次數。

解決方案

請嘗試增加 IoT Edge 中樞 MaxUpstreamBatchSize 環境變數。 這可讓更多訊息以單一批次傳送,以減少裝置與 IoT 中樞 之間的往返次數。

若要在 Azure 入口網站 中設定 Azure Edge Hub 環境變數:

  1. 流覽至您的 IoT 中樞,然後選取 [裝置管理] 功能表下的 [裝置]。
  2. 選取您要更新的IoT Edge裝置。
  3. 選取 [設定模組]
  4. 選取 [執行階段設定]
  5. 在 [Edge Hub 模組設定] 索引標籤中,將 MaxUpstreamBatchSize 環境變數新增為 Number 類型,值為 20
  6. 選取 [套用]。

下一步

您認為您在 IoT Edge 平台中發現錯誤嗎? 提交問題 ,以便我們可以繼續改善。

如果您有更多問題,請建立 支援要求 以取得協助。