-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Random ports and Dockerized Ignition #166
Comments
The network drivers used by docker unfortunately never went along well with any robotic middleware (ROS, YARP, etc). I'm not surprised if also Ignition Gazebo shares the same limitations. Without removing the network isolation, the only possible workaround I'm aware of is opening a range of ports large enough and hoping that no ports are allocated outside that range. With that being said, in my team we're running Ignition Gazebo in containers based on Ubuntu 18:04 for a while now (and since few days also on 20.04), and with host network we do not have experienced any GUI problem. If for you the network host modality is not a strict blocker, I'd suggest to go along with it and perhaps solve the GUI problems you faced. I know that few groups use a VPN as workaround, allowing to scale also to bigger cluster e.g. in Kubernetes. If you want to maintain the network isolation I fear this is the only workaround, that however centralizes all the traffic between the nodes in a single point that could become a bottleneck. |
Since
We could also try restricting the range of permitted ports to, let's say, 100. That's a more manageable number and would make exposing them easier.
That's interesting to hear. Adding the
For each I'm curious to see what your Docker configuration is, and if it's not different from the official one, our problem might be specific to our system. |
An implementation to restrict the range would look something like this: void bindSocketToPortInRange(zmq::socket_t& _socket, const std::string& _ip, int _minPort, int _maxPort)
{
int port = _minPort;
while (true)
{
try
{
auto fullAddress = _ip + ":" + std::to_string(port);
_socket.bind(fullAddress.c_str());
return;
}
catch (...)
{
port++;
if (port > _maxPort)
{
throw std::runtime_error("No available ports in specified range.");
}
continue;
}
}
} We can add this feature via an environment variable |
Yes, I'm not saying that they do not work. The reality is that all of them use a dynamic allocation of ports and it fights with the default network isolation of docker. Opening wide ports range is a workaround with limitations (moby/moby#14288).
I'm not using the official docker images and the error you posted rings a bell even though I'm not sure where I stumbled upon it in the past. Could you try to use the
I let the developers to chime in here, I'm not an expert of the code of |
Before considering further changes in the code I'd like to verify that there's an actual issue:
https://ignitionrobotics.org/api/transport/9.0/relay.html It looks like a simplified case of what you're trying to achieve and I remember being able to communicate using Ignition Transport with a Docker container. Do you mind to verify these two aspects? |
Yes, I'm taking care of this. Just to be clear, I'm able to communicate with the container by using the option
I tried that tutorial without success. I'm somewhat skeptical that the tutorial should work based on:
https://docs.docker.com/config/containers/container-networking/#published-ports Are you positive that it is working for you? |
Furthermore, the Docker network bridge (the configuration used by default) does not support multicast, so discovery won't work either. It seems to me that the only way to connect to inside the container while preserving network isolation (not using |
FYI I found the bell: moby/moby#38442 :) I'm still using the workaround, not sure if it's still necessary (from your error, I suppose it is). |
Thanks, Diego. I ended up arriving at the same solution. Nevertheless, I will keep this issue open so we can clarify some of the Docker networking issues. |
When |
There's a use-case in which we want to have an Ignition Gazebo instance running inside a Docker container and communicate with the host machine through the
ignition-transport
layer.One of the problems is that the ports used by
NodeShared
are randomly chosen during construction. This makes it difficult to expose the ports to the host machine during the container startup, since these aren't known a priori.Questions
Note:
docker run
has the option--network=host
that will mount the host network stack on the container. While this approach solves the problem above, we would prefer to avoid it (it also adds other problems when running the GUI).The text was updated successfully, but these errors were encountered: