ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
5

Exposing ROS Containers to Host Machine

asked 2016-03-05 10:45:13 -0600

ruffsl gravatar image

I've been corresponding with a few people interested in exposing containers (on a docker network) running ros nodes to the host machine. I believe I've stumbled across a viable solution using resolvable. However, I am uncertain on exactly why it works:

  • Is this specific to a recent releases of Docker?
  • Is this a result of adding DNS entries for the Docker bridge interface address?
  • Is something about passive FTP failing without it?

Here is the gist with my complete description of the proposed solution and a small bit of exploration into the issue: gist.github.com/ruffsl/4a24c26a1aa2cc733c64

Since the introduction of docker networking in v1.7, with the advent of libnetwork, I've not had an issue rostopic-echo'ing between containers within the same defined docker network. The issues I did have were avoiding the need to hard-code IP's into environment variables, which is why I happened to quote docker's internal DNS improvement in v1.10 for host names.

Rostopic-echo'ing from outside that network was an entirely different matter, and up until now I hadn't thought if it easally feasible, short-of exposing the network via custom a network bridge docker-plugin or some dummy vpn container. Perhaps the solution I've found using resolvable is not v1.10 specific, but without the resolvable project's gateway resolver, I observed the same behavior described in this status document in the references, i.e:

  1. one could ping the containers from the host
  2. one could ping the host back from the containers
  3. one could set the ROS_MASTER_URI to point to the "master container"
  4. one could list rostopics published by the master from host
  5. but yet, one could not successfully receive subscribe topics from host

I've extended my gist example to include some of my experimentation that lead me to the my thought process on why I think it has to do with Resolvable's provision of a DNS entry for the Docker bridge interface. From my brief poking and prodding using netcat, I don't think erroneous port remapping is the root of all evil here. As I'm not exposing or reassigning any ports as far as I'm aware of. Yet I certainly could be proven wrong and would find any evidence quite invaluable. Please let me know how if anyone can correct or dispel this hypothesis.

I thought that this deeper question on why this works (be it a corrected extension for passive FTP introduced by one of my changes) would be good question to ask of the larger ROS community, members with networking experience beyond my years.

edit retag flag offensive close merge delete

Comments

3

You don't mention it, but have you tried setting ROS_IP on the sessions in your container? Set only that, notROS_HOSTNAME, and make sure you have ROS_MASTER_URI set to an IP as well. I would expect that with proper IP routes between the docker net and your host pc, it would work.

gvdhoorn gravatar image gvdhoorn  ( 2016-03-05 14:50:16 -0600 )edit

2 Answers

Sort by » oldest newest most voted
4

answered 2016-03-05 19:14:13 -0600

ruffsl gravatar image

updated 2016-03-05 19:20:33 -0600

Verified the issues was really a silly resolving issue while posting replying to a github issue asking the resolvable devs the same thing. Just now seeing @gvdhoorn comment reaffirms my thoughts.

  • What I had considered was the domain resolution within the project network, making sure the containers could resolve the [master,talker,listener] host names between themselves by setting the ROS_HOSTNAME environmental variable.
  • What I didn't consider was that this was that same domain name used used in generating the publisher's URI not only need to be resolvable by the ros master node, but as well as any subscriber (i.e. the host). Looking back at the wiki page, this was made clear. I just forgot this relationship pertains to more that just the just (master, publisher), (master, subscriber), but also (subscriber, publisher) after I switched from using domain names to IP address.
  • There must be complete, bi-directional connectivity between all pairs of machines, on all ports.
  • Each machine must advertise itself by a name that all other machines can resolve..

If instead, I where to use a more rigid setup, I can avoid the need of providing a DNS server for bridge network by setting ROS_IP; this of course comes at the cost of losing a more flexible domain name assignment.

version: '2'

services:
  master:
    build: .
    environment:
      - "ROS_IP=172.19.0.3"
    command: roscore

  talker:
    build: .
    environment:
      - "ROS_IP=172.19.0.4"
      - "ROS_MASTER_URI=http://master:11311"
    command: rosrun roscpp_tutorials talker

  listener:
    build: .
    environment:
      - "ROS_IP=172.19.0.2"
      - "ROS_MASTER_URI=http://master:11311"
    command: rosrun roscpp_tutorials listener

On the host:

export ROS_IP=172.19.0.1
export ROS_MASTER_URI=http://172.19.0.3:11311
$ rostopic list
/chatter
/rosout
/rosout_agg
$ rostopic echo /chatter 
data: hello world 84
---
data: hello world 85
---
data: hello world 86
...

Note that the compose file above is quite fragile, as I'm assuming the containers will be assigned the same IP as before on my docker engine, such that ROS_IP remains correctly corresponding. Specify a custom IPAM config for the project's default network (setting each services IP) would be a slight improvement, yet still rigid and possibly conflicting with other networks.

Using a DNS entry for the Docker bridge interface however is so much simpler, I'll probably keep to that method.

edit flag offensive delete link more

Comments

1

Using a DNS entry for the Docker bridge interface however is so much simpler [..]

And a lot more flexible. Using hostnames is obviously fine, as long as you have a DNS server reachable by all your nodes/machines.

gvdhoorn gravatar image gvdhoorn  ( 2016-03-06 00:34:25 -0600 )edit

Also (nitpicking):

Using a DNS entry for the Docker bridge interface however is so much simpler [..]

I assume you mean:DNS entries for the nics in all the involved containers? The bridge is just relaying traffic, afaik.

gvdhoorn gravatar image gvdhoorn  ( 2016-03-06 00:36:22 -0600 )edit

Yep, the resovlable container is just servicing a nameserver for only the registered containers attached to the same docker network you attach it to, not necessarily everything on all the bridges.

ruffsl gravatar image ruffsl  ( 2016-03-06 01:04:20 -0600 )edit

When running my containers I often have my nodes start up before my master and end up never registering. What's a good way of making sure they wait until the master node is online?

waspinator gravatar image waspinator  ( 2017-02-03 19:16:06 -0600 )edit

@waspinator: if you're using Docker Compose, you could use depends_on (see: Controlling startup order in Compose).

gvdhoorn gravatar image gvdhoorn  ( 2017-02-04 14:00:38 -0600 )edit

@gvdhoorn, Compose will not wait until a container is “ready”. Outside of docker, the node seems to wait for master, but it seems that in docker, it just stops. Not sure if the right answer is to specify restart: always?

waspinator gravatar image waspinator  ( 2017-02-04 16:01:28 -0600 )edit

re: won't wait: no, that is also mentioned in the docs I linked. And a strategy to deal with that is also discussed.

re: it just stops: are you sure your network config is ok? I get that behaviour if there is no bi-directional communication possible between containers (ROS_IP, etc).

gvdhoorn gravatar image gvdhoorn  ( 2017-02-05 03:27:13 -0600 )edit
0

answered 2017-02-22 03:25:27 -0600

HI, I''ve been stumbled by how to connect a ROS host computer with another computer's Docker ros container. The two computers are located in the same network segment because I used a router. When i ran roscore command in ROS host computer , and I could get output infomation when I ran rostopic list in another Docker host Computer. However, if chose to use docker ros container, it failed to connect ROS host Computer even if set the port mapping in Docker host computer. DO you know how to figure out? or do you have any othe idea? thanks!

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2016-03-05 10:45:13 -0600

Seen: 9,358 times

Last updated: Mar 05 '16