how to bind specific interface in docker container? - docker

I have a program which has two mandatory arguments -d and -t, both of them mean that bind to a specific network device (IP address), i.e.: ./myprogram -d 172.17.0.2 -t 172.17.0.3, and they can't be the same.
Now, I need to run this program in a docker container, how could I config the container so that I can run this program inside the container and for peer endpoint it is the same as I run this program in the host?
Thanks!

if your container needs to access your network device, you need to share the network devices
docker run --net-host...
extract from
docs.docker.com/engine/reference/run/#ipc-settings---ipc
Network: host With the network set to host a container will share the host’s network stack and all interfaces from the host will be available to the container.
an example, extract from this image using nethogs for network monitoring
https://hub.docker.com/r/k3ck3c/nethogs/
docker run -it --net=host -- --rm k3ck3c/nethogs

Related

Cannot connect interface to Docker container

I am trying to connect and run a device (LiDAR) through Docker container since it needs Ubuntu 16 while my computer is Ubunutu 20.
I got the device to ping inside the docker container, but it is not recognised when I try to use it.
What I did:
Made Dockerfile with requirements (Added EXPOSE to expose all ports)
Built docker image using:
docker build -t testLidar
I then made a container using
docker run -d -P --name test_Lidar (imagename)
Then
docker exec -t test_Lidar (device_ip) works
I am able to ping my LiDAR IP inside the container, but when I do ip a I cannot see the interfaces connected to my machine.
Been stuck on this for 3 days, any suggestions?
Note: I have done the exact same steps but on an Ubuntu 16 machine. The only change was the docker run command had --net host instead of -P tag and my device worked perfectly. I feel like this is the root of my problem.
Use --net host flag with docker run to attach the container to your host's networking stack and make it available in for other hosts in your network.
When you use --net host, you actually attach the container to your host's networking stack. By default, containers are attached to the default network of type bridge and can communicate with each other. You can then reach them only from your host using its ip addresses typically in subnet 172.17.0.0/16.
Using -P actually binds exposed ports from a container with randomly selected free ports on your host. It should be used for exposing network services (eg. web server with port 80), but not for ICMP ping.

How to ping Docker-Container inside host network?

I'm working with Docker containers for a while now but can't figure out how to ping docker containers which are part of my host network.
So until now I created my containers specifing the name and networks flags like described in many tutorials like: https://www.digitalocean.com/community/questions/how-to-ping-docker-container-from-another-container-by-name
Where I am able to create a network and afterwards run my containers in these networks for example like:
docker run -d --name web1 -n testnetwork
docker run -d --name web2 -n testnetwork
That would enable me to ping my containers from each other with:
docker exec -it web1 bash # enter container
ping web2 #ping second container
Now I have to use a given application which only runs in the "host" network for now. To access this container from my other containers they have to be in the same network (== "host").
But It seems like I cant ping my containers from each other anymore. I'm also unable to ping my containers from my host machine using their name.
Did I overlooked something?
Any help would be appreciated!
Best regards
If you set --network host, you basically disable Docker's entire networking stack. Among other things, that disables normal inter-container communications: if you're using host networking you can't call another container by its name. Host networking is very rarely necessary (and doesn't work well on some host platforms); the first thing I'd look at is whether you can switch back to standard (bridged) networking.
If you do run a container with --network host, it's indistinguishable from other processes running on that host. That means you can't directly send ICMP packets to it, any more than you can ping(1) your ssh daemon or Web browser. You need to connect to the container using the host's IP address or DNS name, even from other containers on the same host. From inside of a Docker container, how do I connect to the localhost of the machine? discusses several ways to do this.
(I don't think you can customize the behavior of Docker or Linux when a container receives an ICMP ECHO packet; ping(1) a container doesn't seem that useful.)

Docker network bridge

I'm trying to run multiple containers with the same ports on docker.
For this, I have created a network in brigde mode and specified a subnet.
docker network create -d --subnet 192.168.99.0/24 mynetwork
Then connected the docker containers to it with a static IP.
docker run -i -t -d -p 2377:2377 -p 7946:7946 -p 4789:4789-name container image
docker network connect --ip 192.168.99.98 mynetwork container
I did this with three containers (using different IP's), after starting the second one I got:
Error response from daemon: driver failed programming external connectivity on endpoint container(...): Bind for 0.0.0.0:7946 failed: port is already allocated
As far as I'm concerned, I should not be getting this error, due to bridge mode.
The docker run -p option allocates a port on the host system; those are shared across all containers, independently of what Docker-private network they’re using. These also will conflict with non-Docker processes running on the host.
If your goal is just to be able to communicate between containers on the same network, you don’t need a -p option at all. They can use each others’ --name and the port the service inside the container is listening on to connect.
If you’re trying to run multiple Docker container stacks at the same time, you need to decide which specific instance port 2377 on your host will route to, and change the other container’ -p option.
Specifically setting the Docker-internal private IP addresses (or worrying about them at all) is almost never necessary. I’d delete those --subnet and --ip options. To communicate between containers, put them on the same network as described above; from outside you need a (unique) -p option.

How Docker Container can access each other

In my docker-compose , i have 2 containers .
How to make this 2 containers access each other as they installed in one host without containers .
How they can see each other and their file systems
To allow inter-container communication create a common bridge network, and put both containers into the same network. The build phase assuming nothing needs to "talk" to each other does not need the --network switch.
docker network create jointops
docker build --network jointops -t srv1 /srv1
docker build --network jointops -t srv2 /srv2
docker run --network jointops -d -t srv1
docker run --network jointops -d -t srv2
To check both machines are on the same network now issue the command
docker network inspect jointops
You should see both machines having an IP Allocation.
Ok... so how do they communicate ?
The bridge network - jointops by default will perform dns-resolution
So if srv1 has something like
curl -c http://srv2/bla/bla/bla
This will be resolved correctly.
Regarding Shared Data access ..
Do not run 2 apps in 1 container
Instead
create a docker volume
run 2 separate containers
each container can connect to the same volume
See here for inter-container communication. Each container encapsulates its contents, so use ports for communication instead of trying to just openly expose the full filesystem of one container to another.
If both applications need access to the same filesystem, consider running both in the same container. That is supported.

How to make Docker container accessible to other network machines through IP?

I need to create some docker containers that must be accessed by other computers at the same network.
Problem is that when I create the container, Docker gets IP addresses valid only within the host machine.
I already took a look at Docker documentation (Networking) but nothing has worked.
If I run ifconfig on my machine my IP address is 172.21.46.149. When I go inside the container (Ubuntu) and run ifconfig the IP address is 172.17.0.2. I need Docker to get, for example, 172.21.46.150.
How can I do it?
You have to create a bridge on your host and assign that bridge to the container. This may help you: https://jpetazzo.github.io/2013/10/16/configure-docker-bridge-network/
Multi-host access involves an overlay network with service discovery.
See docker/networking:
An overlay network requires a key-value store. The store maintains information about the network state which includes discovery, networks, endpoints, IP Addresses, and more.
The Docker Engine currently supports Consul, etcd, ZooKeeper (Distributed store), and BoltDB (Local store) key-value store stores.
This example uses Consul.
If if your your nodes (the other computers across the same network) runs their docker daemon with a reference to that key-value store, they will be able to communicate with containers from other nodes.
DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store=consul://<NODE-0-PRIVATE-IP>:8500/network --cluster-advertise=eth0:2375"
You just need to create an overlay network:
docker network create -d overlay --subnet=10.10.10.0/24 RED
(it will be available in all computers because of the key-value store)
And run your containers on that network:
docker run -itd --name container1 --net RED busybox
Docker containers can easily be accessed by other network node when a container:port is published through a host:port.
This is done using the -p docker-run option. Here is the sum-up of the man-page ($man docker-run gives more details and example that I won't copy/paste):
-p, --publish=[]
Publish a container's port, or range of ports, to the host.
See the doc online. This question/answer could be interesting to read too.
Basically:
docker run -it --rm -p 8085:8080 my_netcat nc -l -p 8080
Would allow LAN nodes to connect to the docker-host-ip:8085 and discuss with the netcat command.

Resources