From 14fa76d92f9a3802ca95115ff4424654428e453b Mon Sep 17 00:00:00 2001 From: Mike Dame Date: Tue, 10 Nov 2020 14:50:31 -0500 Subject: [PATCH] Log defaulted kube-scheduler component config at startup --- cmd/kube-scheduler/app/options/configfile.go | 37 ++++++++++++++------ cmd/kube-scheduler/app/server.go | 16 ++++----- pkg/scheduler/BUILD | 1 + pkg/scheduler/factory_test.go | 22 ++++++++++++ 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/cmd/kube-scheduler/app/options/configfile.go b/cmd/kube-scheduler/app/options/configfile.go index 071de9c57c6..5cd6bf72412 100644 --- a/cmd/kube-scheduler/app/options/configfile.go +++ b/cmd/kube-scheduler/app/options/configfile.go @@ -19,6 +19,7 @@ package options import ( "fmt" "io/ioutil" + "k8s.io/klog/v2" "os" "k8s.io/apimachinery/pkg/runtime" @@ -48,8 +49,13 @@ func loadConfig(data []byte) (*kubeschedulerconfig.KubeSchedulerConfiguration, e return nil, fmt.Errorf("couldn't decode as KubeSchedulerConfiguration, got %s: ", gvk) } -// WriteConfigFile writes the config into the given file name as YAML. -func WriteConfigFile(fileName string, cfg *kubeschedulerconfig.KubeSchedulerConfiguration) error { +// LogOrWriteConfig logs the completed component config and writes it into the given file name as YAML, if either is enabled +func LogOrWriteConfig(fileName string, cfg *kubeschedulerconfig.KubeSchedulerConfiguration, completedProfiles []kubeschedulerconfig.KubeSchedulerProfile) error { + if !(klog.V(2).Enabled() || len(fileName) > 0) { + return nil + } + cfg.Profiles = completedProfiles + const mediaType = runtime.ContentTypeYAML info, ok := runtime.SerializerInfoForMediaType(kubeschedulerscheme.Codecs.SupportedMediaTypes(), mediaType) if !ok { @@ -57,15 +63,26 @@ func WriteConfigFile(fileName string, cfg *kubeschedulerconfig.KubeSchedulerConf } encoder := kubeschedulerscheme.Codecs.EncoderForVersion(info.Serializer, kubeschedulerconfigv1beta1.SchemeGroupVersion) - - configFile, err := os.Create(fileName) - if err != nil { - return err - } - defer configFile.Close() - if err := encoder.Encode(cfg, configFile); err != nil { - return err + if klog.V(2).Enabled() { + bytes, err := runtime.Encode(encoder, cfg) + if err != nil { + return err + } + configString := string(bytes) + klog.Infof("Using component config:\n%+v\n", configString) } + if len(fileName) > 0 { + configFile, err := os.Create(fileName) + if err != nil { + return err + } + defer configFile.Close() + if err := encoder.Encode(cfg, configFile); err != nil { + return err + } + klog.Infof("Wrote configuration to: %s\n", fileName) + os.Exit(0) + } return nil } diff --git a/cmd/kube-scheduler/app/server.go b/cmd/kube-scheduler/app/server.go index d235f21162e..81352a8d9a0 100644 --- a/cmd/kube-scheduler/app/server.go +++ b/cmd/kube-scheduler/app/server.go @@ -128,14 +128,6 @@ func runCommand(cmd *cobra.Command, opts *options.Options, registryOptions ...Op return err } - if len(opts.WriteConfigTo) > 0 { - if err := options.WriteConfigFile(opts.WriteConfigTo, &cc.ComponentConfig); err != nil { - return err - } - klog.Infof("Wrote configuration to: %s\n", opts.WriteConfigTo) - return nil - } - return Run(ctx, cc, sched) } @@ -310,6 +302,7 @@ func Setup(ctx context.Context, opts *options.Options, outOfTreeRegistryOptions } recorderFactory := getRecorderFactory(&cc) + completedProfiles := make([]kubeschedulerconfig.KubeSchedulerProfile, 0) // Create the scheduler. sched, err := scheduler.New(cc.Client, cc.InformerFactory, @@ -323,10 +316,17 @@ func Setup(ctx context.Context, opts *options.Options, outOfTreeRegistryOptions scheduler.WithPodInitialBackoffSeconds(cc.ComponentConfig.PodInitialBackoffSeconds), scheduler.WithExtenders(cc.ComponentConfig.Extenders...), scheduler.WithParallelism(cc.ComponentConfig.Parallelism), + scheduler.WithBuildFrameworkCapturer(func(profile kubeschedulerconfig.KubeSchedulerProfile) { + // Profiles are processed during Framework instantiation to set default plugins and configurations. Capturing them for logging + completedProfiles = append(completedProfiles, profile) + }), ) if err != nil { return nil, nil, err } + if err := options.LogOrWriteConfig(opts.WriteConfigTo, &cc.ComponentConfig, completedProfiles); err != nil { + return nil, nil, err + } return &cc, sched, nil } diff --git a/pkg/scheduler/BUILD b/pkg/scheduler/BUILD index b6890e52166..cf834106047 100644 --- a/pkg/scheduler/BUILD +++ b/pkg/scheduler/BUILD @@ -65,6 +65,7 @@ go_test( "//pkg/scheduler/framework:go_default_library", "//pkg/scheduler/framework/plugins:go_default_library", "//pkg/scheduler/framework/plugins/defaultbinder:go_default_library", + "//pkg/scheduler/framework/plugins/defaultpreemption:go_default_library", "//pkg/scheduler/framework/plugins/interpodaffinity:go_default_library", "//pkg/scheduler/framework/plugins/nodeaffinity:go_default_library", "//pkg/scheduler/framework/plugins/nodelabel:go_default_library", diff --git a/pkg/scheduler/factory_test.go b/pkg/scheduler/factory_test.go index 551c19c5948..21cfe0cc389 100644 --- a/pkg/scheduler/factory_test.go +++ b/pkg/scheduler/factory_test.go @@ -38,6 +38,7 @@ import ( schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config" "k8s.io/kubernetes/pkg/scheduler/framework" frameworkplugins "k8s.io/kubernetes/pkg/scheduler/framework/plugins" + "k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodelabel" @@ -107,6 +108,13 @@ func TestCreateFromConfig(t *testing.T) { "apiVersion" : "v1" }`), wantPluginConfig: []schedulerapi.PluginConfig{ + { + Name: defaultpreemption.Name, + Args: &schedulerapi.DefaultPreemptionArgs{ + MinCandidateNodesPercentage: 10, + MinCandidateNodesAbsolute: 100, + }, + }, { Name: interpodaffinity.Name, Args: &schedulerapi.InterPodAffinityArgs{ @@ -231,6 +239,13 @@ func TestCreateFromConfig(t *testing.T) { ] }`), wantPluginConfig: []schedulerapi.PluginConfig{ + { + Name: defaultpreemption.Name, + Args: &schedulerapi.DefaultPreemptionArgs{ + MinCandidateNodesPercentage: 10, + MinCandidateNodesAbsolute: 100, + }, + }, { Name: interpodaffinity.Name, Args: &schedulerapi.InterPodAffinityArgs{ @@ -312,6 +327,13 @@ func TestCreateFromConfig(t *testing.T) { "hardPodAffinitySymmetricWeight" : 10 }`), wantPluginConfig: []schedulerapi.PluginConfig{ + { + Name: defaultpreemption.Name, + Args: &schedulerapi.DefaultPreemptionArgs{ + MinCandidateNodesPercentage: 10, + MinCandidateNodesAbsolute: 100, + }, + }, { Name: interpodaffinity.Name, Args: &schedulerapi.InterPodAffinityArgs{