mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 05:03:09 +00:00
Detect systemd on mounter startup
This commit is contained in:
parent
5a8a6110a2
commit
dd03384747
@ -94,15 +94,6 @@ func (mounter *SafeFormatAndMount) FormatAndMount(source string, target string,
|
|||||||
return mounter.formatAndMount(source, target, fstype, options)
|
return mounter.formatAndMount(source, target, fstype, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a mount.Interface for the current system.
|
|
||||||
// It provides options to override the default mounter behavior.
|
|
||||||
// mounterPath allows using an alternative to `/bin/mount` for mounting.
|
|
||||||
func New(mounterPath string) Interface {
|
|
||||||
return &Mounter{
|
|
||||||
mounterPath: mounterPath,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMountRefs finds all other references to the device referenced
|
// GetMountRefs finds all other references to the device referenced
|
||||||
// by mountPath; returns a list of paths.
|
// by mountPath; returns a list of paths.
|
||||||
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
|
func GetMountRefs(mounter Interface, mountPath string) ([]string, error) {
|
||||||
|
@ -55,6 +55,17 @@ const (
|
|||||||
// kubelet is running in the host's root mount namespace.
|
// kubelet is running in the host's root mount namespace.
|
||||||
type Mounter struct {
|
type Mounter struct {
|
||||||
mounterPath string
|
mounterPath string
|
||||||
|
withSystemd bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a mount.Interface for the current system.
|
||||||
|
// It provides options to override the default mounter behavior.
|
||||||
|
// mounterPath allows using an alternative to `/bin/mount` for mounting.
|
||||||
|
func New(mounterPath string) Interface {
|
||||||
|
return &Mounter{
|
||||||
|
mounterPath: mounterPath,
|
||||||
|
withSystemd: detectSystemd(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mount mounts source to target as fstype with given options. 'source' and 'fstype' must
|
// Mount mounts source to target as fstype with given options. 'source' and 'fstype' must
|
||||||
@ -68,18 +79,18 @@ func (mounter *Mounter) Mount(source string, target string, fstype string, optio
|
|||||||
mounterPath := ""
|
mounterPath := ""
|
||||||
bind, bindRemountOpts := isBind(options)
|
bind, bindRemountOpts := isBind(options)
|
||||||
if bind {
|
if bind {
|
||||||
err := doMount(mounterPath, defaultMountCommand, source, target, fstype, []string{"bind"})
|
err := mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, []string{"bind"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts)
|
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, bindRemountOpts)
|
||||||
}
|
}
|
||||||
// The list of filesystems that require containerized mounter on GCI image cluster
|
// The list of filesystems that require containerized mounter on GCI image cluster
|
||||||
fsTypesNeedMounter := sets.NewString("nfs", "glusterfs", "ceph", "cifs")
|
fsTypesNeedMounter := sets.NewString("nfs", "glusterfs", "ceph", "cifs")
|
||||||
if fsTypesNeedMounter.Has(fstype) {
|
if fsTypesNeedMounter.Has(fstype) {
|
||||||
mounterPath = mounter.mounterPath
|
mounterPath = mounter.mounterPath
|
||||||
}
|
}
|
||||||
return doMount(mounterPath, defaultMountCommand, source, target, fstype, options)
|
return mounter.doMount(mounterPath, defaultMountCommand, source, target, fstype, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// isBind detects whether a bind mount is being requested and makes the remount options to
|
// isBind detects whether a bind mount is being requested and makes the remount options to
|
||||||
@ -108,14 +119,14 @@ func isBind(options []string) (bool, []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// doMount runs the mount command. mounterPath is the path to mounter binary if containerized mounter is used.
|
// doMount runs the mount command. mounterPath is the path to mounter binary if containerized mounter is used.
|
||||||
func doMount(mounterPath string, mountCmd string, source string, target string, fstype string, options []string) error {
|
func (m *Mounter) doMount(mounterPath string, mountCmd string, source string, target string, fstype string, options []string) error {
|
||||||
mountArgs := makeMountArgs(source, target, fstype, options)
|
mountArgs := makeMountArgs(source, target, fstype, options)
|
||||||
if len(mounterPath) > 0 {
|
if len(mounterPath) > 0 {
|
||||||
mountArgs = append([]string{mountCmd}, mountArgs...)
|
mountArgs = append([]string{mountCmd}, mountArgs...)
|
||||||
mountCmd = mounterPath
|
mountCmd = mounterPath
|
||||||
}
|
}
|
||||||
|
|
||||||
if systemdRunPath, err := exec.LookPath("systemd-run"); err == nil {
|
if m.withSystemd {
|
||||||
// Try to run mount via systemd-run --scope. This will escape the
|
// Try to run mount via systemd-run --scope. This will escape the
|
||||||
// service where kubelet runs and any fuse daemons will be started in a
|
// service where kubelet runs and any fuse daemons will be started in a
|
||||||
// specific scope. kubelet service than can be restarted without killing
|
// specific scope. kubelet service than can be restarted without killing
|
||||||
@ -138,7 +149,7 @@ func doMount(mounterPath string, mountCmd string, source string, target string,
|
|||||||
//
|
//
|
||||||
// systemd-mount is not used because it's too new for older distros
|
// systemd-mount is not used because it's too new for older distros
|
||||||
// (CentOS 7, Debian Jessie).
|
// (CentOS 7, Debian Jessie).
|
||||||
mountCmd, mountArgs = addSystemdScope(systemdRunPath, target, mountCmd, mountArgs)
|
mountCmd, mountArgs = addSystemdScope("systemd-run", target, mountCmd, mountArgs)
|
||||||
} else {
|
} else {
|
||||||
// No systemd-run on the host (or we failed to check it), assume kubelet
|
// No systemd-run on the host (or we failed to check it), assume kubelet
|
||||||
// does not run as a systemd service.
|
// does not run as a systemd service.
|
||||||
@ -157,6 +168,31 @@ func doMount(mounterPath string, mountCmd string, source string, target string,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// detectSystemd returns true if OS runs with systemd as init. When not sure
|
||||||
|
// (permission errors, ...), it returns false.
|
||||||
|
// There may be different ways how to detect systemd, this one makes sure that
|
||||||
|
// systemd-runs (needed by Mount()) works.
|
||||||
|
func detectSystemd() bool {
|
||||||
|
if _, err := exec.LookPath("systemd-run"); err != nil {
|
||||||
|
glog.V(2).Infof("Detected OS without systemd")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// Try to run systemd-run --scope /bin/true, that should be enough
|
||||||
|
// to make sure that systemd is really running and not just installed,
|
||||||
|
// which happens when running in a container with a systemd-based image
|
||||||
|
// but with different pid 1.
|
||||||
|
cmd := exec.Command("systemd-run", "--description=Kubernetes systemd probe", "--scope", "true")
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
glog.V(2).Infof("Cannot run systemd-run, assuming non-systemd OS")
|
||||||
|
glog.V(4).Infof("systemd-run failed with: %v", err)
|
||||||
|
glog.V(4).Infof("systemd-run output: %s", string(output))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
glog.V(2).Infof("Detected OS with systemd")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// makeMountArgs makes the arguments to the mount(8) command.
|
// makeMountArgs makes the arguments to the mount(8) command.
|
||||||
func makeMountArgs(source, target, fstype string, options []string) []string {
|
func makeMountArgs(source, target, fstype string, options []string) []string {
|
||||||
// Build mount command as follows:
|
// Build mount command as follows:
|
||||||
|
@ -22,6 +22,15 @@ type Mounter struct {
|
|||||||
mounterPath string
|
mounterPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New returns a mount.Interface for the current system.
|
||||||
|
// It provides options to override the default mounter behavior.
|
||||||
|
// mounterPath allows using an alternative to `/bin/mount` for mounting.
|
||||||
|
func New(mounterPath string) Interface {
|
||||||
|
return &Mounter{
|
||||||
|
mounterPath: mounterPath,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error {
|
func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user