-
Notifications
You must be signed in to change notification settings - Fork 39.7k
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
Correctly handle named pipe host mounts for Windows #69484
Conversation
Signed-off-by: Deep Debroy <ddebroy@docker.com>
/sig storage |
/assign @dchen1107 |
/kind bug |
/test pull-kubernetes-verify |
/test pull-kubernetes-local-e2e-containerized |
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
@PatrickLang Would you like also take a look?
/retest |
pkg/volume/util/util.go
Outdated
@@ -945,6 +945,13 @@ func CheckPersistentVolumeClaimModeBlock(pvc *v1.PersistentVolumeClaim) bool { | |||
return utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && pvc.Spec.VolumeMode != nil && *pvc.Spec.VolumeMode == v1.PersistentVolumeBlock | |||
} | |||
|
|||
func IsWindowsNamedPipe(goos, path string) bool { | |||
if goos == "windows" && strings.HasPrefix(path, `\\.\pipe\`) { |
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.
@PatrickLang @atomaras Does named pipe also starts with \\.\pipe\
? what about upper case like \\.\Pipe\
?
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 also supports like this: \.\pipe\
...
docker run -it --rm -v \.\pipe\docker_engine:\.\pipe\docker_engine microsoft:windowsservercore:1803 powershell
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 think the logic here needs to be aligned with logic in the runtime. Here are some references:
https://github.com/moby/moby/blob/master/volume/mounts/windows_parser.go#L44
and
https://github.com/moby/moby/blob/master/libcontainerd/client_local_windows.go#L303
Both consider \\.\pipe
as the standard named pipe prefix for local pipes on Windows.
@andyzhangx, \.\pipe\...
is rejected by Docker:
C:\k>docker run -ti -v \.\pipe\docker_engine:\.\pipe\docker_engine microsoft/windowsservercore:1803
docker: Error response from daemon: invalid volume specification: '\.\pipe\docker_engine:\.\pipe\docker_engine'.
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.
The underlying CreateFileW()
is case insensitive by default, so \\.\pipe\foo
== \\.\Pipe\foo
https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilew
If it's constrained in the lower layer (moby / containerd), then the same check should be used here. I think it's ok as-is
I seems like |
/test pull-kubernetes-local-e2e-containerized |
/retest |
I talked to @ddebroy on Slack, and this requires Docker EE-basic 18.03 or later. If you're testing on an Azure VM, you need to be sure to upgrade Docker first. This is tracked at Azure/acs-engine#3852 |
pkg/kubelet/kubelet_pods.go
Outdated
containerPath := mount.MountPath | ||
if runtime.GOOS == "windows" { | ||
if (strings.HasPrefix(hostPath, "/") || strings.HasPrefix(hostPath, "\\")) && !strings.Contains(hostPath, ":") { | ||
if !volumeutil.IsWindowsNamedPipe(runtime.GOOS, hostPath) && (strings.HasPrefix(hostPath, "/") || strings.HasPrefix(hostPath, "\\")) && !strings.Contains(hostPath, ":") { |
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.
nit - can you preserve the parenthesis so that the grouping is still easy to see?
@Random-Liu @saad-ali PTAL if this looks good to be approved. Not sure if @dchen1107 (who was originally assigned) is online/offline. |
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.
Couple of minor comments.
/approve
// IsWindowsUNCPath checks if path is prefixed with \\ | ||
// This can be used to skip any processing of paths | ||
// that point to SMB shares, local named pipes and local UNC path | ||
func IsWindowsUNCPath(goos, path string) bool { |
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.
nit, why is goos
a parameter and not generated inside this method?
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.
goos
as a parameter allows for an easy way to unit-test the function to make sure in other OS environments, there are no unexpected results.
pkg/kubelet/kubelet_pods.go
Outdated
@@ -218,11 +218,13 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h | |||
// Docker Volume Mounts fail on Windows if it is not of the form C:/ | |||
containerPath := mount.MountPath | |||
if runtime.GOOS == "windows" { | |||
if (strings.HasPrefix(hostPath, "/") || strings.HasPrefix(hostPath, "\\")) && !strings.Contains(hostPath, ":") { | |||
// Append C: only if it looks like a local path. Do not process UNC path/SMB shares/named pipes | |||
if (strings.HasPrefix(hostPath, "/") || strings.HasPrefix(hostPath, "\\")) && !strings.Contains(hostPath, ":") && !volumeutil.IsWindowsUNCPath(runtime.GOOS, hostPath) { |
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.
IsWindowsUNCPath is checking for prefix \ e.g. \foo\bar which is different from what strings.HasPrefix(hostPath, "\") is checking for: \ vs \
That is very subtle. Add a comment explaining this, so folks are less likely to "fix" this in the future by mistake. Also is there any unit test that can be added to kubelet_pods_tests.go
for this to catch regressions?
For other reviewers - this change allows Windows mounts that are equivalent to https://kubernetes.io/docs/concepts/policy/pod-security-policy/#volumes-and-file-systems |
/lgtm |
/assign @yujuhong |
Signed-off-by: Deep Debroy <ddebroy@docker.com>
Reviewed and left comments. |
Signed-off-by: Deep Debroy <ddebroy@docker.com>
@yujuhong @PatrickLang @saad-ali thanks for reviewing so far. I have addressed the review comments ... PTAL. |
|
||
// IsWindowsLocalPath checks if path is a local path | ||
// prefixed with "/" or "\" like "/foo/bar" or "\foo\bar" | ||
func IsWindowsLocalPath(goos, path string) bool { |
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.
Should MakeAbsolutePath
call this function instead?
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.
@yujuhong I would prefer to keep MakeAbsolutePath
as is for now in the context of this PR. The scope of this PR is to enable named pipe mounting support in Windows and that code path skips MakeAbsolutePath
. MakeAbsolutePath
is called in a couple of contexts (not involving named pipes) and maybe refactored in a separate PR later?
pkg/kubelet/kubelet_pods.go
Outdated
hostPath = "c:" + hostPath | ||
} | ||
if volumeutil.IsWindowsLocalPath(runtime.GOOS, hostPath) { | ||
hostPath = "c:" + hostPath |
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.
Should this call MakeAbsolutePath
instead?
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.
@yujuhong yes, done.
Signed-off-by: Deep Debroy <ddebroy@docker.com>
/retest |
@yujuhong PTAL |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ddebroy, PatrickLang, saad-ali, yujuhong The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
What this PR does / why we need it:
Windows named pipes in host mounts were not being correctly handled and passed through to the container runtime. This PR adds support to detect named pipes in Windows and skip the processing associated with regular file system based host mount paths in Windows.
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when PR gets merged):Fixes # #67147
Special notes for your reviewer:
Tested the following spec spawns up the pod container on Windows with the mount paths to \\.\pipe\docker_pipe correctly configured:
docker inspect
output for above container:Release note: