mirror of https://github.com/k3s-io/k3s
Merge pull request #62951 from dims/support-nsenter-better-in-non-systemd-envs
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Support nsenter in non-systemd environments **What this PR does / why we need it**: In our CI, we run kubekins image for most of the jobs. This is a debian image with upstart and does not enable systemd. So we should * Bailout if any binary is missing other than systemd-run. * SupportsSystemd should check the binary path to correctly identify if the systemd-run is present or not * Pass the errors back to the callers so kubelet is forced to fail early when there is a problem. We currently assume that all binaries are in the root directory by default which is wrong. **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 # **Special notes for your reviewer**: **Release note**: ```release-note NONE ```pull/8/head
commit
aa1ec693c3
|
@ -335,7 +335,10 @@ func UnsecuredDependencies(s *options.KubeletServer) (*kubelet.Dependencies, err
|
||||||
var writer kubeio.Writer = &kubeio.StdWriter{}
|
var writer kubeio.Writer = &kubeio.StdWriter{}
|
||||||
if s.Containerized {
|
if s.Containerized {
|
||||||
glog.V(2).Info("Running kubelet in containerized mode")
|
glog.V(2).Info("Running kubelet in containerized mode")
|
||||||
mounter = mount.NewNsenterMounter()
|
mounter, err = mount.NewNsenterMounter()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
writer = &kubeio.NsenterWriter{}
|
writer = &kubeio.NsenterWriter{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,10 @@ type NsenterWriter struct{}
|
||||||
// WriteFile calls 'nsenter cat - > <the file>' and 'nsenter chmod' to create a
|
// WriteFile calls 'nsenter cat - > <the file>' and 'nsenter chmod' to create a
|
||||||
// file on the host.
|
// file on the host.
|
||||||
func (writer *NsenterWriter) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
func (writer *NsenterWriter) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
ne := nsenter.NewNsenter()
|
ne, err := nsenter.NewNsenter()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
echoArgs := []string{"-c", fmt.Sprintf("cat > %s", filename)}
|
echoArgs := []string{"-c", fmt.Sprintf("cat > %s", filename)}
|
||||||
glog.V(5).Infof("nsenter: write data to file %s by nsenter", filename)
|
glog.V(5).Infof("nsenter: write data to file %s by nsenter", filename)
|
||||||
command := ne.Exec("sh", echoArgs)
|
command := ne.Exec("sh", echoArgs)
|
||||||
|
|
|
@ -52,8 +52,12 @@ type NsenterMounter struct {
|
||||||
ne *nsenter.Nsenter
|
ne *nsenter.Nsenter
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNsenterMounter() *NsenterMounter {
|
func NewNsenterMounter() (*NsenterMounter, error) {
|
||||||
return &NsenterMounter{ne: nsenter.NewNsenter()}
|
ne, err := nsenter.NewNsenter()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &NsenterMounter{ne: ne}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NsenterMounter implements mount.Interface
|
// NsenterMounter implements mount.Interface
|
||||||
|
|
|
@ -25,8 +25,8 @@ import (
|
||||||
|
|
||||||
type NsenterMounter struct{}
|
type NsenterMounter struct{}
|
||||||
|
|
||||||
func NewNsenterMounter() *NsenterMounter {
|
func NewNsenterMounter() (*NsenterMounter, error) {
|
||||||
return &NsenterMounter{}
|
return &NsenterMounter{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = Interface(&NsenterMounter{})
|
var _ = Interface(&NsenterMounter{})
|
||||||
|
|
|
@ -57,7 +57,8 @@ const (
|
||||||
// contents. TODO: remove this requirement.
|
// contents. TODO: remove this requirement.
|
||||||
// 6. The host image must have "mount", "findmnt", "umount", "stat", "touch",
|
// 6. The host image must have "mount", "findmnt", "umount", "stat", "touch",
|
||||||
// "mkdir", "ls", "sh" and "chmod" binaries in /bin, /usr/sbin, or /usr/bin
|
// "mkdir", "ls", "sh" and "chmod" binaries in /bin, /usr/sbin, or /usr/bin
|
||||||
// 7. The host image should have systemd-run in /bin, /usr/sbin, or /usr/bin
|
// 7. The host image should have systemd-run in /bin, /usr/sbin, or /usr/bin if
|
||||||
|
// systemd is installed/enabled in the operating system.
|
||||||
// For more information about mount propagation modes, see:
|
// For more information about mount propagation modes, see:
|
||||||
// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
|
// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
|
||||||
type Nsenter struct {
|
type Nsenter struct {
|
||||||
|
@ -66,7 +67,7 @@ type Nsenter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNsenter constructs a new instance of Nsenter
|
// NewNsenter constructs a new instance of Nsenter
|
||||||
func NewNsenter() *Nsenter {
|
func NewNsenter() (*Nsenter, error) {
|
||||||
ne := &Nsenter{
|
ne := &Nsenter{
|
||||||
paths: map[string]string{
|
paths: map[string]string{
|
||||||
"mount": "",
|
"mount": "",
|
||||||
|
@ -83,9 +84,8 @@ func NewNsenter() *Nsenter {
|
||||||
}
|
}
|
||||||
// search for the required commands in other locations besides /usr/bin
|
// search for the required commands in other locations besides /usr/bin
|
||||||
for binary := range ne.paths {
|
for binary := range ne.paths {
|
||||||
// default to root
|
// check for binary under the following directories
|
||||||
ne.paths[binary] = filepath.Join("/", binary)
|
for _, path := range []string{"/", "/bin", "/usr/sbin", "/usr/bin"} {
|
||||||
for _, path := range []string{"/bin", "/usr/sbin", "/usr/bin"} {
|
|
||||||
binPath := filepath.Join(path, binary)
|
binPath := filepath.Join(path, binary)
|
||||||
if _, err := os.Stat(filepath.Join(hostRootFsPath, binPath)); err != nil {
|
if _, err := os.Stat(filepath.Join(hostRootFsPath, binPath)); err != nil {
|
||||||
continue
|
continue
|
||||||
|
@ -93,10 +93,12 @@ func NewNsenter() *Nsenter {
|
||||||
ne.paths[binary] = binPath
|
ne.paths[binary] = binPath
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// TODO: error, so that the kubelet can stop if the paths don't exist
|
// systemd-run is optional, bailout if we don't find any of the other binaries
|
||||||
// (don't forget that systemd-run is optional)
|
if ne.paths[binary] == "" && binary != "systemd-run" {
|
||||||
|
return nil, fmt.Errorf("unable to find %v", binary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ne
|
return ne, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
|
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
|
||||||
|
@ -119,6 +121,6 @@ func (ne *Nsenter) AbsHostPath(command string) string {
|
||||||
|
|
||||||
// SupportsSystemd checks whether command systemd-run exists
|
// SupportsSystemd checks whether command systemd-run exists
|
||||||
func (ne *Nsenter) SupportsSystemd() (string, bool) {
|
func (ne *Nsenter) SupportsSystemd() (string, bool) {
|
||||||
systemdRunPath, hasSystemd := ne.paths["systemd-run"]
|
systemdRunPath, ok := ne.paths["systemd-run"]
|
||||||
return systemdRunPath, hasSystemd
|
return systemdRunPath, ok && systemdRunPath != ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ type Nsenter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNsenter constructs a new instance of Nsenter
|
// NewNsenter constructs a new instance of Nsenter
|
||||||
func NewNsenter() *Nsenter {
|
func NewNsenter() (*Nsenter, error) {
|
||||||
return &Nsenter{}
|
return &Nsenter{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
|
// Exec executes nsenter commands in hostProcMountNsPath mount namespace
|
||||||
|
|
Loading…
Reference in New Issue