ROS2 connectivity across Docker containers via Host Driver
I'm having some issues connecting ROS2 nodes across Docker containers via the host driver. Reading through some relevant RTI documentation: How to use RTI Connext DDS to Communicate Across Docker Containers Using the Host Driver
I've concluded my main issue stems from this:
As we mentioned before, the host Docker driver mode could affect this generation process as follows:
All the containers in host driver mode will have the same IP address; therefore, they will have the same Host ID.
Due to the way process IDs are generated, two applications in two containers could have the same Process ID; therefore, they could have the same Application ID. In this case, RTI Connext DDS will interpret that both applications are in the same machine and will try to communicate using shared memory.
Suggested workarounds include; enabling communication using shared memory among container by passing the --ipc=host
argument: Communicate two Docker containers using RTI Connext DDS and shared memory.
Among the rwm implementations I've tested, only rmw_opensplice_cpp
seems to be working, however I suspect rtps_auto_id_kind
has been set to RTPS_AUTO_ID_FROM_UUID
for opensplice, given the participant GUIDs seems randomized; not confirmed though as I didn't look at it too closely. Controlling How the GUID is Set (rtps_auto_id_kind)
Here is a minimal example to demonstrate the issue. You'll notice that the listener will print the chatter messages from the talker if neither docker-compose service is set to use the host network driver, or only one is, but not such when both are. Even then, enabling IPC does not seem to resolve anything here.
mkdir ros2_ipc && cd ros2_ipc
touch Dockerfile
touch docker-compose.yml
docker-compose up
Dockerfile:
FROM ros:bouncy
ENV RTI_NC_LICENSE_ACCEPTED yes
RUN apt-get update && apt-get install -y \
ros-$ROS2_DISTRO-rmw-connext-cpp \
ros-$ROS2_DISTRO-rmw-opensplice-cpp && \
rm -rf /var/lib/apt/lists/*
docker-compose.yml
version: '3'
services:
talker:
build: .
environment:
- "ROS_DOMAIN_ID=0"
# - "RMW_IMPLEMENTATION=rmw_connext_cpp"
# - "RMW_IMPLEMENTATION=rmw_fastrtps_cpp"
# - "RMW_IMPLEMENTATION=rmw_opensplice_cpp"
# network_mode: "host"
# ipc: host
command: ros2 run demo_nodes_cpp talker
listener:
build: .
environment:
- "ROS_DOMAIN_ID=0"
# - "RMW_IMPLEMENTATION=rmw_connext_cpp"
# - "RMW_IMPLEMENTATION=rmw_fastrtps_cpp"
# - "RMW_IMPLEMENTATION=rmw_opensplice_cpp"
# network_mode: "host"
# ipc: host
command: ros2 run demo_nodes_cpp listener
TL;DR Anyone know how to easily set a different RTPS App ID for each DDS participant to uniquely identify them across containers, or if I can set rtps_host_id QoS parameter via ROS2 while remaining vendor agnostic?
It has come to my attention that the use of host driver for both nodes works otherwise when security is enabled for fastrtps and connext: https://github.com/ruffsl/ros2_docker...
Docker network architecture covers all network scenarios required for successful communication at the local, remote or cluster level.