Warn when no external DNS nameservers are found

Since commit 925b484 ("No fallback nameservers for internal
resolver"), if the host's resolv.conf has no nameservers and
no servers are supplied via config, the internal resolver will
not use Google's DNS - so the container will not be able to
resolve external DNS requests.

That can happen when container's are "restart-always" and the
docker daemon starts before the host's DNS is configured.

So, to highlight the issue (which may not be an error, but
probably is), include a warning in the container's resolv.conf
file.

Also, log a warning - logs currently say "No non-localhost DNS
nameservers are left in resolv.conf. Using default external
servers". But, that's misleading because it's from an initial
resolv.conf setup, before the internal resolver configured without
those fallbacks - we'll drop the fallbacks completely once the
default bridge has an internal resolver).

Signed-off-by: Rob Murray <rob.murray@docker.com>
This commit is contained in:
Rob Murray
2025-04-17 10:51:06 +01:00
parent 3f46cadf39
commit 619f1ddd05
4 changed files with 21 additions and 4 deletions

View File

@@ -85,10 +85,10 @@ type metadata struct {
SearchOverride bool
OptionsOverride bool
NDotsFrom string
UsedDefaultNS bool
Transform string
InvalidNSs []string
ExtNameServers []ExtDNSEntry
Warnings []string
}
// Load opens a file at path and parses it as a resolv.conf file.
@@ -229,7 +229,7 @@ func (rc *ResolvConf) TransformForLegacyNw(ipv6 bool) {
if len(rc.nameServers) == 0 {
log.G(context.TODO()).Info("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers")
rc.nameServers = defaultNSAddrs(ipv6)
rc.md.UsedDefaultNS = true
rc.md.Warnings = append(rc.md.Warnings, "Used default nameservers.")
}
}
@@ -280,6 +280,9 @@ func (rc *ResolvConf) TransformForIntNS(
}
rc.md.Transform = "internal resolver"
if len(rc.md.ExtNameServers) == 0 {
rc.md.Warnings = append(rc.md.Warnings, "NO EXTERNAL NAMESERVERS DEFINED")
}
return append([]ExtDNSEntry(nil), rc.md.ExtNameServers...), nil
}
@@ -325,8 +328,8 @@ options {{join . " "}}
{{join . "\n"}}
{{end}}{{if .Comments}}
# Based on host file: '{{.Md.SourcePath}}'{{with .Md.Transform}} ({{.}}){{end}}
{{if .Md.UsedDefaultNS -}}
# Used default nameservers.
{{range .Md.Warnings -}}
# {{.}}
{{end -}}
{{with .Md.ExtNameServers -}}
# ExtServers: {{.}}

View File

@@ -410,6 +410,10 @@ func TestRCTransformForIntNS(t *testing.T) {
reqdOptions: []string{"ndots:0", "attempts:3", "edns0", "trust-ad"},
expExtServers: []ExtDNSEntry{mke("127.0.0.53", true)},
},
{
name: "No config",
input: "",
},
}
for _, tc := range testcases {

View File

@@ -0,0 +1,5 @@
nameserver 127.0.0.11
# Based on host file: '/etc/resolv.conf' (internal resolver)
# NO EXTERNAL NAMESERVERS DEFINED
# Overrides: []

View File

@@ -219,6 +219,11 @@ func (sb *Sandbox) restoreHostsPath() {
}
func (sb *Sandbox) setExternalResolvers(entries []resolvconf.ExtDNSEntry) {
if len(entries) == 0 {
log.G(context.TODO()).WithField("cid", sb.ContainerID()).Warn("DNS resolver has no external nameservers")
sb.extDNS = nil
return
}
sb.extDNS = make([]extDNSEntry, 0, len(entries))
for _, entry := range entries {
sb.extDNS = append(sb.extDNS, extDNSEntry{