I have many containers on my server, I need to access all containers by the name(not IP).
and of course, I can ping containers by IP address.
problem is I can't ping them by hostname or name.
also, I don't using docker-compose. I use docker file and docker restapi
Option A: run a DNS proxy server container
Here is a DNS proxy server project that can do this: https://github.com/mageddo/dns-proxy-server
First, you need to start the DNS proxy server:
docker run --rm --hostname dns.mageddo -v /var/run/docker.sock:/var/run/docker.sock -v /etc/resolv.conf:/etc/resolv.conf defreitas/dns-proxy-server
Then, run a dummy container and assign it a --hostname for testing purpose:
docker run -d --hostname=this-can-be-resolved-from-host nginx
Finally, try to resolve/ping/curl the name you assigned to the nginx container in the previous step, from your host machine:
neo#neo-desktop:~$ nslookup this-can-be-resolved-from-host
Server: 172.17.0.4
Address: 172.17.0.4#53
Non-authoritative answer:
Name: this-can-be-resolved-from-host
Address: 172.17.0.3
Name: this-can-be-resolved-from-host
Address: 172.17.0.3
neo#neo-desktop:~$ ping this-can-be-resolved-from-host
PING this-can-be-resolved-from-host (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3 (172.17.0.3): icmp_seq=1 ttl=64 time=0.032 ms
neo#neo-desktop:~$ curl this-can-be-resolved-from-host
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
[...]
Option B: Run an injector that adds the container names directly in the hosts file, on the docker host:
(solution found by the OP #Tokyo Developer)
Here is a simple "etc/hosts" file injection tool: https://github.com/dvddarias/docker-hoster
Run the injector container:
docker run -d \
-v /var/run/docker.sock:/tmp/docker.sock \
-v /etc/hosts:/tmp/hosts \
dvdarias/docker-hoster
Run a dummy container and assign it a --hostname for testing purpose:
docker run -d --hostname=this-can-be-resolved-from-host nginx
Try to resolve the hostname AND the container name assigned to the nginx container in the previous step, from your host machine:
nslookup this-can-be-resolved-from-host
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: this-can-be-resolved-from-host
Address: 172.17.0.3
nslookup keen_lamarr
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: keen_lamarr
Address: 172.17.0.3
Related
I've run into an issue that seems similar too this one; https://forums.docker.com/t/cant-access-service-in-swarm/63876. My setup is a little bit different though and I haven't found a solution to my problem yet.
The minimal, reproducible example
Build a swarm cluster between atleast 3 Ubuntu 20.04 docker swarm managers.
Deploy a service docker service create --name test_web --replicas 3 --publish published=8080,target=80 nginxdemos/hello
Check that the containers and services were created properly and observe the failure of connecting to that service:
demi-ubu01:~/stacks$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d4a12a3c5448 nginxdemos/hello:latest "nginx -g 'daemon of…" About a minute ago Up About a minute 80/tcp test_web.2.yul33wdycarig3qoxnehgrjrz
demi-ubu01:~/stacks$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
0yqd7gvggwuh test_web replicated 3/3 nginxdemos/hello:latest *:8080->80/tcp
# External test:
demi-ubu01:~/stacks$ curl -I 10.100.4.5:8080
curl: (7) Failed to connect to 10.100.4.5 port 8080: Connection refused
# Inside container to published service port:
demi-ubu01:~/stacks$ docker exec -it d4a12a3c5448 wget http://test_web:8080
Connecting to test_web:8080 (10.0.4.2:8080)
wget: can't connect to remote host (10.0.4.2): Host is unreachable
# Inside container to apps exposed port:
demi-ubu01:~/stacks$ docker exec -it d4a12a3c5448 wget http://localhost:80
Connecting to localhost:80 (127.0.0.1:80)
index.html 100% |****************************| 7217 0:00:00 ETA
The expected result of the first curl command should be a Status 200 Ok.
The detailed report
My setup is 4 nodes in total. They are identical Ubuntu 20.04 KVM virtual machines all on the same network. There are no firewalls between them. I have 3 Managers and 1 Worker (which i've only added as a step during troubleshooting).
:~/stacks$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
kcm5v64psntjxngnqkfdj1jzh * demi-ubu01 Ready Active Reachable 20.10.1
uo3rljg6ax5qkjm898pyym9t1 demi-ubu02 Ready Active Leader 20.10.1
pysnl8sohdp4fv67gui156z4k demi-ubu03 Ready Active Reachable 20.10.1
rp2otsqpnxkgbmxbpkv21yjs6 demi-ubu04 Ready Active 20.10.1
I can run a container normally and reach it on the local host fine.
demi-ubu01:~/stacks$ docker run -p 8080:80 -d nginxdemos/hello
de4d0a937710acb1d6d8ae3b7eb9175860b6614dfd9ce92bc972efe619ae095f
demi-ubu01:~/stacks$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
de4d0a937710 nginxdemos/hello "nginx -g 'daemon of…" 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp pedantic_wiles
demi-ubu01:~/stacks$ curl -I 10.100.4.5:8080
HTTP/1.1 200 OK
Server: nginx/1.13.8
Date: Sat, 19 Dec 2020 17:59:23 GMT
Content-Type: text/html
Connection: keep-alive
Expires: Sat, 19 Dec 2020 17:59:22 GMT
Cache-Control: no-cache
However the same app deployed as a service using the following compose file:
demi-ubu01:~/stacks$ cat test.yml
version: "3.6"
services:
web:
image: nginxdemos/hello:latest
deploy:
replicas: 3
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- target: 80
published: 8080
protocol: tcp
mode: ingress
networks:
- webnet
networks:
webnet:
driver: overlay
It does not become reachable from any of the hosts at all:
demi-ubu01:~/stacks$ docker stack deploy -c test.yml test
Creating network test_webnet
Creating service test_web
demi-ubu01:~/stacks$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
05030ef897a1 nginxdemos/hello:latest "nginx -g 'daemon of…" 10 seconds ago Up 7 seconds 80/tcp test_web.1.kobrpkp68f2qbs4jhd6o8aebg
# Trying on all of the hosts in the cluster. No firewalls here.
demi-ubu01:~/stacks$ curl -I 10.100.4.5:8080
curl: (7) Failed to connect to 10.100.4.5 port 8080: Connection refused
demi-ubu01:~/stacks$ curl -I 10.100.4.9:8080
curl: (7) Failed to connect to 10.100.4.9 port 8080: Connection refused
demi-ubu01:~/stacks$ curl -I 10.100.4.10:8080
curl: (7) Failed to connect to 10.100.4.10 port 8080: Connection refused
demi-ubu01:~/stacks$ curl -I 10.100.4.11:8080
curl: (7) Failed to connect to 10.100.4.11 port 8080: Connection refused
demi-ubu01:~/stacks$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
elvfm7o4v4zo test_web replicated 3/3 nginxdemos/hello:latest *:8080->80/tcp
I also don't see any port bindings being made on those hosts at all, so it doesn't look like any ports are being published.
INeed2Poo#demi-ubu01:~/stacks$ docker service inspect test_web
[
## https://pastebin.com/WqqyDnVS ##
]
demi-ubu01:~/stacks$ netstat -na | grep LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:49152 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:24007 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
demi-ubu01:~/stacks$ docker network ls
NETWORK ID NAME DRIVER SCOPE
6e5f7e7cebc3 bridge bridge local
7a1155f87a62 docker_gwbridge bridge local
ab32da8ac1ec host host local
46id8wzw4ayf ingress overlay swarm
a24a40ef78f4 none null local
d9l7msysdx8m test_webnet overlay swarm
INeed2Poo#demi-ubu01:~/stacks$ docker network inspect 46id8wzw4ayf
[
https://pastebin.com/JPA0ZBjE
]
I also can't reach the service while exec'ed into a container for that service. Execing into a container, I'm able to hit the LOCAL app port, however I cannot hit the service by name. The container CAN resolve the service name.
## Testing the app's service from the local container fails:
demi-ubu01:~/stacks$ docker exec -it 05030ef897a1 wget http://test_web:8080
Connecting to test_web:8080 (10.0.4.2:8080)
wget: can't connect to remote host (10.0.4.2): Host is unreachable
## Testing the app's local port from the local container is sucessful:
demi-ubu01:~/stacks$ docker exec -it 05030ef897a1 wget http://localhost:80
Connecting to localhost:80 (127.0.0.1:80)
index.html 100% |****************************| 7217 0:00:00 ETA
demi-ubu01:~/stacks$ docker --version
Docker version 20.10.1, build 831ebea
I've changed the default-addr-pool for the swarm cluster from the original 10.0.0.0/8 network:
demi-ubu01:~$ docker info --format '{{json .Swarm.Cluster.DefaultAddrPool}}'
["10.135.0.0/16"]
I've gone and made sure that I'm not using any overlapping networks that might be causing this and have gone so far as to completely redeploy the cluster. I've just about exhausted all of my troubleshooting idea's. Any Idea's?
Edit: Update: I redeployed using Ubuntu 18.04 as my base image, and the same exact setup on that (deployed using ansible) seems to work fine... So this is an issue with the current version of Docker on Ubuntu 20.04.
Let me add my response from the docker forum here as well, as it is high likely the solution:
Is it safe to assume that 10.100.4.5 is one of your nodes ip?
The default address pool is 10.0.0.0/8, see: docker info --format '{{json .Swarm.Cluster.DefaultAddrPool}}'
If this is the case, you might find this blog post helpful - you can safely ignore that it refers to Docker EE, the problem and solution is valid for Docker CE as well. You need to alter default-addr-pool either when initiating the swarm or by modifying each node’s /etc/docker/daemon.json configuration file (and restart the daemon then).
i'm trying to set up pihole in a docker container (on a raspberry pi) and as such, have my DNS on my ip: 192.160.170.10. The docker container runs the dns and exposes its port 53, where the dns is available
when running iplookup google.com on the host, i get the correct output:
Server: 192.160.170.10
Address: 192.160.170.10#53
Non-authoritative answer:
Name: google.com
Address: 172.217.16.78
My resolv.conf also contains this address.
when running a docker container, i am unable to do this nslookup however:
docker run busybox nslookup google.com
outputs:
;; connection timed out; no servers could be reached
Following this tutorial i've tried specifying the dns with the following command:
docker run --dns 192.160.170.10 busybox nslookup google.com
but this also does not solve the problem. I've also tried adding the dns to /etc/docker/daemon.json, which also does nothing.
the docker container's resolv.conf output is: nameserver 192.160.170.10
What is wrong with my configuration / How can i further debug this DNS issue?
edit:
output from docker run --rm --net=host busybox nslookup google.com:
Server: 192.160.170.10
Address: 192.160.170.10:53
Non-authoritative answer:
Name: google.com
Address: 172.217.16.78
*** Can't find google.com: No answer
I have this scheme for a remote connection to docker app.
ContainerA Ip: 172.17.0.2
ContainerB Ip: 172.17.0.3
vncserver in the containerA run on port 5901 and exposed to others.
containerA[vncserver] <-- containerB[virtualGL + App]
ContainerB has ENTRYPOINT ["/opt/VirtualGL/vglrun"]
Then, I run: docker exec containerB -d 172.17.0.2:5901 App
But it fails with:
fail to open Display 172.17.0.2:5901
How do I to communicate virtualGL with vncserver?
docker network create --driver bridge network1
docker run -itd --name docker1 --network network1 busybox
docker run -itd --name docker2 --network network1 busybox
docker exec -it docker1 /bin/bash
now in docker1, I can ping docker2
/ # ping docker2
PING docker2 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.056 ms
I thought this entry is added in /etc/hosts, but it is not
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
172.19.0.2 841c0dc99115
How does docker1 know docker2's ip address?
Docker resolves names through internal dns server which is used by the Docker Daemon you can check the dns adress by cat /etc/resolv.conf to understand more you can read here
My setup is the following:
Host: Win10
Guest: Ubuntu 15.10 (clean install, only docker and nodejs are added)
Base image: https://hub.docker.com/r/microsoft/aspnet/ 1.0.0-beta8-coreclr
Inside the guest I have installed Docker and created image (added sample webapp using yeoman to the image above). When I run the image inside container I can ping the container IP sucessfuly using the container IP from the linux (e.g. 172.17.0.2).
$sudo docker run -d -p 80:5000 --name web myapp
$sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' "web"
172.17.0.2
$ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.060 ms
1 packets transmitted, 1 received, 0% packet loss, time 999ms
$curl 172.17.0.2:80
curl: (7) Failed to connect to 172.17.0.2 port 80: Connection refused
I can also connect to the container and execute commands like ping, however from the linux machine (guest in VirtualBox, host for docker) I cannot access the web app that is hosted inside the container as seen above. I tried several approaches like mapping to the host IP addresses etc, but none of them worked. Did anyone have ideas where to start from ? Is the issue comes from that the docker is installed inside VirtualBox machine?
Thank you in advance.
Edit: Here are the logs from the container:
Could not open /etc/lsb_release. OS version will default to the empty string.
Hosting environment: Production
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
Your command tells Docker to essentially proxy requests from port 80 of the Linux guest to port 5000 of the container. So the curl command you tried doesn't work because you're trying on port 80 on the container, while the container itself has a service listening on port 5000.
To connect to the container directly, you would use (on the Linux guest):
curl 172.17.0.2:5000
To access via the published port on the Linux guest (from your host):
curl (Linux guest IP)
Or (from the Linux guest):
curl localhost
Edit: This will also prove to be problematic:
Now listening on: http://localhost:5000
You'll want your app inside the container to bind to all interfaces (0.0.0.0) so it listens on the container's assigned IP. With localhost it won't be accessible.
You might find this example useful:
https://github.com/aspnet/Home/blob/dev/samples/1.0.0-beta8/HelloWeb/project.json
This line specifies that the app bind to all interfaces (using "*") on port 5004:
21 "kestrel": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel --server.urls http://*:5004"
You'll need similar configuration.