分享方式:


[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 入口網站中的裝置詳細資料中消失。 未定義的模組也可能出現在裝置上。

原因

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

解決方案

每個裝置僅使用一種類型的部署機制,可以是自動部署或個別裝置部署。 如果您有多個以裝置為目標的自動部署,您可以變更優先順序或目標描述,以確保會將正確的部署套用至指定的裝置。 您也可以更新裝置對應項,使其不再比對自動部署的目標描述。

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

IoT Edge 執行階段

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

徵兆

edgeAgent 模組啟動並成功執行約一分鐘,然後停止。 記錄指出 IoT Edge 代理程式嘗試透過 AMQP 連線至 IoT 中樞,然後嘗試使用 AMQP over WebSocket 連線。 這些作業失敗時,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。 此問題較常見於使用 Windows 容器 (使用 NAT 網路) 的 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 部署中,為每個模組的 createOptions 設定 DNS 伺服器。 例如:

"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 中樞] 模組設定中,從 [容器建立選項] 文字方塊中刪除所有項目。

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

在 deployment.json 檔案中:

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

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

      "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 模組因發生 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 的所有模組強制執行處理序識別。 它會確認模組傳送的所有訊息都來自該模組的主要處理序識別碼。 如果模組從與最初建立的進程標識碼不同的進程標識碼傳送訊息,則會拒絕具有 404 錯誤訊息的訊息。

解決方案

從 1.0.7 版開始,所有模組程序都已有權連線。 如需詳細資訊,請參閱 1.0.7 版本變更記錄

如果無法升級至 1.0.7,請完成下列步驟。 請確定自訂 IoT Edge 模組一律使用相同的處理序識別碼將訊息傳送給 edgeHub。 例如,請務必在 Docker 檔案中使用 ENTRYPOINT,而不使用 CMD 命令。 CMD 命令會導致模組有一個程序識別碼,執行主要程式的 Bash 命令有另一個程序識別碼,而 ENTRYPOINT 則會產生單一程序識別碼。

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

徵兆

資源受限的裝置 (例如 Raspberry Pi) 可能會發生穩定性的問題,尤其是在當作閘道時。 徵兆包括 IoT Edge 中樞模組發生記憶體不足例外狀況、下游裝置無法連線,或裝置在數小時後即無法傳送遙測訊息。

原因

根據預設,IoT Edge 中樞 (是 IoT Edge 執行階段的一部分) 已針對效能最佳化,且會嘗試配置大量的記憶體。 此最佳化不適合用於受限邊緣裝置,而且可能會造成穩定性問題。

解決方案

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

在 Azure 入口網站中:

  1. 在 IoT 中樞選取您的 IoT Edge 裝置,然後從裝置詳細資料頁面中選取 [設定模組]>[執行階段設定]

  2. 為 IoT Edge 中樞模組建立具有型別 True/False 並名為 OptimizeForPerformance、設定為 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. 選取 [建立],以儲存變更並部署模組。

安全性精靈無法成功啟動

徵兆

安全性精靈無法啟動,且模組容器未建立。 IoT Edge 服務未啟動 edgeAgentedgeHub 和其他自訂模組。 在 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 中樞時,下游裝置的認證未正確更新。 因此,edgeAgentedgeHub 模組被設定為具有驗證類型 none (若未明確設定,則為預設值)。 在連線期間,下游裝置上的模組會使用舊認證,而導致驗證失敗。

解決方案

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

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

IoT Edge 在距離 IoT 中樞較遠的地方時,訊息輸送量較低

徵兆

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

原因

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

解決方案

請嘗試 MaxUpstreamBatchSize 環境變數來增加 IoT Edge 中樞。 這會允許單一批次中傳送更多訊息,這會降低裝置與 IoT 中樞之間的往返次數。

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

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

下一步

您在 IoT Edge 平台中發現到錯誤嗎? 提交問題,讓我們可以持續進行改善。

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