On host machine, it's very fast to lookup a domain. But inside docker container, it's much
slower and sometimes timeout.
The host machine is a virtual host, and it's dns server address is 127.0.0.1 (weird but true). So I've tried to modify /etc/resolv.conf inside container and set the dns server to be 172.x (host's address). As a result, I didn't see any good effect.
I've also tried to set the container's dns server to be a self-built one (101.x), but still, it's slow to look up a domain. Another weird thing is that ping 101.x is very fast.
I'm confused about this phenomenon, anyone can explain and help?
I am not sure of why resolving DNS is slow in the containers, but I have procedure which I follow to resolve the DNS in the docker containers.
To verify DNS resolution issue:
# docker run busybox nslookup google.com
Server: 8.8.8.8
Address 1: 8.8.8.8
nslookup: can't resolve 'google.com'
Find out the DNS server used in your machine :
# nm-tool |grep DNS
DNS: 172.24.100.50
DNS: 10.1.100.50
Run it again using DNS IP found in the above step which resolves the DNS issue:
# docker run --dns 172.24.100.50 busybox nslookup google.com
Server: 172.24.100.50
Address 1: 172.24.100.50 indc01.radisys.com
Name: google.com
Address 1: 2607:f8b0:4009:80c::200e ord36s01-in-x0e.1e100.net
Address 2: 172.217.4.110 ord36s04-in-f14.1e100.net
To resolve it permanently add the following content as below to a new file:
root#labadmin-VirtualBox:/home/labadmin# cat /etc/docker/daemon.json
{
"dns" : ["172.24.100.50", "8.8.8.8"]
}
More info on Docker DNS configuration.
Restart the docker service and verify it again:
# docker run busybox nslookup google.com
Server: 172.24.100.50
Address 1: 172.24.100.50 indc01.radisys.com
Name: google.com
Address 1: 2607:f8b0:4009:801::200e ord30s31-in-x0e.1e100.net
Address 2: 172.217.4.238 ord30s31-in-f14.1e100.net
Check it by running the container:
# docker run -it e02e811dd08f
/ # ping google.com
PING google.com (172.217.4.238): 56 data bytes
64 bytes from 172.217.4.238: seq=0 ttl=47 time=251.506 ms
64 bytes from 172.217.4.238: seq=1 ttl=47 time=245.621 ms
Hope this helps.
Related
I am trying to run a coredns plugin https://github.com/coredns/demo that returns 1.1.1.1 for 172.0.0.0/8 or 127.0.0.0/8 and 8.8.8.8 for everything else.
I run the binary and try to make a request from dig using dig example.org #localhost -p1053 +short which returns 1.1.1.1 since the request is sent from localhost
Is there anyway I can send a request from dig to coredns that it might look like to the DNS server that it is sent from another IP and it will return 8.8.8.8 instead?
From dig manual:
-b address[#port]
Set the source IP address of the query. The address must be a valid address on one of the host's network interfaces, or "0.0.0.0" or "::". An optional port may be
specified by appending "#<port>"
Otherwise, if the server supports ECS (EDNS Client Subnet) you can use dig option +subnet=addr to give it to the server and see how its reply changes.
I have a .NET Core API App running in Azure App Services using Windows, but now I want to test it using Linux. The app uses a custom DNS Zone just to map a custom hostname to a specific IP address.
To implement that in my Windows App Service I used the following Application Settings as stated in this page: WEBSITE_DNS_SERVER and WEBSITE_ALT_DNS_SERVER. Although it looks like a workaround, it works pretty well with Windows App Services. But in Linux it seems to have no effect and my app is not resolving the hostname as needed.
How can I use a custom DNS server in Azure App Service with Linux or add a custom hostname like editing the hosts file?
Unlike our App Service Windows, nameresolver.exe is not available and the Application settings for "WEBSITES_ALT_DNS" and "WEBSITES_DNS" do not populate the configuration files within the container. Below are steps are troubleshooting issues for "Alpine" based images since you don’t mention if you are using a Linux container or the default Linux OS.
Install Bind-tools-
apk update
apk add bind-tools
Run Nslookup-
Once bind-tools is installed, you'll see the server that is being used. If bind-tools are not installed, the DNS server will not be shown. Example provided below.
9031977be93a:~# nslookup google.com
Server: 127.0.0.11
Address: 127.0.0.11#53
Non-authoritative answer:
Name: google.com
Address: 216.58.194.174
Name: google.com
Address: 2607:f8b0:4005:801::200e
Update Config file-
To use a different DNS server for testing, update the /etc/resolv.conf file and update the "nameserver" to use a different DNS server. In this example, we're using Googles DNS.
vi /etc/resolv.conf
By default, the following will be in the resolv.conf file.
search reddog.microsoft.com
nameserver 127.0.0.11
options timeout:1 attempts:5 ndots:0cd /etc
If you're not familiar with "vi", press "i" on your keyboard to begin editing the file.
Once you're done, press "esc" and ":wq!" then enter.
search reddog.microsoft.com
nameserver 8.8.8.8
options timeout:1 attempts:5 ndots:0
Running Nslookup again, you'll see the new nameserver being used.
9031977be93a:~# nslookup google.com
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name: google.com
Address: 216.58.194.174
Name: google.com
Address: 2607:f8b0:4005:804::200e
Hardcoding Hostname-
You can also hardcode the IP address for the hostname in question for testing. To do so, you'll need to update the following file.
vi /etc/hosts
Add the IP address that you would like the DNS to point to. In this example, I'm changing the IP for my custom domain.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.20.0.2 9031977be93a
10.10.10.10 www.polytechniks.com
Save the changes and use "ping" or "traceroute" to see the IP being used. NOTE: Nslookup does NOT use the /etc/hosts file so you will still see the IP address associated with the DNS.
9031977be93a:~# ping www.polytechniks.com
PING www.polytechniks.com (10.10.10.10): 56 data bytes
--- www.polytechniks.com ping statistics ---
8 packets transmitted, 0 packets received, 100% packet loss
9031977be93a:~# traceroute www.polytechniks.com
traceroute to www.polytechniks.com (10.10.10.10), 30 hops max, 46 byte packets
1 172.20.0.1 (172.20.0.1) 0.005 ms 0.004 ms 0.004 ms
I am on ubuntu, and I am running a docker default bridge network. I have containerized versions of zookeeper, kafka, and an app that I wrote that talks to kafka.
I do a:
docker exec -it <my-app id> /bin/bash
Then inside my app's container I run nslookup kafka
/go # nslookup schmafka
nslookup: can't resolve '(null)': Name does not resolve
Name: schmafka
Address 1: 172.20.0.8 docker_kafka_1.docker_default
I do not understand why I get the output "can't resolve '(null)'" and then I get the expected ip address printed out later. I tried to google nslookup and this output message but I cannot figure why this happens.
My /etc/resolv.conf file looks like this:
/go # cat /etc/resolv.conf
search valhalla.local valhalla v
nameserver 127.0.0.11
options ndots:0
This is a bug/oddity in nslookup. The "can't resolve" message is actually about the DNS server in use, not the site you are trying to look up.
For example this query (which tells nslookup to lookup google.com using the 8.8.8.8 DNS server) has no error message:
nslookup google.com 8.8.8.8
Server: 8.8.8.8
Address 1: 8.8.8.8 dns.google
Name: google.com
Address 1: 172.217.164.110 sfo03s18-in-f14.1e100.net
Address 2: 2607:f8b0:4005:80b::200e sfo03s18-in-x0e.1e100.net
But this query (in which the DNS server is "null") does show the "error":
UAP-AC-LR1-BZ.v4.0.42# nslookup google.com
nslookup: can't resolve '(null)': Name does not resolve
Name: google.com
Address 1: 172.217.164.110 sfo03s18-in-f14.1e100.net
Address 2: 2607:f8b0:4005:80b::200e sfo03s18-in-x0e.1e100.net
Admittedly this is misleading/confusing, and really should be fixed in nslookup.
I try create docker container with custom network and dos settings.
docker network create --driver=bridge --opt "com.docker.network.bridge.enable_ip_masquerade"="true" --opt "com.docker.network.bridge.enable_icc"="true" --opt="com.docker.network.driver.mtu"="1500" --opt="com.docker.network.bridge.host_binding_ipv4"="0.0.0.0" net
--
docker run --dns 10.0.0.2 --network=net busybox cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
Else if I use standard network all work fine
docker run --dns 10.0.0.2 --network=bridge busybox cat /etc/resolv.conf
nameserver 10.0.0.2
As of Docker 1.10, DNS is managed differently for user-defined networks. DNS for the default bridge network is unchanged for backwards compatibility. In a user-defined network, docker daemon uses the embedded DNS server. According to the documentation found here:
https://docs.docker.com/engine/userguide/networking/configure-dns/
--dns=[IP_ADDRESS...] The IP addresses passed via the --dns option is used by the embedded
DNS server to forward the DNS query if embedded DNS server is unable
to resolve a name resolution request from the containers. These
--dns IP addresses are managed by the embedded DNS server and will not
be updated in the container’s /etc/resolv.conf file.
So, the DNS nameserver will be used, it just is not visible in the container's /etc/resolv.conf.
Here is my Dockerfile
FROM javamachine_0.1.2
MAINTAINER Meiram
RUN /report/report.sh start
ENV LANG C.UTF-8 ENV LANGUAGE C.UTF-8 ENV LC_ALL C.UTF-8
RUN echo "nameserver 192.168.1.100" > /etc/resolv.conf
COPY resolv.conf /etc/resolv.conf
EXPOSE 9090
when creating container directive docker run --dns also do not change entries in /etc/resolv.conf
How to change entries in /etc/resolv.conf permanently?
If you use docker-compose you can simple add your dns-server in docker-compose.yml
my-app:
build: my-app
dns:
- 10.20.20.1 # dns server 1
- 10.21.21.2 # dns server 2
dns_search: ibm-edv.ibmnet.int
see https://bitbucket.org/snippets/mountdiablo/9yKxG/docker-compose-reference-yaml-file-with
if you use --dns you may need to remove those lines:
RUN echo "nameserver 192.168.1.100" > /etc/resolv.conf
COPY resolv.conf /etc/resolv.conf
also,
try to swap the lines too.. COPY command will override the previous one.
I found the answer
When you need to create a container with default network settings (172.0.0.x)
The key --dns is working. But doesn't work with user-defined network --net some_name_of_your_network
So if you need to create container you can define hostnames in /etc/hosts
using this command
docker run --net my_net --ip 192.168.1.x --add-host webserver:192.168.1.100 --add-host mysqlserver:192.168.1.x -td someimage
But this solution is not acceptable for me. Because I need to edit /etc/resolv.conf
See https://docs.docker.com/engine/userguide/networking/default_network/configure-dns/ for more details.
You'll want to add the following to your docker command line, instead of all the --add-host options (assuming that your hosts are resolvable through your dns)
--dns=192.168.1.100
Based on the fact that you're running multiple services, if your webserver and mysqlserver are also docker containers, you might want to configure the collection of containers via docker-compose. See https://docs.docker.com/compose/overview/ for more details.
DNS services
--dns IP
The IP address of a DNS server. To specify multiple DNS servers, use multiple --dns flags. If the container cannot reach any of the IP addresses you specify, Google’s public DNS server 8.8.8.8 is added, so that your container can resolve internet domains.
NOTE
That if we pass IP address to --dns option still /etc/resolv.conf nameserver is as before; because Docker uses default embedded DNS server and the value of --dns is set for that network.
Example
we can run CoreDNS this way:
docker container run --rm -it -v $PWD:/root/ --network mybr --ip 10.11.12.244 coredns/coredns:latest -dns.port 53 -conf /root/coredns
So our DNS server is up and running on --ip 10.11.12.244
At the same time we can run another container on the network (custom-defined) and check for some records .
docker container run --rm -it --network mybr --ip 10.11.12.11 --dns 10.11.12.244 nicolaka/netshoot bash
So by passing --dns 10.11.12.244 inside that container still we see the default one which is not right.
bash-5.1# cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
And test it
bash-5.1# dig node.examp1e.ir #10.11.12.244 +nocmd +nostats +nocomments
;node.examp1e.ir. IN A
node.examp1e.ir. 3600 IN A 10.11.12.10
examp1e.ir. 3600 IN NS a.ns.examp1e.ir.
examp1e.ir. 3600 IN NS b.ns.examp1e.ir.
bash-5.1#
bash-5.1#
bash-5.1#
bash-5.1# dig node.examp1e.ir +nocmd +nostats +nocomments
;node.examp1e.ir. IN A
node.examp1e.ir. 3600 IN A 10.11.12.10
examp1e.ir. 3600 IN NS a.ns.examp1e.ir.
examp1e.ir. 3600 IN NS b.ns.examp1e.ir.
bash-5.1#
and here is the config and zone for examp1e.ir
examp1e.ir {
file /root/db.10.11.12.0
log
errors
}
And db.10.11.12.0
$TTL 3600
# IN SOA a.ns.examp1e.ir. webmaster.examp1e.ir. (
3 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
# IN NS a.ns.examp1e.ir.
# IN NS b.ns.examp1e.ir.
a.ns IN A 10.11.12.244
b.ns IN A 10.11.12.244
node IN A 10.11.12.10
nginx IN A 10.11.12.11
nginx IN TXT "this is nginx design pattern"
mybr is a custom defined network
docker network ls | grep mybr
02884d702083 mybr bridge local
and ... inspect mybr
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "10.11.12.0/24",
"Gateway": "10.11.12.1"
}
]
},
Hey Just bind container volume, with the volume, inside a container,
E.g. Make a file on host machine resolv.conf, and then bind it with /etc/resolv.conf inside the container.
It worked for me