-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: check network mode when choosing resolv.conf #5207
Conversation
6888dc0
to
02bdc28
Compare
// resolver it's also possible to use nameservers on the host's loopback | ||
// interface. Once legacy networking is removed, this can always return | ||
// defaultPath. | ||
func Path() string { | ||
func Path(netMode pb.NetMode) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes in vendor/github.com/docker/docker
should be first done in https://github.com/moby/moby repo and vendored back here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to figure out a way for build containers to use something similar to the internal resolver used by custom bridge networks (127.0.0.11
) - it proxies DNS requests from the container, making upstream requests from the host's network namespace when necessary.
(At the moment, we use addresses from the host's resolv.conf
, but they may not work in the container's network namespace - including nameservers with localhost addresses like systemd's 127.0.0.53
, or IPv6 nameservers in an IPv4-only build container. If there are no nameservers the container can use, we fall back to Google's DNS.)
Once that's done, we'll be able to completely get rid of the code that looks at /run/systemd/resolve/resolv.conf
(and the Google DNS fallbacks, and the default-bridge network would be able to use the internal resolver, making it more like other networks).
However, once that's done, the build container will still need a special-case for host networking. (It just needs a copy of the host's resolv.conf
in that case. There's no need for a DNS proxy, because there's no container namespace to escape from).
So, for this fix, it might be best to deal with that special case in executor/oci/resolvconf.go
now - for host networking, just don't call resolvconf.Path
and use /etc/resolv.conf
? (Then, no need to update vendored code.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea. I've refactored the code and tested it which seems to work the same.
5b9c07b
to
4538de4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's simplified things a bit - thank you!
The commits will need squashing, and could you update the commit message to explain the change? (Just something like "In host networking mode, unconditionally use "/etc/resolv.conf" rather than systemd's config".)
I was a bit unsure what happens here and if it might get problematic in consecutive builds with different networking modes. Maybe someone can explain this to me.
Looks like it's ok because it already had to deal with removing/not-removing localhost nameservers, so the output path depends on netMode
...
buildkit/executor/oci/resolvconf.go
Lines 29 to 32 in 5c66a49
p := filepath.Join(stateDir, "resolv.conf") | |
if netMode == pb.NetMode_HOST { | |
p = filepath.Join(stateDir, "resolv-host.conf") | |
} |
... and it's covered by
TestRegenerateResolvconfToRemoveLocalDNS
/ TestRegenerateResolvconfToAddLocalDNS
. But, that needs checking by someone who knows this code better than me.
(Not directly related to this change - but lastNotEmpty
is never set to true, so it doesn't do anything. Probably not causing any issues, but I'm not sure what the intention was. I think if the input file is removed, unlikely as that is, an old output file will be left as-is rather than getting cleared - maybe it was something to do with that?)
Update: "I think if the input file is removed, unlikely as that is, an old output file will be left as-is rather than getting cleared" ... oh, not that - because an empty path is returned in that case. Maybe lastNotEmpty
could be removed. (Not needed as part of this change though.)
executor/oci/resolvconf_test.go
Outdated
@@ -111,7 +111,7 @@ func TestResolvConf(t *testing.T) { | |||
t.Cleanup(func() { | |||
resolvconfPath = oldResolvconfPath | |||
}) | |||
resolvconfPath = func() string { | |||
resolvconfPath = func(netMode pb.NetMode) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's perhaps worth checking this is called with the expected netMode
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I've had to move the whole block into the iterator over the network modes. Can you please check if that's okay like this?
4538de4
to
be338db
Compare
Signed-off-by: Kai Takac <[email protected]>
be338db
to
fa157f4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Cool, thanks for the review! |
Hi,
this fixes #2404 . Instead of always checking for systemd-resolved it's sufficient to do so only if the run does not happen within the host networking mode.
I was a bit unsure what happens here and if it might get problematic in consecutive builds with different networking modes. Maybe someone can explain this to me.
BR Kai