Skip to content

Better selection of DNS server#41022

Merged
AkihiroSuda merged 1 commit intomoby:masterfrom
thaJeztah:smarter_resolv
Jun 25, 2020
Merged

Better selection of DNS server#41022
AkihiroSuda merged 1 commit intomoby:masterfrom
thaJeztah:smarter_resolv

Conversation

@thaJeztah
Copy link
Copy Markdown
Member

@thaJeztah thaJeztah commented May 25, 2020

Commit e353e7e (#37485) updated selection of the resolv.conf file to use in situations where systemd-resolvd is used as a resolver.

If a host uses systemd-resolvd, the system's /etc/resolv.conf file is
updated to set 127.0.0.53 as DNS, which is the local IP address for
systemd-resolvd. The DNS servers that are configured by the user will now
be stored in /run/systemd/resolve/resolv.conf, and systemd-resolvd acts
as a forwarding DNS for those.

Originally, Docker copied the DNS servers as configured in /etc/resolv.conf
as default DNS servers in containers, which failed to work if systemd-resolvd
is used (as 127.0.0.53 is not available inside the container's networking
namespace). To resolve this, e353e7e instead
detected if systemd-resolvd is in use, and in that case copied the "upstream"
DNS servers from the /run/systemd/resolve/resolv.conf configuration.

While this worked for most situations, it had some downsides, among which:

  • we're skipping systemd-resolvd altogether, which means that we cannot take
    advantage of addition functionality provided by it (such as per-interface
    DNS servers)
  • when updating DNS servers in the system's configuration, those changes were
    not reflected in the container configuration, which could be problematic in
    "developer" scenarios, when switching between networks.

This patch changes the way we select which resolv.conf to use as template
for the container's resolv.conf;

  • in situations where a custom network is attached to the container, and the
    embedded DNS is available, we use /etc/resolv.conf unconditionally. If
    systemd-resolvd is used, the embedded DNS forwards external DNS lookups to
    systemd-resolvd, which in turn is responsible for forwarding requests to
    the external DNS servers configured by the user.
  • if the container is running in "host mode" networking, we also use the
    DNS server that's configured in /etc/resolv.conf. In this situation, no
    embedded DNS server is available, but the container runs in the host's
    networking namespace, and can use the same DNS servers as the host (which
    could be systemd-resolvd or DNSMasq
  • if the container uses the default (bridge) network, no embedded DNS is
    available, and the container has its own networking namespace. In this
    situation we check if systemd-resolvd is used, in which case we skip
    systemd-resolvd, and configure the upstream DNS servers as DNS for the
    container. This situation is the same as is used currently, which means
    that dynamically switching DNS servers won't be supported for these
    containers.

Signed-off-by: Sebastiaan van Stijn [email protected]

- What I did

- How I did it

- How to verify it

- Description for the changelog

- A picture of a cute animal (not mandatory but encouraged)

Commit e353e7e updated selection of the
`resolv.conf` file to use in situations where systemd-resolvd is used as
a resolver.

If a host uses `systemd-resolvd`, the system's `/etc/resolv.conf` file is
updated to set `127.0.0.53` as DNS, which is the local IP address for
systemd-resolvd. The DNS servers that are configured by the user will now
be stored in `/run/systemd/resolve/resolv.conf`, and systemd-resolvd acts
as a forwarding DNS for those.

Originally, Docker copied the DNS servers as configured in `/etc/resolv.conf`
as default DNS servers in containers, which failed to work if systemd-resolvd
is used (as `127.0.0.53` is not available inside the container's networking
namespace). To resolve this, e353e7e instead
detected if systemd-resolvd is in use, and in that case copied the "upstream"
DNS servers from the `/run/systemd/resolve/resolv.conf` configuration.

While this worked for most situations, it had some downsides, among which:

- we're skipping systemd-resolvd altogether, which means that we cannot take
  advantage of addition functionality provided by it (such as per-interface
  DNS servers)
- when updating DNS servers in the system's configuration, those changes were
  not reflected in the container configuration, which could be problematic in
  "developer" scenarios, when switching between networks.

This patch changes the way we select which resolv.conf to use as template
for the container's resolv.conf;

- in situations where a custom network is attached to the container, and the
  embedded DNS is available, we use `/etc/resolv.conf` unconditionally. If
  systemd-resolvd is used, the embedded DNS forwards external DNS lookups to
  systemd-resolvd, which in turn is responsible for forwarding requests to
  the external DNS servers configured by the user.
- if the container is running in "host mode" networking, we also use the
  DNS server that's configured in `/etc/resolv.conf`. In this situation, no
  embedded DNS server is available, but the container runs in the host's
  networking namespace, and can use the same DNS servers as the host (which
  could be systemd-resolvd or DNSMasq
- if the container uses the default (bridge) network, no embedded DNS is
  available, and the container has its own networking namespace. In this
  situation we check if systemd-resolvd is used, in which case we skip
  systemd-resolvd, and configure the upstream DNS servers as DNS for the
  container. This situation is the same as is used currently, which means
  that dynamically switching DNS servers won't be supported for these
  containers.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
@thaJeztah thaJeztah marked this pull request as ready for review May 26, 2020 07:11
@thaJeztah
Copy link
Copy Markdown
Member Author

@arkodg @cpuguy83 PTAL (let me know if this approach makes sense)

// namespace, so both `/etc/hosts` and `/etc/resolv.conf` should be the same
// as on the host itself. The container gets a copy of these files, but they
// may be symlinked, so resolve the original path first.
etcHosts, err := filepath.EvalSymlinks("/etc/hosts")
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is new; previously we didn't check if these were symlinked (which at least in case of /etc/resolv.conf may be the case for systems that were upgraded from older versions)

Copy link
Copy Markdown
Member

@cpuguy83 cpuguy83 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thaJeztah
Copy link
Copy Markdown
Member Author

@xinfengliu PTAL, perhaps you have thought as well if this makes sense 🤗

@arkodg
Copy link
Copy Markdown
Contributor

arkodg commented May 28, 2020

thanks for the detailed code comments !
can we add tests for these 🤗 ?

@xinfengliu
Copy link
Copy Markdown
Contributor

@xinfengliu PTAL, perhaps you have thought as well if this makes sense 🤗

@thaJeztah Sorry I'm not familiar with this part of codes, not able to comment.

@thaJeztah
Copy link
Copy Markdown
Member Author

can we add tests for these 🤗 ?

Thinking what the best way is to test this, as we don't run the daemons with systemd inside the docker-in-docker containers; do you have suggestions for that?

Copy link
Copy Markdown
Contributor

@arkodg arkodg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya an integration test will be non trivial, approving this PR
thanks !

@thaJeztah
Copy link
Copy Markdown
Member Author

@AkihiroSuda LGTY?

@AkihiroSuda AkihiroSuda merged commit 3621812 into moby:master Jun 25, 2020
@thaJeztah thaJeztah deleted the smarter_resolv branch June 25, 2020 14:01
@thaJeztah thaJeztah added this to the 20.03.0 milestone Jul 3, 2020
@vincentbernat
Copy link
Copy Markdown
Contributor

Would it be possible this commit to also be pushed in 19.03 branch? There are more and more systemd-resolved based setup.

@thaJeztah
Copy link
Copy Markdown
Member Author

@arkodg @cpuguy83 WDYT? Safe to backport? I recall we had some discussion about it, but don't recall where we ended up.

(I did notice there was a change that was discussed that somehow didn't make it in this PR 🤔 opened #41335 to address that)

@cpuguy83
Copy link
Copy Markdown
Member

It seems ok but also risky... I don't know...
Maybe after 20.0x is out and this has some real use?

@thaJeztah
Copy link
Copy Markdown
Member Author

Opened a draft backport #41374, so that we can discuss/consider

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants