How do I make host.docker.internal work with custom dns configuration enabled? - docker

I have docker compose running with several containers. One of those containers is a dns server running bind. In my docker daemon configuration I specify the dns like this:
"dns" : [
"10.1.1.8", /* static ip address of my dockerized bind container defined in compose */
"x.x.x.x", /* my companies internal vpn dns */
"8.8.8.8" /* google dns */
]
This all works fine. My containers in the compose file will use the bind server running on 10.1.1.8 for dns lookup and then fall back on my companies internal dns and lastly googles dns for external websites.
Docker provides a special dns host.docker.internal which should point at the host IP (lets say you want docker containers to connect to services running locally but not on docker). I want to use this in a few containers which should allow the container to reference the host IP address without hardcoding an IP which can change. In fact docker inserts this value into the hosts file (windows/system32/driver/etc/host) on the host operating system and updates it when you host IP gets assigned a new dns.
The issue is docker uses dns to resolve "host.docker.internal". When using my custom dns configuration in the daemon it breaks things and I get issues reaching the host os service. I spent 2 hours debugging this issue till I realized host.docker.internal starts working only when I delete the dns configuration from the daemon config. Is there any way to make docker resolve the dns correctly and still use custom dns bind server on the same machine? Can I somehow update the daemon dns to also point at some docker dns ip address?

Have you considered to rely on Docker Compose and how it helps defining custom DNS addressing policies.
I provide you the link to the Compose DNS configuration official guide.

Related

How to use the Docker's embedded DNS server for builds via docker-compose?

When I run docker-compose up, I see that it creates a custom network for the containers. AFAIU, this makes the containers use the Docker’s embedded DNS server for resolving, which can forward DNS lookups to addresses like 127.0.0.1 on the host (e.g. when the host uses a local DNS server, such as dnsmasq).
However, docker-compose seems to use the default bridge network for builds, which makes containers use the Google's public DNS servers in case the host is configured with 127.0.0.1, for example.
Is it possible to use the Docker's embedded DNS server for builds, like it's used for running containers?

Access Docker container via DNS name from corporate LAN

I'm looking for a way to access containers that are running on server in our company lan by domain names. By far I only managed to access them by IPs
So the setup is. Docker (for windows) is running on server srv1.ourdomain.com (Windows Server 2019), network for container is configured with l2bridge driver, container's dns name, as specifiedn in run command, is cont1. It is accessible by dns name on the docker host (srv1) and by IP from my machine.
What can I do to access the container by dns name cont1.ourdomain.com from my local machine located in the same lan?
I tried to use proxy (traefik) but it cant rewrite urls in the content, so web applications running inside the container are failing. Bacause of this I can't host multiple web application behind that proxy.
I know that it is possible to map container's port to host port and then it will be accessible from lan through the host name and host port, but applications I'm running are requiring many ports to be mapped (like 8 ports for each container) and with those containers being short-lived developer's environments it will be a hell to find a port pool when running new container.
So again if I can access container and its' ports by IP, is there a way to do the same by DNS name?
UPD1. Container host is a virtual server running on vmware. I tried to follow those recommendations and configure promiscuous mode. Thise doesn't help with dns though.
UPD2. I tried transparent network as well. For some reason DHCP can never assign propper IP and container ends up with autoconfigured ip from 168.x.x.x subnet.
You could create a transparent network and make the container discoverable on the network just like host. However, using host ports is what's recommended.
Did you try PathStrip or PathPrefixStrip with Traefik? That should let you rewrite the URLs for the backend.

docker images fail to start because of unknownhost exception while trying to communicate with external host

I have a spring boot service which runs fine as spring boot app. I have created docker image out of it using docker file. When the image start, application seems starting fine till a point when it try to resolve external host (I have couple fo external service configured based on profile and I am running in dev profile which will communicate with external service like consule , mysql etc). It throws unknownhost exception. Same application run fine and able to run and communicate with external services while running it as spring boot app/service in my local machine . It seems like the issue is between host and docker container not able to use dns of host. Any help, how can I resolve the issue ?
From the Docker documentation:
https://docs.docker.com/config/containers/container-networking/#ip-address-and-hostname
DNS services
By default, a container inherits the DNS settings of the Docker
daemon, including the /etc/hosts and /etc/resolv.conf.You can override
these settings on a per-container basis.
Flag Description
--dns 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.
--dns-search A DNS search domain to search non-fully-qualified hostnames.
To specify multiple DNS search prefixes, use multiple --dns-search flags.
--dns-opt A key-value pair representing a DNS option and its value. See your
operating system’s documentation for resolv.conf for valid options.
--hostname The hostname a container uses for itself. Defaults to the container’s
ID if not specified.
See also:
Docker docs: Configure container DNS
java.net.UnknownHostException on Docker

Remote Docker container by hostname

How do you access remote Docker container by its hostname?
I need to access remote Docker containers by its hostnames (or some constant IP's) for development and testing purposes. I have tried:
looking for any DNS approach (have not found any clues),
importing /ets/hosts (probably impossible),
creating tunnes (only this works but it is very time consuming).
It's the same as running any other process on a host, Docker or not Docker: you access it via the host name or IP address of the host and the port the service is listening on (the first port of the docker run -p argument). Docker containers don't have externally visible individual IP addresses any more than non-Docker HTTP or ssh daemons do.
If you do have DNS infrastructure available to you, you could set up CNAME records to resolve particular service names to the specific hosts that are running them.
One solution that may help you is some sort of service registry; in the past I've used Consul with some success. You can configure Consul with some health checks or other probes ("look for an HTTP service on port 12345 that answers GET / calls"), and it will provide its own DNS service ("okay, http://whatevername.service.consul:12345/ will reach your service on whichever hosts it happens to be running on").
Nothing in the Docker infrastructure specifically helps this. Using /etc/hosts is distinctly not a best practice: the name-to-IP mapping needs to be kept in sync across all machines and you'll start wishing you had a network service to publish it for you, which is exactly what DNS is for.

Docker container DNS - Resolve URL

I have a docker container that needs to access an network server on the LAN. This server is visible from the docker host machine and I can access it from within the container when I reference the IP address directly.
However I need to be able to specify a url and port (e.g http://myserver:8080) rather than an IP address, which the docker container cannot resolve.
How can I configure the container to resolve this? ideally using the docker hosts dns. I have looked at many of the docs, but not being a DNS expert, it doesn't seem straightforward.
UPDATE:
I have tried this, which seems to work, but does this have any downsides or unintended consequences?
--network host
Thanks,
The rigth way to do this is to configure the docker daemon dns as specified under daemon-dns-options.
Using the host network is not recommended as it has some downsides https://docs.docker.com/network/host/

Resources