Skip to content

Direct exec() the kubelet instead of launching in proc #16270

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

Merged
merged 4 commits into from
Sep 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 8 additions & 0 deletions pkg/cmd/flagtypes/glog.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,18 @@ func GLog(flags *pflag.FlagSet) {
level := flag.Value.(*glog.Level)
levelPtr := (*int32)(level)
flags.Int32Var(levelPtr, "loglevel", 0, "Set the level of log output (0-10)")
if flags.Lookup("v") == nil {
flags.Int32Var(levelPtr, "v", 0, "Set the level of log output (0-10)")
}
flags.Lookup("v").Hidden = true
}
if flag := from.Lookup("vmodule"); flag != nil {
value := flag.Value
flags.Var(pflagValue{value}, "logspec", "Set per module logging with file|pattern=LEVEL,...")
if flags.Lookup("vmodule") == nil {
flags.Var(pflagValue{value}, "vmodule", "Set per module logging with file|pattern=LEVEL,...")
}
flags.Lookup("vmodule").Hidden = true
}
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/cmd/server/kubernetes/node/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ func Build(options configapi.NodeConfig) (*kubeletoptions.KubeletServer, *compon
server.HTTPCheckFrequency = metav1.Duration{Duration: time.Duration(0)} // no remote HTTP pod creation access
server.FileCheckFrequency = metav1.Duration{Duration: time.Duration(fileCheckInterval) * time.Second}
server.KubeletFlags.ContainerRuntimeOptions.PodSandboxImage = imageTemplate.ExpandOrDie("pod")
server.LowDiskSpaceThresholdMB = 256 // this the previous default
server.CPUCFSQuota = true // enable cpu cfs quota enforcement by default
server.MaxPods = 250
server.PodsPerCore = 10
server.CgroupDriver = "systemd"
Expand Down Expand Up @@ -203,3 +201,7 @@ func buildKubeProxyConfig(options configapi.NodeConfig) (*componentconfig.KubePr

return proxyconfig, nil
}

func ToFlags(config *kubeletoptions.KubeletServer) []string {
return cmdflags.AsArgs(config.AddFlags, kubeletoptions.NewKubeletServer().AddFlags)
}
78 changes: 78 additions & 0 deletions pkg/cmd/server/start/start_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"

"github.com/coreos/go-systemd/daemon"
"github.com/golang/glog"
"github.com/spf13/cobra"

kerrors "k8s.io/apimachinery/pkg/api/errors"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
kubeletoptions "k8s.io/kubernetes/cmd/kubelet/app/options"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"

Expand Down Expand Up @@ -328,12 +333,85 @@ func (o NodeOptions) IsRunFromConfig() bool {
return (len(o.ConfigFile) > 0)
}

// execKubelet attempts to call execve() for the kubelet with the configuration defined
// in server passed as flags. If the binary is not the same as the current file and
// the environment variable OPENSHIFT_ALLOW_UNSUPPORTED_KUBELET is unset, the method
// will return an error. The returned boolean indicates whether fallback to in-process
// is allowed.
func execKubelet(server *kubeletoptions.KubeletServer) (bool, error) {
// verify the Kubelet binary to use
path := "kubelet"
requireSameBinary := true
if newPath := os.Getenv("OPENSHIFT_ALLOW_UNSUPPORTED_KUBELET"); len(newPath) > 0 {
requireSameBinary = false
path = newPath
}
kubeletPath, err := exec.LookPath(path)
if err != nil {
return requireSameBinary, err
}
kubeletFile, err := os.Stat(kubeletPath)
if err != nil {
return requireSameBinary, err
}
thisPath, err := exec.LookPath(os.Args[0])
if err != nil {
return true, err
}
thisFile, err := os.Stat(thisPath)
if err != nil {
return true, err
}
if !os.SameFile(thisFile, kubeletFile) {
if requireSameBinary {
return true, fmt.Errorf("binary at %q is not the same file as %q, cannot execute", thisPath, kubeletPath)
}
glog.Warningf("UNSUPPORTED: Executing a different Kubelet than the current binary is not supported: %s", kubeletPath)
}

// convert current settings to flags
args := nodeoptions.ToFlags(server)
args = append([]string{kubeletPath}, args...)
for i := glog.Level(10); i > 0; i-- {
if glog.V(i) {
args = append(args, fmt.Sprintf("--v=%d", i))
break
}
}
for i, s := range os.Args {
if s == "--vmodule" {
if i+1 < len(os.Args) {
args = append(args, fmt.Sprintf("--vmodule=", os.Args[i+1]))
break
}
}
if strings.HasPrefix(s, "--vmodule=") {
args = append(args, s)
break
}
}
glog.V(3).Infof("Exec %s %s", kubeletPath, strings.Join(args, " "))
return false, syscall.Exec(kubeletPath, args, os.Environ())
}

func StartNode(nodeConfig configapi.NodeConfig, components *utilflags.ComponentFlag) error {
server, proxyConfig, err := nodeoptions.Build(nodeConfig)
if err != nil {
return err
}

// as a step towards decomposing OpenShift into Kubernetes components, perform an execve
// to launch the Kubelet instead of loading in-process
if components.Calculated().Equal(sets.NewString(ComponentKubelet)) {
ok, err := execKubelet(server)
if !ok {
return err
}
if err != nil {
utilruntime.HandleError(fmt.Errorf("Unable to call exec on kubelet, continuing with normal startup: %v", err))
}
}

networkConfig, err := network.New(nodeConfig, server.ClusterDomain, proxyConfig, components.Enabled(ComponentProxy), components.Enabled(ComponentDNS) && len(nodeConfig.DNSBindAddress) > 0)
if err != nil {
return err
Expand Down
27 changes: 27 additions & 0 deletions pkg/cmd/util/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,33 @@ func Resolve(args map[string][]string, fn func(*pflag.FlagSet)) []error {
return Apply(args, fs)
}

func AsArgs(fn, defaultFn func(*pflag.FlagSet)) []string {
fs := pflag.NewFlagSet("extended", pflag.ContinueOnError)
fn(fs)
defaults := pflag.NewFlagSet("defaults", pflag.ContinueOnError)
defaultFn(defaults)
var args []string
fs.VisitAll(func(flag *pflag.Flag) {
defaultFlag := defaults.Lookup(flag.Name)
s := flag.Value.String()
defaultValue := defaultFlag.Value.String()
if s == defaultValue {
return
}
if values, err := fs.GetStringSlice(flag.Name); err == nil {
for _, s := range values {
args = append(args, fmt.Sprintf("--%s=%s", flag.Name, s))
}
} else {
if len(s) == 0 {
s = defaultValue
}
args = append(args, fmt.Sprintf("--%s=%s", flag.Name, s))
}
})
return args
}

// ComponentFlag represents a set of enabled components used in a command line.
type ComponentFlag struct {
enabled string
Expand Down
4 changes: 4 additions & 0 deletions vendor/k8s.io/kubernetes/pkg/apis/componentconfig/helpers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion vendor/k8s.io/kubernetes/pkg/util/taints/taints.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.