diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 10bbae78cf..761cd49df3 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -360,7 +360,7 @@ func UnsecuredDependencies(s *options.KubeletServer) (*kubelet.Dependencies, err var writer kubeio.Writer = &kubeio.StdWriter{} if s.Containerized { glog.V(2).Info("Running kubelet in containerized mode") - mounter, err = mount.NewNsenterMounter() + mounter, err = mount.NewNsenterMounter(s.RootDirectory) if err != nil { return nil, err } diff --git a/pkg/util/mount/nsenter_mount.go b/pkg/util/mount/nsenter_mount.go index e1e02b7d82..71660405f5 100644 --- a/pkg/util/mount/nsenter_mount.go +++ b/pkg/util/mount/nsenter_mount.go @@ -43,9 +43,15 @@ const ( // the host's mount namespace. type NsenterMounter struct { ne *nsenter.Nsenter + // rootDir is location of /var/lib/kubelet directory. + rootDir string } -func NewNsenterMounter() (*NsenterMounter, error) { +// NewNsenterMounter creates a new mounter for kubelet that runs as a container. +// rootDir is location of /var/lib/kubelet directory (in case it's not on the +// default place). This directory must be available in the container +// on the same place as it's on the host. +func NewNsenterMounter(rootDir string) (*NsenterMounter, error) { ne, err := nsenter.NewNsenter() if err != nil { return nil, err @@ -305,14 +311,28 @@ func (mounter *NsenterMounter) SafeMakeDir(subdir string, base string, perm os.F if err != nil { return fmt.Errorf("error resolving symlinks in %s: %s", fullSubdirPath, err) } - kubeletSubdirPath := mounter.ne.KubeletPath(evaluatedSubdirPath) + evaluatedSubdirPath = filepath.Clean(evaluatedSubdirPath) evaluatedBase, err := mounter.ne.EvalSymlinks(base, true /* mustExist */) if err != nil { return fmt.Errorf("error resolving symlinks in %s: %s", base, err) } - kubeletBase := mounter.ne.KubeletPath(evaluatedBase) + evaluatedBase = filepath.Clean(evaluatedBase) + rootDir := filepath.Clean(mounter.rootDir) + if pathWithinBase(evaluatedBase, rootDir) { + // Base is in /var/lib/kubelet. This directory is shared between the + // container with kubelet and the host. We don't need to add '/rootfs'. + // This is useful when /rootfs is mounted as read-only - we can still + // create subpaths for paths in /var/lib/kubelet. + return doSafeMakeDir(evaluatedSubdirPath, evaluatedBase, perm) + } + + // Base is somewhere on the host's filesystem. Add /rootfs and try to make + // the directory there. + // This requires /rootfs to be writable. + kubeletSubdirPath := mounter.ne.KubeletPath(evaluatedSubdirPath) + kubeletBase := mounter.ne.KubeletPath(evaluatedBase) return doSafeMakeDir(kubeletSubdirPath, kubeletBase, perm) } diff --git a/pkg/util/mount/nsenter_mount_unsupported.go b/pkg/util/mount/nsenter_mount_unsupported.go index 401e1371f6..ef5cb5a107 100644 --- a/pkg/util/mount/nsenter_mount_unsupported.go +++ b/pkg/util/mount/nsenter_mount_unsupported.go @@ -25,7 +25,7 @@ import ( type NsenterMounter struct{} -func NewNsenterMounter() (*NsenterMounter, error) { +func NewNsenterMounter(rootDir string) (*NsenterMounter, error) { return &NsenterMounter{}, nil }