Azure IoT Edge ClientModule 无法在主机模式下连接
Azure IoT Edge ClientModule can't connect in host mode
正如初学 IoT Edge 开发人员所期望的那样,我开始遵循有关如何将自定义代码部署到 IoT Edge 服务器的 Microsoft 教程 Tutorial: Develop a C# IoT Edge module for Linux devices。
我能够在一台工业英特尔 PC 上安装 Ubuntu 18.04 服务器,下载并配置 edgeHub 和 edgeAgent 模块,创建一个免费的 Azure 和 Docker Hub 帐户等。即使是示例教程中的代码已成功构建并部署到我的目标设备,一切看起来都很好,所有模块都在相互通信,等等。
获得 运行 的演示代码后,我开始修改代码以更好地满足我的最终目标,即捕获我们使用 UDP multicast/broadcast 的工业设备生成的网络流量.显然我需要在 'host' 网络模式下将我的 docker 图像配置为 运行。事实上,一旦我告诉 azure edgeAgent 在主机模式下启动模块容器,UDP 数据包就开始进来了。
然而,现在我的示例模块无法再连接到物联网集线器,我完全不知所措。我也尝试 运行 主机模式下的 edgeHub 容器,这似乎没有任何区别。 ModuleClient.OpenAsync 方法导致的确切错误是:
Unhandled exception. System.AggregateException: One or more errors occurred. (Transient network error occurred, please retry.)
---> Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException: Transient network error occurred, please retry.
---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 0xFFFDFFFF): Name or service not known
at System.Net.Dns.InternalGetHostByName(String hostName)
at System.Net.Dns.ResolveCallback(Object context)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source)
at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult)
at System.Net.Dns.EndGetHostAddresses(IAsyncResult asyncResult)
at System.Net.Dns.<>c.<GetHostAddressesAsync>b__25_1(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttTransportHandler.OpenAsyncInternal(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttTransportHandler.OpenAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.Transport.ProtocolRoutingDelegatingHandler.OpenAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.<>c__DisplayClass23_0.<<ExecuteWithErrorHandlingAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.ExecuteWithErrorHandlingAsync[T](Func`1 asyncOperation)
--- End of inner exception stack trace ---
at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.ExecuteWithErrorHandlingAsync[T](Func`1 asyncOperation)
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.<>c__DisplayClass33_0.<<OpenInternalAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.EnsureOpenedAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.InternalClient.OpenAsync()
at SampleModule.Program.Init() in /app/SampleModule/Program.cs:line 54
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at SampleModule.Program.Main(String[] args) in /app/SampleModule/Program.cs:line 26
用于连接的代码:
ITransportSettings[] settings = { mqttSetting };
ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings);
await ioTHubModuleClient.OpenAsync();
Console.WriteLine("IoT Hub module client initialized.");
很明显,ModuleClient 无法再找到 edgeHub(名称或服务未知?)。我知道 'CreateFromEnvironmentAsync' 使用 edgeAgent 设置的环境变量,但哪些是?任何人都知道这是为什么?非常感谢开始调试此问题的正确方向的指示!
如果我将 docker 容器改回 'bridge' 网络,OpenAsync 方法可以完美运行,但当然不再接收我的 UDP 广播消息。
经过进一步挖掘,我自己找到了解决方案。
Module fails to restart because of transient network error
这篇文章,虽然我已经读过很多遍了,但还是提示 /etc/hosts 文件有问题。果然,我的设备 (127.0.1.1) 的条目有误,我一定是在某个地方更改了我的设备的主机名,而此更改未反映在主机文件中。
自那次更改以来,我让 AMQP 和 MQTT 都可以工作,但是两者都使用 edgeHub 容器 运行 在主机模式下。在桥接模式下,我 运行 遇到了一个新问题,其中 docker-proxy 没有绑定导出的端口(这导致了一个新的 'Connection refused' 异常)。为什么......
仍然是个谜
正如初学 IoT Edge 开发人员所期望的那样,我开始遵循有关如何将自定义代码部署到 IoT Edge 服务器的 Microsoft 教程 Tutorial: Develop a C# IoT Edge module for Linux devices。
我能够在一台工业英特尔 PC 上安装 Ubuntu 18.04 服务器,下载并配置 edgeHub 和 edgeAgent 模块,创建一个免费的 Azure 和 Docker Hub 帐户等。即使是示例教程中的代码已成功构建并部署到我的目标设备,一切看起来都很好,所有模块都在相互通信,等等。
获得 运行 的演示代码后,我开始修改代码以更好地满足我的最终目标,即捕获我们使用 UDP multicast/broadcast 的工业设备生成的网络流量.显然我需要在 'host' 网络模式下将我的 docker 图像配置为 运行。事实上,一旦我告诉 azure edgeAgent 在主机模式下启动模块容器,UDP 数据包就开始进来了。
然而,现在我的示例模块无法再连接到物联网集线器,我完全不知所措。我也尝试 运行 主机模式下的 edgeHub 容器,这似乎没有任何区别。 ModuleClient.OpenAsync 方法导致的确切错误是:
Unhandled exception. System.AggregateException: One or more errors occurred. (Transient network error occurred, please retry.)
---> Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException: Transient network error occurred, please retry.
---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 0xFFFDFFFF): Name or service not known
at System.Net.Dns.InternalGetHostByName(String hostName)
at System.Net.Dns.ResolveCallback(Object context)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source)
at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult)
at System.Net.Dns.EndGetHostAddresses(IAsyncResult asyncResult)
at System.Net.Dns.<>c.<GetHostAddressesAsync>b__25_1(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttTransportHandler.OpenAsyncInternal(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.Transport.Mqtt.MqttTransportHandler.OpenAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.Transport.ProtocolRoutingDelegatingHandler.OpenAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.<>c__DisplayClass23_0.<<ExecuteWithErrorHandlingAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.ExecuteWithErrorHandlingAsync[T](Func`1 asyncOperation)
--- End of inner exception stack trace ---
at Microsoft.Azure.Devices.Client.Transport.ErrorDelegatingHandler.ExecuteWithErrorHandlingAsync[T](Func`1 asyncOperation)
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.<>c__DisplayClass33_0.<<OpenInternalAsync>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.Azure.Devices.Client.Transport.RetryDelegatingHandler.EnsureOpenedAsync(CancellationToken cancellationToken)
at Microsoft.Azure.Devices.Client.InternalClient.OpenAsync()
at SampleModule.Program.Init() in /app/SampleModule/Program.cs:line 54
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at SampleModule.Program.Main(String[] args) in /app/SampleModule/Program.cs:line 26
用于连接的代码:
ITransportSettings[] settings = { mqttSetting };
ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings);
await ioTHubModuleClient.OpenAsync();
Console.WriteLine("IoT Hub module client initialized.");
很明显,ModuleClient 无法再找到 edgeHub(名称或服务未知?)。我知道 'CreateFromEnvironmentAsync' 使用 edgeAgent 设置的环境变量,但哪些是?任何人都知道这是为什么?非常感谢开始调试此问题的正确方向的指示!
如果我将 docker 容器改回 'bridge' 网络,OpenAsync 方法可以完美运行,但当然不再接收我的 UDP 广播消息。
经过进一步挖掘,我自己找到了解决方案。
Module fails to restart because of transient network error
这篇文章,虽然我已经读过很多遍了,但还是提示 /etc/hosts 文件有问题。果然,我的设备 (127.0.1.1) 的条目有误,我一定是在某个地方更改了我的设备的主机名,而此更改未反映在主机文件中。
自那次更改以来,我让 AMQP 和 MQTT 都可以工作,但是两者都使用 edgeHub 容器 运行 在主机模式下。在桥接模式下,我 运行 遇到了一个新问题,其中 docker-proxy 没有绑定导出的端口(这导致了一个新的 'Connection refused' 异常)。为什么......
仍然是个谜