-
Notifications
You must be signed in to change notification settings - Fork 40k
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
Set up DNS server in containerized mounter path #51645
Conversation
ab1769f
to
e9643ed
Compare
Manually tested. Will add an e2e test soon. The following is the yaml file for the manual test
|
cc @MrHohn |
pkg/kubelet/kubelet.go
Outdated
@@ -745,7 +746,26 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, | |||
// check node capabilities since the mount path is not the default | |||
if len(kubeCfg.ExperimentalMounterPath) != 0 { | |||
kubeCfg.ExperimentalCheckNodeCapabilitiesBeforeMount = false | |||
resolvePath := filepath.Join(strings.TrimSuffix(kubeCfg.ExperimentalMounterPath, "/mounter"), "rootfs", "etc", "resolv.conf") |
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.
Are there any issues with adding the dns servers to the host resolv.conf? Wouldn't that also solve the hostname problem for non-containerized mounts?
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.
Adding kube-dns's service VIP to (edited: host) resolv.conf might introduce too many side effects:
- kube-dns's service VIP may not be routable on host in some environments (ref minkube: Dynamic Flexvolume plugin discovery proposal. community#833 (comment))
- Processes on host namespace will send DNS requests to kube-dns first, then kube-dns will forward requests to upstream. This brings in additional hop and latency.
- kube-dns pod copies resolv.conf from host in order to mirror the upstream DNS server setup, if we set kube-dns's service VIP there, this seems to be a circle?
- If kube-dns dies, it breaks the DNS resolution on host even if upstream server is healthy.
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.
And I think it will breaks dnsPolicy
field on pod.spec as well :)
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.
I guess when we move to CSI, the volume mounts will happen inside a container, and no longer from the host, so in the meantime, for non-containerized mounts using containerized filesystem services, we still only support using IPs and not hostnames.
pkg/kubelet/kubelet.go
Outdated
for _, dns := range klet.clusterDNS { | ||
dnsString = dnsString + fmt.Sprintf("nameserver %s\n", dns) | ||
} | ||
dnsString = dnsString + fmt.Sprintf("options rotate\n") |
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.
fmt.Sprintf("options rotate\n" -> "options rotate\n"?
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.
what is the difference?
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 shouldn't need fmt.Sprintf()
because there is no arguments?
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.
Humm..BTW do we really need "options rotate"
? It won't hurt to do DNS query in the order as defined in resolv.conf right?
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.
Without rotate option, the name still cannot be resolved.
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.
address the comments, PTAL
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.
Yep I think it occasionally worked with "options rotate"
because sometime kube-dns got rotated as the first server.
pkg/kubelet/kubelet.go
Outdated
defer fileHandle.Close() | ||
|
||
dnsString := "" | ||
for _, dns := range klet.clusterDNS { |
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.
Could we just don't write if len(klet.clusterDNS) == 0
?
cc @vishh could you please help approve this PR? |
e9643ed
to
634532c
Compare
pkg/kubelet/kubelet.go
Outdated
} | ||
dnsString = dnsString + "options rotate\n" | ||
glog.V(4).Infof("DNS nameserver string is %s", dnsString) | ||
if _, err = fileHandle.WriteString(dnsString); err != nil { |
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.
Just realize we might have problem here. If we are appending kube-dns as an additional nameserver, dns request will be sent to upstream DNS server first. If we query in-cluster DNS name, upstream server will return NXDOMAIN, then the resolver won't check the other server (kube-dns in this case). Ref: https://unix.stackexchange.com/questions/150703/can-subsequent-nameservers-defined-in-etc-resolv-conf-be-used-if-the-previous-n
I think we should overwrite the nameserver entry instead of appending a new one?
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.
Does kube-dns forward to upstream dns if it can't resolve the name?
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.
Yep it will :)
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.
So basically overwrite is enough. If kube-dns could not resolve it, upstream dns will work (just similar to use host dns nameserver)?
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.
So basically overwrite is enough. If kube-dns could not resolve it, upstream dns will work (just similar to use host dns nameserver)?
Correct, this is exactly the way cluster DNS works in k8s :)
634532c
to
6a1769d
Compare
@krzyzacy Robot went crazy here :O |
/release-note-none |
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.
This LGTM, did it work locally?
pkg/kubelet/kubelet.go
Outdated
dnsString = dnsString + fmt.Sprintf("nameserver %s\n", dns) | ||
} | ||
|
||
ioutil.WriteFile(resolvePath, []byte(dnsString), 0600) |
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.
In this way the mounter wouldn't be able to utilize the internal search paths (e.g. "c.[PROJECT_ID].internal.", "google.internal."
), but I guess that is okay?
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.
Oh and we should check error 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.
What does it mean to not utilize the internal search paths? The NFS or Gluster service could be setup directly on a GCE instance instead of as a Pod.
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 means user will have to specify FQDN instead of relying on resolver automatically appending those search paths.
The NFS or Gluster service could be setup directly on a GCE instance instead of as a Pod.
Humm, then seems like this will change the behavior (e.g. INSTANCE_NAME
alone is not resolvable anymore) and may break existing users?
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.
If a user is migrating from debian to gci, then it will break.
In GCI, we had this timeline:
Initial: DNS resolution failed to work at all
1.6.?, 1.7.? patch: DNS resolution works for non-Pod based services.
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.
An alternative is to rewrite the nameserver only, while keeping the original search paths in resolv.conf. There are some similar logic in GetClusterDNS():
kubernetes/pkg/kubelet/kubelet.go
Lines 1341 to 1344 in 7c70dec
hostDNS, hostSearch, err = kl.parseResolvConf(f) | |
if err != nil { | |
return nil, nil, false, err | |
} |
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.
ok, I also write the search string as suggested. So this time non-pod nfs service will also work, right?
@grodrigues3 whoops, who suppose to own this munger? |
I think this needs a release note because it's going to be fixing a user-facing issue with DNS resolution of NFS and Gluster services. But we need to make sure that this solution will work with both pod-based services and non-pod based services. |
CI is down? all CIs didn't report status. |
/test all |
6a1769d
to
8c6f989
Compare
fa2c4df
to
d5434e0
Compare
@MrHohn I rebased it. |
/lgtm |
/approve |
manually added cc: @kubernetes/kubernetes-release-managers |
/retest |
/retest Review the full test history for this PR. |
/retest |
/retest Review the full test history for this PR. |
During NFS/GlusterFS mount, it requires to have DNS server to be able to resolve service name. This PR gets the DNS server ip from kubelet and add it to the containerized mounter path. So if containerized mounter is used, service name could be resolved during mount
d5434e0
to
3d4bc93
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: MrHohn, bowei, jingxu97, vishh No associated issue. Update pull-request body to add a reference to an issue, or get approval with The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
/retest |
@jingxu97: The following test failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Automatic merge from submit-queue (batch tested with PRs 51186, 50350, 51751, 51645, 51837) |
@jingxu97 could you please add a SIG to this PR please? Thanks! |
cc @kubernetes/sig-storage-misc |
I'd really appreciate if this was a generic PR that would be usable outside of GCE/GKE. It's not only Google who needs to mount nfs/gluster volumes hosted by Kybernetes! |
During NFS/GlusterFS mount, it requires to have DNS server to be able to
resolve service name. This PR gets the DNS server ip from kubelet and
add it to the containerized mounter path. So if containerized mounter is
used, service name could be resolved during mount
Release note: