docker userdefined network - no connection to the outside world - networking

I try to expose a docker container to the outside world (well, to be specific just in my internal network - 10.0.0.0/24) with a static ip adress. In my example the container should have the IP address 10.0.0.200.
Docker version is 1.10.3.
Therefore i created a userdefined network:
docker network create --subnet 10.0.0.0/24 --gateway 10.0.0.254 dn in bridge mode.
Then i created a container and attached it to the container.
docker run -d \
--name testhost \
-it \
-h testhost \
--net dn \
--ip 10.0.0.200 \
-p 8080:8080 \
some image
The container has the correct ip and gw assigned (10.0.0.200, 10.0.0.254 - which is also the ip from the docker created bridge interface) but no communication from the container to the outside world nor from the outside to the container is possible. only thing that works is nslookup but tbh i dont know why this is working.
From another host in the network i can ping the bridge interface which was created through the docker network create command.
A second container connected the the dn network can ping my first container. so communication inside the network seems fine.
As in the docker [network documentation][1]
[1]: https://docs.docker.com/engine/userguide/networking/#a-bridge-network "docker network docu" (second picture in bridge network) it should be possible
It seems that im missing some step or config. Any advice is appreciated, thank you.

Related

How to expose ports only within the docker network?

I have a few apps running in a Docker network with their ports (3000,4200, etc) exposed. I also have an nginx container running within the same Docker network which hosts these apps on port 80 with different domain names (site1.com, site2.com).
But right now if I go directly to the ports the apps are running on (localhost:3000) I can access them that way too.
How do I expose those ports only to the nginx container and not the host system?
But right now if I go directly to the ports the apps are running on
(localhost:3000) I can access them that way too.
Thats because you are using -p aka --publish command in your docker run
Explanation:
If you want to expose ports between containers only, Do Not use -p or --publish just put them on the same docker network.
Example:
Lets create a new user-defined network:
sudo docker network create appnet
Lets create nginx container for reverse proxy, It should be available to outside world so we use publish.
sudo docker run --name nginx -d --network appnet nginx
Now put your apps in the same network but do not expose ports.
sudo docker run --name app1 -d --network appnet <app image name/id>
You have to use Docker networks.
The default network is shared with host, thus accessible from localhost. You can either configure Docker, creating a network manually, or let tools like docker-compose or Kubernetes to do it for you.

Unable to connect to container using host network from host

I set up two container. Using --net=host both. Container A and B can access each other, also can ping host. But host can't connect to container.
It is very strange that using host network but got different IP address in host and containers.
My host ip addr is 192.168.1.106
Containers' ip addr is 192.168.65.2
My command to run the container are
docker run -ti -d --name fastdfs_tracker --net=host ewnit/fastdfs sh tracker.sh
docker run -ti --name fastdfs_storage --net=host -e TRACKER_IP=192.168.65.2:22122 ewnit/fastdfs sh storage.sh
fastdfs_storage using TRACKER_IP to get connect with fastdfs_tracker, and it works well.
I've got the answer. Host networking does not work as expected in Docker for Mac at present.

How do I find the network ip using docker and travis?

In my local setup, I can run ...
docker run --name myapp -e HOST=$(docker-machine ip default) --user root myapp
... and then use $HOST to connect to any other container (e.g. one running mongodb).
However, in Travis, docker-machine does not exist. Thus, I cannot simply put that line in my .travis.yml.
How do I get the network IP?
The flag --link adds an entry to /etc/hosts with the ip address of the specified running container
docker run --name myapp --link mongodb:mongodb myapp
However please note that:
The default docker0 bridge network supports the use of port mapping
and docker run --link to allow communications between containers in
the docker0 network. These techniques are cumbersome to set up and
prone to error. While they are still available to you as techniques,
it is better to avoid them and define your own bridge networks
instead.
Another option is using the flag --add-host if you want to add a known ip address
docker run --name myapp --add-host mongodb:10.10.10.1 myapp
Option 2
Create a network
docker network create --subnet=172.18.0.0/16 mynet123
Run mongodb container assigning an static ip
docker run --network mynet123 --ip 172.18.0.22 -d mongodb
Add that ip to the other container
docker run --network mynet123 --add-host mongodb:172.18.0.22 -d myapp

Access a docker container in docker multi-host network

I have created a Docker multi-host network using Docker Overlay network with 4 nodes: node0, node1, node2, and node3. Node0 act as key-value store which shares the information of nodes while node1, node2, and node3 are bound to the key-value store.
Here are node1 networks:
user#node1$ docker network ls
NETWORK ID NAME DRIVER
04adb1ab4833 RED overlay
[ . . ]
As for node2 networks:
user#node2$ docker network ls
NETWORK ID NAME DRIVER
04adb1ab4833 RED overlay
[ . . ]
container1 is running on node1, that hosts the RED-named network.
user#node1$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f9bacac3c01d ubuntu "/bin/bash" 3 hours ago Up 2 hours container1
Docker added an entry to /etc/hosts for each container that belongs to the RED overlay network.
user#node1$ docker exec container1 cat /etc/hosts
10.10.10.2 d82c36bc2659
127.0.0.1 localhost
[ . . ]
10.10.10.3 container2
10.10.10.3 container2.RED
From node2, I'm trying to access the container1 running on node1. I tried to run container1 using command below but it returns error.
`user#node2$ docker docker exec -i -t container1 bash`
Error response from daemon: no such id: container1
Any suggestion?
Thanks.
The network is shared only for the containers.
While the network is shared among the containers across the multi-hosts overlay, the docker daemons cannot communicate between them as is.
The user#_node2_$ docker exec -i -t container1 bash doest not work because, indeed, no such id: container1 are running from node2.
Accessing remote Docker daemon
Docker daemons communicate through socket. UNIX socket by default, but it is possible to add an option, --host to specify other sockets the daemon should bind to.
See the docker daemon man page:
-H, --host=[unix:///var/run/docker.sock]: tcp://[host:port] to bind or unix://[/path/to/socket] to use.
The socket(s) to bind to in daemon mode specified using one or more
tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.
Thus, it is possible to access from any node a docker daemon bind to a tcp socket.
The command user#node2$ docker -H tcp://node1:port exec -i -t container1 bash would work well.
Docker and Docker cluster (Swarm)
I do not know what you are trying to deploy, maybe just playing around with the tutorials, and that's great! You may be interested to look into Swarm that deploys a cluster of docker. In short: you can use several nodes as it they were one powerful docker daemon access through a single node with the whole Docker API.

Setting Up Docker Dnsmasq

I'm trying to set up a docker dnsmasq container so that I can have all my docker containers look up the domain names rather than having hard-coded IPs (if they are on the same host). This fixes an issue with the fact that one cannot alter the /etc/hosts file in docker containers, and this allows me to easily update all my containers in one go, by altering a single file that the dnsmasq container references.
It looks like someone has already done the hard work for me and created a dnsmasq container. Unfortunately, it is not "working" for me. I wrote a bash script to start the container as shown below:
name="dnsmasq_"
timenow=$(date +%s)
name="$name$timenow"
sudo docker run \
-v="$(pwd)/dnsmasq.hosts:/dnsmasq.hosts" \
--name=$name \
-p='127.0.0.1:53:5353/udp' \
-d sroegner/dnsmasq
Before running that, I created the dnsmasq.hosts directory and inserted a single file within it called hosts.txt with the following contents:
192.168.1.3 database.mydomain.com
Unfortunately whenever I try to ping that domain from within:
the host
The dnsmasq container
another container on the same host
I always receive the ping: unknown host error message.
I tried starting the dnsmasq container without daemon mode so I could debug its output, which is below:
dnsmasq: started, version 2.59 cachesize 150
dnsmasq: compile time options: IPv6 GNU-getopt DBus i18n DHCP TFTP conntrack IDN
dnsmasq: reading /etc/resolv.dnsmasq.conf
dnsmasq: using nameserver 8.8.8.8#53
dnsmasq: read /etc/hosts - 7 addresses
dnsmasq: read /dnsmasq.hosts//hosts.txt - 1 addresses
I am guessing that I have not specified the -p parameter correctly when starting the container. Can somebody tell me what it should be for other docker containers to lookup the DNS, or whether what I am trying to do is actually impossible?
The build script for the docker dnsmasq service needs to be changed in order to bind to your server's public IP, which in this case is 192.168.1.12 on my eth0 interface
#!/bin/bash
NIC="eth0"
name="dnsmasq_"
timenow=$(date +%s)
name="$name$timenow"
MY_IP=$(ifconfig $NIC | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}')
sudo docker run \
-v="$(pwd)/dnsmasq.hosts:/dnsmasq.hosts" \
--name=$name \
-p=$MY_IP:53:5353/udp \
-d sroegner/dnsmasq
On the host (in this case ubuntu 12), you need to update the resolv.conf or /etc/network/interfaces file so that you have registered your public IP (eth0 or eth1 device) as the nameserver.
You may want to set a secondary nameserver to be google for whenever the container is not running, by changing the line to be dns-nameservers xxx.xxx.xxx.xxx 8.8.8.8 E.g. there is no comma or another line.
You then need to restart your networking service sudo /etc/init.d/networking restart if you updated the /etc/network/interfaces file so that this auto updates the /etc/resolve.conf file that docker will copy to the container during the build.
Now restart all of your containers
sudo docker stop $CONTAINER_ID
sudo docker start $CONTAINER_ID
This causes their /etc/resolv.conf files update so they point to the new nameserver settings.
DNS lookups in all your docker containers (that you built since making the changes) should now work using your dnsmasq container!
As a side note, this means that docker containers on other hosts can also take advantage of your dnsmasq service on this host as long as their host's nameserver settings is set to using this server's public IP.

Resources