Run pod bind mounts in the host mount namespace via nsenter.

Kubelet checks volume mounts from the host namespace, so NodePublishVolume
must mkdir and bind-mount the pod target path on the host, not only inside
the CSI plugin container.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-06 08:57:30 +03:30
co-authored by Cursor
parent 62c26f6fda
commit 802c9b91f7
3 changed files with 45 additions and 39 deletions
+27 -5
View File
@@ -106,16 +106,38 @@ func cleanupMountPoint(target string, mounter *mount.SafeFormatAndMount) error {
return mount.CleanupMountPoint(target, mounter, true)
}
func hostMount(args ...string) ([]byte, error) {
return exec.Command("nsenter", append([]string{"--target", "1", "--mount", "--"}, args...)...).CombinedOutput()
}
func isHostMounted(path string) bool {
out, err := hostMount("findmnt", "-n", path)
return err == nil && strings.TrimSpace(string(out)) != ""
}
func bindMount(source, target string) error {
if !isMounted(source) {
if !isHostMounted(source) && !isMounted(source) {
return fmt.Errorf("staging path %s is not mounted", source)
}
if isMounted(target) {
if isHostMounted(target) {
return nil
}
mounter := mount.New("")
if err := mounter.Mount(source, target, "", []string{"bind"}); err != nil {
return fmt.Errorf("bind mount %s -> %s: %w", source, target, err)
if out, err := hostMount("mkdir", "-p", target); err != nil {
return fmt.Errorf("create bind mount target %s: %w: %s", target, err, strings.TrimSpace(string(out)))
}
if out, err := hostMount("mount", "--bind", source, target); err != nil {
return fmt.Errorf("bind mount %s -> %s: %w: %s", source, target, err, strings.TrimSpace(string(out)))
}
return nil
}
func unmountHost(path string) error {
if !isHostMounted(path) {
return nil
}
out, err := hostMount("umount", path)
if err != nil {
return fmt.Errorf("umount %s: %w: %s", path, err, strings.TrimSpace(string(out)))
}
return nil
}