0
votes

as expected of a beginner IoT Edge developer, I started following the Microsoft tutorial on how to deploy custom code to an IoT Edge server Tutorial: Develop a C# IoT Edge module for Linux devices.

I was able to install Ubuntu 18.04 server on an industrial intel PC, download and configure the edgeHub and edgeAgent modules, create a free Azure and Docker Hub account, etc. Even the example code from the tutorial was succesfully built and deployed to my target device and all seemed well, all modules were talking to each other, etc.

Once I got the demo code to run, I started modifying the code to better suit my end goal, which is to capture network traffic generated by our industrial equipment, which uses UDP multicast/broadcast. Apparently I needed to configure my docker image to run in 'host' networking mode. And indeed, as soon as I told the azure edgeAgent to start the module container in host mode, the UDP packets started to come in.

HOWEVER, now my sample module is no longer able to connect to the iot hub and I'm at a complete loss. I've tried to run the edgeHub container in host mode as well, this doesn't seem to make any difference. The exact error I'm getting as a result of the ModuleClient.OpenAsync method is:

    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

The code used for connecting:

ITransportSettings[] settings = { mqttSetting };
ModuleClient ioTHubModuleClient = await ModuleClient.CreateFromEnvironmentAsync(settings);
await ioTHubModuleClient.OpenAsync();
Console.WriteLine("IoT Hub module client initialized.");

So apparently the ModuleClient can't find the edgeHub anymore (Name or service not known?). I understood that the 'CreateFromEnvironmentAsync' uses environment variables set by the edgeAgent, but which ones? Anyone have any idea why this is? Even pointers in the right direction to start debugging this issue are greatly appreciated!

If I change my docker containers back to 'bridge' networking, the OpenAsync method works perfectly, but my UDP broadcast messages are no longer received, of course.

1

1 Answers

2
votes

After some more digging around, I found the solution myself.

Module fails to restart because of transient network error

This article, although I had read it already multiple times, suggested that something was wrong with the /etc/hosts file. Sure enough, the entry for my device (127.0.1.1) was faulty, somewhere along the way I must have changed the hostname of my device and this change wasn't reflected in the hosts file.

Since that change, I got both AMQP and MQTT to work, however both with the edgeHub container also running in host mode. In bridge mode I ran across a new issue where the docker-proxy didn't bind the exported ports (which resulted in a new 'Connection refused' exception). It remains a mystery why...