Confused about container network isolation with Docker - docker

I have Docker running on a couple of Ubuntu 18.04 vms and also on a Synology DS218+. There is inconsistent behaviour between the two with regards to the ability for containers to access other hosts on the local network. I am confused as to what exactly is happening here:
My method of testing this is to launch an interactive shell with bash into a container that has ping installed. From that I can test connectivity to other containers and to the docker hosts. The containers are using default bridge networks. I understand this should mean that they can only communicate with other containers that are on the same bridge network.
On the Synology, when I bash into a container, I am not able to ping the host that the machine is running on. That seems to be desired behaviour. However, if I try to ping other machines on the host network, the container receives a response. This shouldn't happen as the default bridge network is supposed to be isolated from the host network. I tried taking down all containers, stopping the docker daemon, flushing iptables and bring everything back up again. Same result.
On the Ubuntu hosts, I can not only ping other machines on the host network, but the host that the container is running on.
Is there something I am missing here?

Related

Sharing VirtualBox VM and Docker Container network

I have an headless server with VirtualBox. It run multiple virtual machines. One of them is a web proxy. It redirect external access to the right VM in function of the subdomain. Those VMs are communicating between them with internal network (intnet).
I would like to add some docker container to this configuration. How could I successfully create a network shared between my docker containers and this proxy VM ?
I tried to create a bridge network with docker docker network create my_net and then connect the VM with a additional network card in 'bridged' mode.
With this config ping works but not the actual connection. It isn't impossible to display the web page into a browser.
Am I missing some configuration here ? Also, is it a good practice to connect one VM to a docker network ?
Run the containers on one of the VMs. Use a totally normal Docker setup here: create a network for inter-container communication but don't configure it, and completely ignore the container-private network details and IP addresses.
When you use the docker run -p option, that will publish a container's port on its VM's network interface(s). From that point, other VMs can call the published port using that VM's IP address, just as if it were a non-container process running on the VM. Conversely, containers should be able to make outbound calls to the other VMs without special setup.

How to have communication between Docker Containers and A Linux VM on my windows Host

I have a Hyper-V machine and Docker running a few containers. I need them to be able to ping each other. Is there a way I can do this. Ive tried putting them on the same nat but im not sure I even accomplished that. There both on my windows host and i spin up the docker containers using a yml file.

How to access docker container in a custom network from another docker container running with host network

My program is consisting of a network of ROS1 and ROS2 nodes, which are software that work with a publish/subscribe way of communication.
Assume there is 4 nodes running inside a custom network: onboard_network.
Those 4 nodes (ROS1) can only communicate together, therefore we have a bridge node (ROS1 & ROS2) that needs to be sitting on the edge on both onboard_network and host network. The reason why we need the host network is because the host is inside a VPN (Zerotier). Inside the VPN we have also our server (ROS2).
We also need the bride node to work with host network because ROS2 work with some multicast stuff that works only on host mode.
So basically, I want a docker compose file running 4 containers inside an onboard_network & a container running inside the host network. The last container needs to be seen from the containers in the onboard_network and being able to see them too. How could I do it ? Is it even possible ?
If you're running a container on the host network, its network setup is identical to a non-container process running on the host.
A container can't be set to use both host networking and Docker networking.
That means, for your network_mode: host container, it can call other containers using localhost as a hostname and their published ports: (because its network is the host's network). For your bridge-network containers, they can call the host-network container using the special hostname host.docker.internal on MacOS or Windows hosts, or on Linux they need to find some reachable IP address (this is discussed further in From inside of a Docker container, how do I connect to the localhost of the machine?.

How to expose the docker container ip to the external network?

i want to expose the container ip to the external network where the host is running so that i can directly ping the docker container ip from an external machine.
If i ping the docker container ip from the external machine where the machine hosting the docker and the machine from which i am pinging are in the same network i need to get the response from these machines
Pinging the container's IP (i.e. the IP it shows when you look at docker inspect [CONTAINER]) from another machine does not work. However, the container is reachable via the public IP of its host.
In addition to Borja's answer, you can expose the ports of Docker containers by adding -p [HOST_PORT]:[CONTAINER_PORT] to your docker run command.
E.g. if you want to reach a web server in a Docker container from another machine, you can start it with docker run -d -p 80:80 httpd:alpine. The container's port 80 is then reachable via the host's port 80. Other machines on the same network will then also be able to reach the webserver in this container (depending on Firewall settings etc. of course...)
Since you tagged this as kubernetes:
You cannot directly send packets to individual Docker containers. You need to send them to somewhere else that’s able to route them. In the case of plain Docker, you need to use the docker run -p option to publish a port to the host, and then containers will be reachable via the published port via the host’s IP address or DNS name. In a Kubernetes context, you need to set up a Service that’s able to route traffic to the Pod (or Pods) that are running your container, and you ultimately reach containers via that Service.
The container-internal IP addresses are essentially useless in many contexts. (They cannot be reached from off-host at all; in some environments you can’t even reach them from outside of Docker on the same host.) There are other mechanisms you can use to reach containers (docker run -p from outside Docker, inter-container DNS from within Docker) and you never need to look up these IP addresses at all.
Your question places a heavy emphasis on ping(1). This is a very-low-level debugging tool that uses a network protocol called ICMP. If sending packets using ICMP is actually core to your workflow, you will have difficulty running it in Docker or Kubernetes. I suspect you aren’t actually. Don’t worry so much about being able to directly ping containers; use higher-level tools like curl(1) if you need to verify that a request is reaching its container.
It's pretty easy actually, assuming you have control over the routing tables of your external devices (either directly, or via your LAN's gateway/router). Assuming your containers are using a bridge network of 172.17.0.0/16, you add a static entry for the 172.17.0.0/16 network, with your Docker physical LAN IP as the gateway. You might need to also allow this forwarding in your Docker OS firewall configuration.
After that, you should be able to connect to your docker container using its bridge address (172.17.0.2 for example). Note however that it will likely not respond to pings, due to the container's firewall.
If you're content to access your container using only the bridge IP (and never again use your Docker host IP with the mapped-port), you can remove port mapping from the container entirely.
You need to create a new bridge docker network and attach the container to this network. You should be able to connect by this way.
docker network create -d bridge my-new-bridge-network
or
docker network create --driver=bridge --subnet=192.168.0.0/16 my-new-bridge-network
connect:
docker network connect my-new-bridge-network container1
or
docker network connect --ip 192.168.0.10/16 my-new-bridge-network container-name
If the problem persist, just reload docker daemon, restart the service. Is a known issue.

Access devices on local network when running Docker for Mac

I have some smart wifi devices on my network I can see from a script on my Mac. But running the same script from within a Docker container those devices are not visible.
I assume this is related to Docker for Mac's inability to connect to the host's network using --network host or network_mode: host. I also assume this issue wouldn't exist on a Linux machine but I don't have one to test on.
What is the workaround?
Edit:
Confirmed this worked fine when running inside an Ubuntu virtualbox, but I'd really not have to develop inside it.
If you start the container with network option as host, the container will share the network stack of the host. Thus any device reachable from you host should be reachable by the container.
docker run --network host ...
Adding containers to a network would allow them to communicate with each other but if you want to access other services running on host then host.docker.internal (from 18.03+). I had to do the same in a mac mini setup to access external service.
[https://docs.docker.com/docker-for-mac/networking/]
If you have to access a service on another host then you can setup an nginx server on the docker host and a proxy pass rule to direct it to the remote service.

Resources