compose icon indicating copy to clipboard operation
compose copied to clipboard

bridge DNS does not work when referencing a service alias as dns

Open samrocketman opened this issue 6 years ago • 32 comments

Description of the issue

Referencing the dns key in YAML does not work when the value is a service alias of another container in the docker-compose.yml file.

Sample compose file.

networks:
  internal:
     driver: bridge
services:
  dnsmasq:
    # ... some container configuration which should be reachable from the DNS host "dnsmasq"
    networks:
      - internal
  my-service:
    # NOTE: setting DNS to docker-compose service alias does not work
    dns: dnsmasq
    networks:
      - internal

Context information (for bug reports)

$ docker-compose version
docker-compose version 1.22.0, build f46880fe
docker-py version: 3.4.1
CPython version: 3.6.6
OpenSSL version: OpenSSL 1.1.0f  25 May 2017
$ docker version
Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:24:56 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:23:21 2018
  OS/Arch:          linux/amd64
  Experimental:     false

Broken config https://github.com/samrocketman/docker-compose-ha-consul-vault-ui/blob/03ba4d1c5875e3b1c10d85425316ffa7d064ca74/docker-compose.yml

Steps to reproduce the issue

  1. docker-compose run dns-troubleshoot
  2. dig example.com
  3. dig @dnsmasq example.com

Observed result

dig example.com fails with the following message:

/ # dig example.com
; <<>> DiG 9.10.4-P3 <<>> example.com
;; global options: +cmd
;; connection timed out; no servers could be reached

/ # cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0

However, dig @dnsmasq example.com succeeds.

/ # dig @dnsmasq example.com

; <<>> DiG 9.10.4-P3 <<>> @dnsmasq example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4516
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;example.com.			IN	A

;; ANSWER SECTION:
example.com.		4335	IN	A	93.184.216.34

;; Query time: 0 msec
;; SERVER: 172.19.0.2#53(172.19.0.2)
;; WHEN: Wed Sep 12 04:53:29 UTC 2018
;; MSG SIZE  rcvd: 56

Expected result

I expect both dig example.com and dig @dnsmasq example.com to work the same way.

Additional information

I installed docker-compose by downloading the go binary from GitHub releases and adding it to a location available in my $PATH.

samrocketman avatar Sep 12 '18 04:09 samrocketman

It is desirable to use a custom dnsmasq container so that I can use consul DNS across all of my containers. Example, here I look up DNS using consul DNS.

/ # dig @dnsmasq consul.service.consul

; <<>> DiG 9.10.4-P3 <<>> @dnsmasq consul.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1598
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 4

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;consul.service.consul.		IN	A

;; ANSWER SECTION:
consul.service.consul.	0	IN	A	172.16.238.5
consul.service.consul.	0	IN	A	172.16.238.3
consul.service.consul.	0	IN	A	172.16.238.4

;; ADDITIONAL SECTION:
consul.service.consul.	0	IN	TXT	"consul-network-segment="
consul.service.consul.	0	IN	TXT	"consul-network-segment="
consul.service.consul.	0	IN	TXT	"consul-network-segment="

;; Query time: 0 msec
;; SERVER: 172.16.238.2#53(172.16.238.2)
;; WHEN: Wed Sep 12 05:05:22 UTC 2018
;; MSG SIZE  rcvd: 206

samrocketman avatar Sep 12 '18 05:09 samrocketman

The only fix currently is to statically set the DNS and not use the docker-compose service name in the dns YAML key.

ref: https://github.com/samrocketman/docker-compose-ha-consul-vault-ui/commit/3b5f422dbf386056d1a11ba9e45de05a98a9487f

That is to say, the bug still exists but there's currently a workaround until it is fixed.

samrocketman avatar Sep 12 '18 05:09 samrocketman

Hi @samrocketman

As far as I can tell, the issue you're reporting is a Docker networking issue, not a Compose issue. If you concur, please open an issue on the moby/moby tracker where it can more readily be addressed.

shin- avatar Sep 12 '18 18:09 shin-

I don't understand if it's a docker networking issue. I've only seen docker-compose service aliases used in docker-compose as hostnames. So I assumed it was this project.

I can copy my issue to moby/moby if that's what you think is appropriate. I don't have the expertise to determine which project is appropriate to address the root cause of this issue.

Please let me know.

samrocketman avatar Sep 13 '18 08:09 samrocketman

I'd like to see this issue get resolved as well. Is there an update on whether this is actually a docker-compose issue or does a new issue need to be filed with Docker? If it does need to be filed with moby/moby, can someone with an understanding of why it's a moby/moby issue expand upon it so we can file it correctly? Thanks.

chizou avatar Apr 10 '19 17:04 chizou

This is because a DNS server should be specified by IP-address, so using a name won't work (unless some step was added to resolve the IP based on the name, and use that).

There's a tracking issue for that in the cli repository; https://github.com/docker/cli/issues/385 (I think there's also one in the Moby repository, but I'd have to search for that)

thaJeztah avatar Apr 11 '19 11:04 thaJeztah

I understand that /etc/resolve.conf only takes IP’s in Linux (and why that is). My hope is that docker-compose would resolve the DNS IP from the compose service under the hood and do the right thing with it to expose the DNS automatically.

FWIW I have a workaround but it’s not ideal because I need to statically set the network and IP.

  • set network https://github.com/samrocketman/docker-compose-ha-consul-vault-ui/blob/a91f37e57066cd8d662e7c614f9cc47279c194d2/docker-compose.yml#L5-L11
  • set DNS server IP so that other containers can use it https://github.com/samrocketman/docker-compose-ha-consul-vault-ui/blob/a91f37e57066cd8d662e7c614f9cc47279c194d2/docker-compose.yml#L66-L68
  • other containers configured to use the DNS https://github.com/samrocketman/docker-compose-ha-consul-vault-ui/blob/a91f37e57066cd8d662e7c614f9cc47279c194d2/docker-compose.yml#L100-L102

In case someone finds it useful.

samrocketman avatar Apr 12 '19 14:04 samrocketman

My hope is that docker-compose would resolve the DNS IP from the compose service under the hood and do the right thing with it to expose the DNS automatically.

This is exactly what I'd like to see as well. Hardcoding IP addresses for this specific purpose is less than ideal.

chizou avatar Apr 12 '19 16:04 chizou

I had the same problem.

And I thought about another solution. This solution is only available for nginx container:

version: '3'
services:
  openresty:
    image: openresty/openresty:1.13.6.2-alpine
    volumes:
      - ./nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf
    ports:
      - 80:80
    dns:
      - 127.0.0.1
    links:
      - dns-server
  dns-server:
    image: jpillora/dnsmasq
    cap_add:
      - NET_ADMIN
    ports:
      - 53:53/tcp
      - 8080:8080

nginx.conf has such a code snippet:

stream {
    upstream dns {
        server dns-server:53;
    }

    server{
        listen 53 udp;
        proxy_connect_timeout 1s;
        proxy_pass dns;
    }
}

Veitor avatar Apr 17 '19 09:04 Veitor

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Oct 15 '19 03:10 stale[bot]

This is still desirable so should not be stale IMO.

samrocketman avatar Oct 21 '19 02:10 samrocketman

This issue has been automatically marked as not stale anymore due to the recent activity.

stale[bot] avatar Oct 21 '19 02:10 stale[bot]

This is still desirable so should not be stale IMO.

samrocketman avatar Mar 12 '20 02:03 samrocketman

Same issue. I expect this behaviour as well.

ricardoper avatar Mar 24 '20 07:03 ricardoper

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Sep 20 '20 07:09 stale[bot]

This is still desirable so should not be stale IMO.

samrocketman avatar Sep 24 '20 13:09 samrocketman

This issue has been automatically marked as not stale anymore due to the recent activity.

stale[bot] avatar Sep 24 '20 13:09 stale[bot]

@shin- can we remove the kind/question label? This is not a question. It is a docker-compose enhancement request originally reported as a bug since it made intuitive sense. Considering most things can be referenced by service name in the compose file it made sense you should be able to do the same in the DNS field and have docker-compose translate that to the service IP.

I feel like kind/question makes this issue not an obvious feature request so it has been overlooked for 2 years.

Why this is a docker-compose issue

docker-compose has some glue logic which makes using docker easy. For example, if you reference a service name foo there is no such reference in the docker daemon. docker-compose translates foo into a docker container (or group of docker containers) in dockerd backend.

The syntax exposed by docker-compose should support docker-compose services in the same way that the docker-compose syntax supports docker-compose services in other fields. To put another way, the brief syntax in docker-compose translates into API calls on the dockerd backend. This translation should occur for the service name in the DNS field.

samrocketman avatar Sep 26 '20 14:09 samrocketman

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Mar 26 '21 12:03 stale[bot]

This issue is not stale.

samrocketman avatar Apr 03 '21 03:04 samrocketman

This issue has been automatically marked as not stale anymore due to the recent activity.

stale[bot] avatar Apr 03 '21 03:04 stale[bot]

@chris-crone please review my prior comments; can the label kind/question be removed? It is hiding this valid feature request making it opaque if someone is searching for issues to contribute. Pinging you since I noticed you merged a pull request recently.

Thanks in advance.

samrocketman avatar Apr 03 '21 03:04 samrocketman

I've updated the labels. From what @thaJeztah said, it appears that we need to make Engine changes before this is possible.

chris-crone avatar Apr 06 '21 09:04 chris-crone

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Nov 09 '21 20:11 stale[bot]

This is still desirable. Commenting so not stale.

samrocketman avatar Nov 10 '21 02:11 samrocketman

This issue has been automatically marked as not stale anymore due to the recent activity.

stale[bot] avatar Nov 10 '21 02:11 stale[bot]

Would need to extend https://github.com/compose-spec/compose-spec/blob/master/spec.md#dns so that we clarify a service name can be used to set dns. In terms of implementation, this implies an implicit depends_on being set between service and dns provider

ndeloof avatar Feb 22 '22 13:02 ndeloof

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Sep 21 '22 10:09 stale[bot]

Hello, please do not close this issue as it would be a nice feature

Oliv4945 avatar Sep 23 '22 19:09 Oliv4945

being able to support this comes with multiple challenges:

  1. compose would need to support dns being set with a service name. This is the easy part: we could just add support for dns: "service:foo like we do in a few other places
  2. dns MUST be set with an IP, not container name. docker CLI has an explicit check for this, but it seems docker engine silently ignore invalid valid (need to be confirmed). The challenge here, is that IP is only assigned to the dnsmasq container when started, but with current implementation, compose creates ALL services THEN starts them in dependency order.

Addressing 2. would be a major change in compose design, and would prevent use of the docker compose create command.

ndeloof avatar May 14 '23 09:05 ndeloof