Confusing resolver structure

I am just getting back in to using Docker after a few retirement years away from the “Dev Crowd”, so I find myself getting in places I thought I’d figured out a few years back. Well, things change, right? Still, it would be great if one of the experts on this forum could clear up a few “head-scratchers” for me:

  1. /etc/resolv.conf is pointed at a 192.168.. IP, which I assume to be Docker’s “internal” DNS server
  2. Two different containers point at this same IP but container1 can’t resolve container2’s hostname, although it can ping its IPv4 address, so a SQL connection fails. This same container2 is resolvable from the host, and from Container1 when I use --network host in the launch command. Why?
  3. Hosts files both map to 127.0.0.11, I assume this is that same DNS server bridged/shared with the host, but the commands such as nslookup are resolved differently
  4. What does the -h command do when launching a container from CLI?

Thanks, any help appreciated!

  1. Depends on the kind of network you use. When using the host network or the default bridge, /run/systemd/resolve/resolv.conf will be mounted to the containers where the DNS servers of the host are. While your /etc/resolv.conf on your host could point to /run/systemd/resolve/stub-resolv.conf which contains a loopback address which would not be available inside a container which has its own network namespace.
  2. I guess by “point at this same IP” you mean you see the same DNS server in both containers. That is still the DNS server of your host. There is no DNS resolution for contaner IPs with the default docker bridge network. That is only supported in user-defined networks which are also created by Docker Compose for each project.
  3. 127.0.0.11 is what you see when you use a user-defined bridge network. The DNS server is not actually running in your container but this is how Docker handles referring to its own internal DNS server indeed. That will add the ability to resolve domains pointing to container IPs as long as you are in a container in the same docker network. If the domain is not found as a container domain name, the request will still be forwarded to the host’s DNS servers.
  4. You mean -H with the uppercase letter? You can find all parameters in the output of docker --help, but I don’t know about a lowercase -h. I tried to run it and the client warns me about that it was the shorthand for --help but it is deprecated so it is not listed in the help output.

What @rimelek says!

To give you the complete picture: of course, user defined networks can be created using the cli command docker network create {network name}, and Containers can be attached to one or more networks docker run --network {network name} {other args} {repo:tag}.

I don’t know about -h either. I can’t remember using it in the last 10 years. Though, -H is used to configure the socket binding, for instance when you want to bind a tcp port to the docker engine.

Someone on SO I believe mentioned it … -h is the context I recall, sort of a “resolv.conf helper” but could have been a way old post too.

The project I’ve been working on is probably one I won’t complete: putting nginx and a .NET 8 web server (Kestrel) in the same container.

I’m still a bit unclear on what the EXPOSE line in Dockerfile accomplishes (if anything). I have plunged the depths of custom Docker networking, and wish to avoid it as much as possible. It’s kind of like building your own router or bridge, and an alphabet soup of OSI layers are not what I am hoping to get out of this exercise.

I’d also like to see an “apples and oranges” comparison between using yaml-based docker-compose and just a flat Dockerfile, especially when it comes to the networking piece. I see no advantage to isolate my web server behind nginx in its own container, and it seems to add a level of complexity, especially when self-signed certificates are thrown in the mix.

I do appreciate both you and @rimelek having responded to my twisted tale. It’s really helpful in refamiliarizing with the Dockersphere. Thanks a Terabyte guys!

  1. docker run -h foo <container_name> seems to work, but not sure what it accomplishes; How to connect to SQL Server docker container from another container? - Stack Overflow and Dave Guzman’s comment is where I sourced that knowledge.

So the option of docker run and not docker. You forgot to mention that before. But the way to learn about it is the same. Checking the help

docker run --help
  -h, --hostname string                  Container host name

I never use it, but it indeed affects DNS resolution because you can use that to acess the container on a user-defined network in addition to the container name an container id (or in compose, the service name).

The following command (use the actual container name) can show you what can be used fo dns resolution:

docker container inspect CONTAINRNAME

Somewhere at the end of my output:

                    "DNSNames": [
                        "test-name",
                        "a7f7b7383945",
                        "test-host"
                     ]

That has nothing to do with the resolv conf file so to this topic, but I wrote about it: LINK

If you want to learn more about it, please, open another topic, but you could also find other existing topics in which we discussed it.

I don’t think that you need any advanced customization. I almost never do that either, but (if you wanted to refer to that too) docker network create is a very standard and very normal and frequent thing to do. It is just part of using Docker. But if you use Docker Compose, you don’t have to worry about that either.

Again, that is not related to the resolver so you could open a new topic, but A Dockerfile and a compose file is for completely different purposes. You can find tutorials about those too on the sitefrom which I linked the EXPOSE tutorial. Note that there is no network configuration in a Dockerfile. It is not for that, but for creating your base filesystem with some metadata used when the container starts.

Whether it has an advantage or not, depemds on your use case, but if you need an nginx in front of your app, then a separate container is the right way in most of the cases and trying to add both apps in a single container adds a different kind of complexity and not recommended. It could be discussed in another topic as well, but you could also search for something like “why not docker multiple app in a single container” on Google.

Thank you for all the illuminating info @rimelek. However, I’m still stuck with the resolution question (mssql22 is the name passed to the sql server instance via docker run -h mssql22 command):

root@73ca13100861:/app# nslookup mssql22
Server:         192.168.65.7
Address:        192.168.65.7#53

** server can't find mssql22: NXDOMAIN

root@73ca13100861:/app# hostname
73ca13100861
root@73ca13100861:/app# nslookup 73ca13100861
Server:         192.168.65.7
Address:        192.168.65.7#53

** server can't find 73ca13100861: NXDOMAIN

This is regardless of the name I put in to nslookup, it is a container-to-container issue, I fully get that we want mssql22 isolated.

  • Does that mean installing a custom network for communication between app and sql?
  • Can that only be done with docker-compose, and not via Dockerfile?
  • What if I want to ‘expose’ sql to the ‘world’ (meaning local network)? Will that mean using a --network host in the docker run command for app?

TIA,
Alex

Please share the exact commands you used to create both containers, and if a user defined network was created and used, the command to create it as well, so we can re-create it.

You might also want to check out docker compose, as it makes working with containers much easier.
Once the commands are shared, we can help you to translate the docker run commands into a compose file.

Sorry to be a bother, through trial and error I have answered my own question above:

  • Yes, custom network solved all the resolution problems (I am thinking the default bridged network is super isolated in nature)
  • No, Dockerfile for each container, however I am not sure if you can name a custom network in the Dockerfile?
  • Seems to expose sql to the ‘world’ at least on the port I care about (1433) when I connect it to said custom (bridged) network