Skip to content
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

WIP: Add SysV init support #7081

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions pkg/minikube/bootstrapper/bsutil/ktmpl/kubelet_sysv.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
Copyright 2020 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package ktmpl

RestartWrapperTemplate = template.Must(template.New("kubeletSysVTemplate").Parse(`#!/bin/bash
# Wrapper script to emulate systemd restart on non-systemd systems
binary=$1
unitfile=$2
args=""

while [[ -x "${binary}" ]]; do
if [[ -f "${unitfile}" ]]; then
args=$(egrep "^ExecStart=${binary}" "${unitfile}" | cut -d" " -f2-)
fi
${binary} ${args}
sleep 1
done
```

KubeletSysVTemplate = template.Must(template.New("kubeletSysVTemplate").Parse(`#!/bin/sh
# SysV style init script for kubelet

readonly KUBELET={{.KubeletPath}}
readonly KUBELET_WRAPPER={{.KubeletWrapperPath}}
readonly KUBELET_PIDFILE="/var/run/kubelet.pid"
readonly KUBELET_LOGFILE=/var/run/nohup.out

if [[ ! -x "${KUBELET}" ]]; then
echo "$KUBELET not present or not executable"
exit 1
fi

function start() {
cd /var/run
nohup "${KUBELET_WRAPPER}" &
echo $! > "${KUBELET_PIDFILE}"
}

function stop() {
if [[ -f "${KUBELET_PIDFILE}" ]]; then
kill $(cat ${KUBELET_PIDFILE})
fi
pkill "${KUBELET_WRAPPER}"
pkill kubelet
}


case "$1" in
start)
start
;;

stop)
stop
;;

restart)
stop
start
;;

status)
pgrep kubelet
;;

*)
echo "Usage: service kubelet {start|stop|restart|status}"
exit 1
;;
esac
`)
8 changes: 6 additions & 2 deletions pkg/minikube/bootstrapper/kubeadm/kubeadm.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,11 +426,14 @@ func (k *Bootstrapper) UpdateCluster(cfg config.ClusterConfig) error {

glog.Infof("kubelet %s config:\n%+v", kubeletCfg, cfg.KubernetesConfig)

sm := sysinit.New(k.c)

// stop kubelet to avoid "Text File Busy" error
if err := stopKubelet(k.c); err != nil {
if err := sm.Stop("kubelet"); err != nil {
glog.Warningf("unable to stop kubelet: %s", err)
}


if err := bsutil.TransferBinaries(cfg.KubernetesConfig, k.c); err != nil {
return errors.Wrap(err, "downloading binaries")
}
Expand All @@ -444,9 +447,10 @@ func (k *Bootstrapper) UpdateCluster(cfg config.ClusterConfig) error {
return err
}

if err := startKubelet(k.c); err != nil {
if err := sm.Start("kubelet"); err != nil {
return err
}

return nil
}

Expand Down
19 changes: 6 additions & 13 deletions pkg/minikube/cruntime/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/sysinit"
)

const (
Expand Down Expand Up @@ -115,6 +116,7 @@ type Containerd struct {
Runner CommandRunner
ImageRepository string
KubernetesVersion semver.Version
Init sysinit.Manager
}

// Name is a human readable name for containerd
Expand Down Expand Up @@ -157,9 +159,7 @@ func (r *Containerd) DefaultCNI() bool {

// Active returns if containerd is active on the host
func (r *Containerd) Active() bool {
c := exec.Command("sudo", "systemctl", "is-active", "--quiet", "service", "containerd")
_, err := r.Runner.RunCmd(c)
return err == nil
return r.Init.Active("containerd")
}

// Available returns an error if it is not possible to use this runtime on a host
Expand Down Expand Up @@ -207,21 +207,14 @@ func (r *Containerd) Enable(disOthers bool) error {
if err := enableIPForwarding(r.Runner); err != nil {
return err
}

// Otherwise, containerd will fail API requests with 'Unimplemented'
c := exec.Command("sudo", "systemctl", "restart", "containerd")
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrap(err, "restart containerd")
}
return nil
return r.Init.Restart("containerd")
}

// Disable idempotently disables containerd on a host
func (r *Containerd) Disable() error {
c := exec.Command("sudo", "systemctl", "stop", "containerd")
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrapf(err, "stop containerd")
}
return nil
return r.Init.Stop("containerd")
}

// ImageExists checks if an image exists, expected input format
Expand Down
19 changes: 7 additions & 12 deletions pkg/minikube/cruntime/crio.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/sysinit"

)

const (
Expand All @@ -40,6 +42,8 @@ type CRIO struct {
Runner CommandRunner
ImageRepository string
KubernetesVersion semver.Version
Init sysinit.Manager

}

// generateCRIOConfig sets up /etc/crio/crio.conf
Expand Down Expand Up @@ -103,9 +107,7 @@ func (r *CRIO) Available() error {

// Active returns if CRIO is active on the host
func (r *CRIO) Active() bool {
c := exec.Command("sudo", "systemctl", "is-active", "--quiet", "service", "crio")
_, err := r.Runner.RunCmd(c)
return err == nil
return r.Init.Active("crio")
}

// Enable idempotently enables CRIO on a host
Expand All @@ -124,19 +126,12 @@ func (r *CRIO) Enable(disOthers bool) error {
if err := enableIPForwarding(r.Runner); err != nil {
return err
}

if _, err := r.Runner.RunCmd(exec.Command("sudo", "systemctl", "restart", "crio")); err != nil {
return errors.Wrapf(err, "enable crio.")
}
return nil
return r.Init.Start("crio")
}

// Disable idempotently disables CRIO on a host
func (r *CRIO) Disable() error {
if _, err := r.Runner.RunCmd(exec.Command("sudo", "systemctl", "stop", "crio")); err != nil {
return errors.Wrapf(err, "disable crio.")
}
return nil
return r.Init.Stop("crio")
}

// ImageExists checks if an image exists
Expand Down
21 changes: 18 additions & 3 deletions pkg/minikube/cruntime/cruntime.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/sysinit"
)

// ContainerState is the run state of a container
Expand Down Expand Up @@ -131,13 +132,27 @@ type ListOptions struct {

// New returns an appropriately configured runtime
func New(c Config) (Manager, error) {
sm := sysinit.New(c.Runner)

switch c.Type {
case "", "docker":
return &Docker{Socket: c.Socket, Runner: c.Runner}, nil
return &Docker{Socket: c.Socket, Runner: c.Runner, Init: sm}, nil
case "crio", "cri-o":
return &CRIO{Socket: c.Socket, Runner: c.Runner, ImageRepository: c.ImageRepository, KubernetesVersion: c.KubernetesVersion}, nil
return &CRIO{
Socket: c.Socket,
Runner: c.Runner,
ImageRepository: c.ImageRepository,
KubernetesVersion: c.KubernetesVersion,
Init: sm,
}, nil
case "containerd":
return &Containerd{Socket: c.Socket, Runner: c.Runner, ImageRepository: c.ImageRepository, KubernetesVersion: c.KubernetesVersion}, nil
return &Containerd{
Socket: c.Socket,
Runner: c.Runner,
ImageRepository: c.ImageRepository,
KubernetesVersion: c.KubernetesVersion,
Init: sm,
}, nil
default:
return nil, fmt.Errorf("unknown runtime type: %q", c.Type)
}
Expand Down
28 changes: 11 additions & 17 deletions pkg/minikube/cruntime/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"k8s.io/minikube/pkg/minikube/docker"
"k8s.io/minikube/pkg/minikube/download"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/sysinit"
)

// KubernetesContainerPrefix is the prefix of each kubernetes container
Expand All @@ -56,6 +57,8 @@ func (e *ErrISOFeature) Error() string {
type Docker struct {
Socket string
Runner CommandRunner
Init sysinit.Manager

}

// Name is a human readable name for Docker
Expand Down Expand Up @@ -95,11 +98,10 @@ func (r *Docker) Available() error {
return err
}


// Active returns if docker is active on the host
func (r *Docker) Active() bool {
c := exec.Command("sudo", "systemctl", "is-active", "--quiet", "service", "docker")
_, err := r.Runner.RunCmd(c)
return err == nil
return r.Init.Active("docker")
}

// Enable idempotently enables Docker on a host
Expand All @@ -109,29 +111,21 @@ func (r *Docker) Enable(disOthers bool) error {
glog.Warningf("disableOthers: %v", err)
}
}
c := exec.Command("sudo", "systemctl", "start", "docker")
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrap(err, "enable docker.")
}
return nil

return r.Init.Start("docker")
}

// Restart restarts Docker on a host
func (r *Docker) Restart() error {
c := exec.Command("sudo", "systemctl", "restart", "docker")
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrap(err, "restarting docker.")
}
return nil
return r.Init.Restart("docker")
}

// Disable idempotently disables Docker on a host
func (r *Docker) Disable() error {
c := exec.Command("sudo", "systemctl", "stop", "docker", "docker.socket")
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrap(err, "disable docker")
if err := r.Init.Stop("docker"); err != nil {
return err
}
return nil
return r.Init.Stop("docker.socket")
}

// ImageExists checks if an image exists
Expand Down
4 changes: 2 additions & 2 deletions pkg/minikube/registry/drvs/none/none.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) {
}

func status() registry.State {
_, err := exec.LookPath("systemctl")
_, err := exec.LookPath("iptables")
if err != nil {
return registry.State{Error: err, Fix: "Use a systemd based Linux distribution", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/none/"}
return registry.State{Error: err, Fix: "iptables must be installed", Doc: "https://minikube.sigs.k8s.io/docs/reference/drivers/none/"}
}
return registry.State{Installed: true, Healthy: true}
}
42 changes: 42 additions & 0 deletions pkg/minikube/sysinit/sysinit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package sysinit

import (
"os/exec"

"k8s.io/minikube/pkg/minikube/command"
)

// Runner is the subset of command.Runner this package consumes
type Runner interface {
RunCmd(cmd *exec.Cmd) (*command.RunResult, error)
}

// Manager is a common interface for init systems
type Manager interface {
// Name returns the name of the init manager
Name() string

// Active returns if a service is active
Active(string) bool

// Start starts a service idempotently
Start(string) error

// Restart restarts a service
Restart(string) error

// Stop stops a service
Stop(string) error
}

// New returns an appropriately configured service manager
func New(r Runner) Manager {
// If we aren't passed a runner, pretend we are systemd as always
if r == nil {
return &Systemd{r: r}
}
if usesSystemd(r) {
return &Systemd{r: r}
}
return &SysV{r: r}
}
Loading