Azure / iot-edge-v1

Azure IoT Edge
http://azure.github.io/iot-edge/
Other
524 stars 258 forks source link

[V2] Container create options for ports not used when starting container #561

Open Strandfelt opened 6 years ago

Strandfelt commented 6 years ago

Hi,

I am working on a module that needs to connect to my local machine through TCP port 2222. However, I am having some difficulties creating the ports configuration for my module "customtcpmodule".

In Azure Portal, I have set the following Container Create Options for my module:

{
  "HostConfig": {
    "PortBindings": {
      "2222/tcp": [
        {
          "HostPort": "2222"
        }
      ]
    }
  }
}

However, when I run docker container ls, I get this (notice no port options defined for my module):

CONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS              PORTS                                          NAMES
9832ab40202f        custom.azurecr.io/customtcpmodule:0.0.2-amd64         "dotnet Custom.TcpMo…"   25 minutes ago      Up 25 minutes                                                      customTcpModule
9c9f9fbd7ffb        microsoft/azureiotedge-hub:1.0-preview                "scripts/linux/start…"   2 hours ago         Up 38 minutes       0.0.0.0:443->443/tcp, 0.0.0.0:8883->8883/tcp   edgeHub
59a0ee3bd2fe        microsoft/azureiotedge-agent:1.0-preview              "/usr/bin/dotnet Mic…"   2 hours ago         Up 38 minutes                                                      edgeAgent

If I check the log for the edgeAgent using docker logs -f edgeAgent, I see the following:

2018-03-28 11:30:31.768 +00:00 [INF] - Executing command: "docker rm customTcpModule && docker create --name customTcpModule custom.azurecr.io/customtcpmodule:0.0.2-amd64"

When I lookup the module details on the Azure portal, I see that the container create options have been successfully set on the module.

I am running runtime iotedgectl 1.0.0rc21.

Am I missing something or is this an issue with the runtime or edgeAgent?

darobs commented 6 years ago

Hello @Strandfelt

The most likely culprit is the Dockerfile for your module. In the edgeHub module, we set up to HostConfig just like that, but we also expose the ports in the Dockerfile, like this:

# Expose MQTT and HTTPS ports
EXPOSE 8883/tcp
EXPOSE 443/tcp
Strandfelt commented 6 years ago

Actually, I might have been mistaken about the Docker networking and ambiguous in my wording.

I don't want to expose ports in my container to my host. I would like to expose ports on my host to my container, such that my container can connect to port 2222/tcp on my host machine. I guess that's the opposite direction of what you are suggesting me? Apologies for the misunderstanding.

darobs commented 6 years ago

Ah - then you probably don't want to set the HostConfig's PortBindings like that. That's for the mapping of container ports to host ports.

So, there is a caveat to how modules are created by default: We put the module in a network with the edgeHub, so that we can easily communicate module to module. To access the host's ports, you either need to connect to "localhost" or change the HostConfig's NetworkMode to "host". There's a caveat with that as well... setting the NetworkMode to "host" will mean directly communicating to other modules is lost.

We're tracking this in a PBI to see if we can improve this experience.

Strandfelt commented 6 years ago

@darobs So if I have a use case where I have some server (e.g. OPC UA) running as a module on the edgeHub network, and another server running on the host or in another container outside the edge runtime, I might be better off separating this into distinct modules?

If we assume all servers are OPC UA and I am using the OPC edge publisher, it would make sense to have one OPC publisher module running default Edge module container options to monitor OPC Edge modules and another OPC publisher (also deployed as an Edge module) with the network mode set to host for OPC servers running on the host?

Thanks a lot for your help so far.

MikeWise2718 commented 6 years ago

I worked around this by using the external ip address of the local host. Ugly, but it worked.

davihar commented 6 years ago

You are missing setting the ExposedPorts property. This syntax works:

{ "ExposedPorts": { "5672/tcp": {} }, "HostConfig": { "PortBindings": { "5672/tcp": [ { "HostPort": "5672" } ] } } }