Skip to content

Commit

Permalink
UPSTREAM: <carry>: allows for switching KS to talk to Kube API over l…
Browse files Browse the repository at this point in the history
…ocalhost

to force KS to use localhost set the following flag in kubescheduler (oc edit kubescheduler cluster)

unsupportedConfigOverrides:
  arguments:
    unsupported-kube-api-over-localhost::
    - "true"
  • Loading branch information
p0lyn0mial authored and damemi committed Dec 20, 2021
1 parent 75bef3c commit 04eabe5
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cmd/kube-scheduler/app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type Config struct {

// LeaderElection is optional.
LeaderElection *leaderelection.LeaderElectionConfig

// OpenShiftContext is additional context that we need to launch the kube-scheduler for openshift
OpenShiftContext OpenShiftContext
}

type completedConfig struct {
Expand Down
15 changes: 15 additions & 0 deletions cmd/kube-scheduler/app/config/patch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package config

import (
"k8s.io/client-go/transport"

"github.com/openshift/library-go/pkg/monitor/health"
)

// OpenShiftContext is additional context that we need to launch the kube-scheduler for openshift.
// Basically, this holds our additional config information.
type OpenShiftContext struct {
UnsupportedKubeAPIOverPreferredHost bool
PreferredHostRoundTripperWrapperFn transport.WrapperFunc
PreferredHostHealthMonitor *health.Prober
}
12 changes: 12 additions & 0 deletions cmd/kube-scheduler/app/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import (
kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
"k8s.io/kubernetes/pkg/scheduler/apis/config/validation"
netutils "k8s.io/utils/net"

libgorestclient "github.com/openshift/library-go/pkg/config/client"
)

// Options has all the params needed to run a Scheduler
Expand All @@ -71,6 +73,9 @@ type Options struct {

// Flags hold the parsed CLI flags.
Flags *cliflag.NamedFlagSets

// OpenShiftContext is additional context that we need to launch the kube-scheduler for openshift.
OpenShiftContext schedulerappconfig.OpenShiftContext
}

// NewOptions returns default scheduler app options.
Expand Down Expand Up @@ -184,6 +189,7 @@ func (o *Options) initFlags() {
fs.StringVar(&o.ConfigFile, "config", o.ConfigFile, "The path to the configuration file.")
fs.StringVar(&o.WriteConfigTo, "write-config-to", o.WriteConfigTo, "If set, write the configuration values to this file and exit.")
fs.StringVar(&o.Master, "master", o.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)")
fs.BoolVar(&o.OpenShiftContext.UnsupportedKubeAPIOverPreferredHost, "unsupported-kube-api-over-localhost", false, "when set makes KS prefer talking to localhost kube-apiserver (when available) instead of an LB")

o.SecureServing.AddFlags(nfs.FlagSet("secure serving"))
o.Authentication.AddFlags(nfs.FlagSet("authentication"))
Expand Down Expand Up @@ -262,13 +268,19 @@ func (o *Options) Config() (*schedulerappconfig.Config, error) {
if err := o.ApplyTo(c); err != nil {
return nil, err
}
c.OpenShiftContext = o.OpenShiftContext

// Prepare kube config.
kubeConfig, err := createKubeConfig(c.ComponentConfig.ClientConnection, o.Master)
if err != nil {
return nil, err
}

if c.OpenShiftContext.PreferredHostRoundTripperWrapperFn != nil {
libgorestclient.DefaultServerName(kubeConfig)
kubeConfig.Wrap(c.OpenShiftContext.PreferredHostRoundTripperWrapperFn)
}

// Prepare kube clients.
client, eventClient, err := createClients(kubeConfig)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions cmd/kube-scheduler/app/options/patch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package options

import kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"

func LoadKubeSchedulerConfiguration(file string) (*kubeschedulerconfig.KubeSchedulerConfiguration, error) {
return loadConfigFromFile(file)
}
69 changes: 69 additions & 0 deletions cmd/kube-scheduler/app/patch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package app

import (
"time"

"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/component-base/metrics/legacyregistry"
"k8s.io/kubernetes/cmd/kube-scheduler/app/options"

libgorestclient "github.com/openshift/library-go/pkg/config/client"
"github.com/openshift/library-go/pkg/monitor/health"
)

func setUpPreferredHostForOpenShift(kubeSchedulerOptions *options.Options) error {
if !kubeSchedulerOptions.OpenShiftContext.UnsupportedKubeAPIOverPreferredHost {
return nil
}

master, kubeConfig := kubeSchedulerOptions.Master, kubeSchedulerOptions.ComponentConfig.ClientConnection.Kubeconfig

// this makes our patch small
// if there was no kubeconfig specified we won't be able to get cluster info.
// in that case try to load the configuration and read kubeconfig directly from it if it was provided.
if len(kubeConfig) == 0 && len(kubeSchedulerOptions.ConfigFile) > 0 {
cfg, err := options.LoadKubeSchedulerConfiguration(kubeSchedulerOptions.ConfigFile)
if err != nil {
return err
}
kubeConfig = cfg.ClientConnection.Kubeconfig
}

config, err := clientcmd.BuildConfigFromFlags(master, kubeConfig)
if err != nil {
return err
}
libgorestclient.DefaultServerName(config)

targetProvider := health.StaticTargetProvider{"localhost:6443"}
kubeSchedulerOptions.OpenShiftContext.PreferredHostHealthMonitor, err = health.New(targetProvider, createRestConfigForHealthMonitor(config))
if err != nil {
return err
}
kubeSchedulerOptions.OpenShiftContext.PreferredHostHealthMonitor.
WithHealthyProbesThreshold(3).
WithUnHealthyProbesThreshold(5).
WithProbeInterval(5 * time.Second).
WithProbeResponseTimeout(2 * time.Second).
WithMetrics(health.Register(legacyregistry.MustRegister))

kubeSchedulerOptions.OpenShiftContext.PreferredHostRoundTripperWrapperFn = libgorestclient.NewPreferredHostRoundTripper(func() string {
healthyTargets, _ := kubeSchedulerOptions.OpenShiftContext.PreferredHostHealthMonitor.Targets()
if len(healthyTargets) == 1 {
return healthyTargets[0]
}
return ""
})

kubeSchedulerOptions.Authentication.WithCustomRoundTripper(kubeSchedulerOptions.OpenShiftContext.PreferredHostRoundTripperWrapperFn)
kubeSchedulerOptions.Authorization.WithCustomRoundTripper(kubeSchedulerOptions.OpenShiftContext.PreferredHostRoundTripperWrapperFn)
return nil
}

func createRestConfigForHealthMonitor(restConfig *rest.Config) *rest.Config {
restConfigCopy := *restConfig
rest.AddUserAgent(&restConfigCopy, "kube-scheduler-health-monitor")

return &restConfigCopy
}
9 changes: 9 additions & 0 deletions cmd/kube-scheduler/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ func runCommand(cmd *cobra.Command, opts *options.Options, registryOptions ...Op
cancel()
}()

if err := setUpPreferredHostForOpenShift(opts); err != nil {
return err
}

cc, sched, err := Setup(ctx, opts, registryOptions...)
if err != nil {
return err
Expand All @@ -138,6 +142,11 @@ func Run(ctx context.Context, cc *schedulerserverconfig.CompletedConfig, sched *
// To help debugging, immediately log version
klog.InfoS("Starting Kubernetes Scheduler", "version", version.Get())

// start the localhost health monitor early so that it can be used by the LE client
if cc.OpenShiftContext.PreferredHostHealthMonitor != nil {
go cc.OpenShiftContext.PreferredHostHealthMonitor.Run(ctx)
}

// Configz registration.
if cz, err := configz.New("componentconfig"); err == nil {
cz.Set(cc.ComponentConfig)
Expand Down

0 comments on commit 04eabe5

Please sign in to comment.