Merge pull request #96345 from ingvagabund/disable-insecure-port-in-scheduler

refactor: disable insecure serving in kube-scheduler
This commit is contained in:
Kubernetes Prow Robot 2021-09-14 08:01:09 -07:00 committed by GitHub
commit c10be982d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 117 additions and 1027 deletions

View File

@ -36,11 +36,9 @@ type Config struct {
// LoopbackClientConfig is a config for a privileged loopback connection
LoopbackClientConfig *restclient.Config
InsecureServing *apiserver.DeprecatedInsecureServingInfo // nil will disable serving on an insecure port
InsecureMetricsServing *apiserver.DeprecatedInsecureServingInfo // non-nil if metrics should be served independently
Authentication apiserver.AuthenticationInfo
Authorization apiserver.AuthorizationInfo
SecureServing *apiserver.SecureServingInfo
Authentication apiserver.AuthenticationInfo
Authorization apiserver.AuthorizationInfo
SecureServing *apiserver.SecureServingInfo
Client clientset.Interface
KubeConfig *restclient.Config
@ -67,13 +65,6 @@ type CompletedConfig struct {
func (c *Config) Complete() CompletedConfig {
cc := completedConfig{c}
if c.InsecureServing != nil {
c.InsecureServing.Name = "healthz"
}
if c.InsecureMetricsServing != nil {
c.InsecureMetricsServing.Name = "metrics"
}
apiserver.AuthorizeClientBearerToken(c.LoopbackClientConfig, &c.Authentication, &c.Authorization)
return CompletedConfig{&cc}

View File

@ -1,67 +0,0 @@
/*
Copyright 2018 The Kubernetes Authors.
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 config
import (
"testing"
"github.com/google/go-cmp/cmp"
apiserver "k8s.io/apiserver/pkg/server"
)
func TestConfigComplete(t *testing.T) {
scenarios := []struct {
name string
want *Config
config *Config
}{
{
name: "SetInsecureServingName",
want: &Config{
InsecureServing: &apiserver.DeprecatedInsecureServingInfo{
Name: "healthz",
},
},
config: &Config{
InsecureServing: &apiserver.DeprecatedInsecureServingInfo{},
},
},
{
name: "SetMetricsInsecureServingName",
want: &Config{
InsecureMetricsServing: &apiserver.DeprecatedInsecureServingInfo{
Name: "metrics",
},
},
config: &Config{
InsecureMetricsServing: &apiserver.DeprecatedInsecureServingInfo{},
},
},
}
for _, scenario := range scenarios {
t.Run(scenario.name, func(t *testing.T) {
cc := scenario.config.Complete()
returnValue := cc.completedConfig.Config
if diff := cmp.Diff(scenario.want, returnValue); diff != "" {
t.Errorf("Complete(): Unexpected return value (-want, +got): %s", diff)
}
})
}
}

View File

@ -18,6 +18,7 @@ package options
import (
"fmt"
"net"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/util/validation/field"
@ -34,6 +35,20 @@ type DeprecatedOptions struct {
PolicyConfigMapName string
PolicyConfigMapNamespace string
UseLegacyPolicyConfig bool
Port int
}
// TODO: remove these insecure flags in v1.24
func addDummyInsecureFlags(o *DeprecatedOptions, fs *pflag.FlagSet) {
var (
bindAddr = net.IPv4(127, 0, 0, 1)
)
fs.IPVar(&bindAddr, "address", bindAddr,
"The IP address on which to serve the insecure --port (set to 0.0.0.0 for all IPv4 interfaces and :: for all IPv6 interfaces).")
fs.MarkDeprecated("address", "This flag has no effect now and will be removed in v1.24. You can use --bind-address instead.")
fs.IntVar(&o.Port, "port", o.Port, "The port on which to serve unsecured, unauthenticated access. Set to 0 to disable.")
fs.MarkDeprecated("port", "This flag has no effect now and will be removed in v1.24. You can use --secure-port instead.")
}
// AddFlags adds flags for the deprecated options.
@ -42,6 +57,8 @@ func (o *DeprecatedOptions) AddFlags(fs *pflag.FlagSet, cfg *kubeschedulerconfig
return
}
addDummyInsecureFlags(o, fs)
fs.StringVar(&o.PolicyConfigFile, "policy-config-file", o.PolicyConfigFile, "DEPRECATED: file with scheduler policy configuration. This file is used if policy ConfigMap is not provided or --use-legacy-policy-config=true. Note: The predicates/priorities defined in this file will take precedence over any profiles define in ComponentConfig.")
usage := fmt.Sprintf("DEPRECATED: name of the ConfigMap object that contains scheduler's policy configuration. It must exist in the system namespace before scheduler initialization if --use-legacy-policy-config=false. The config must be provided as the value of an element in 'Data' map with the key='%v'. Note: The predicates/priorities defined in this file will take precedence over any profiles define in ComponentConfig.", kubeschedulerconfig.SchedulerPolicyConfigMapKey)
fs.StringVar(&o.PolicyConfigMapName, "policy-configmap", o.PolicyConfigMapName, usage)
@ -66,6 +83,10 @@ func (o *DeprecatedOptions) Validate() []error {
errs = append(errs, field.Required(field.NewPath("policyConfigFile"), "required when --use-legacy-policy-config is true"))
}
// TODO: delete this check after insecure flags removed in v1.24
if o.Port != 0 {
errs = append(errs, field.Required(field.NewPath("port"), fmt.Sprintf("invalid port value %d: only zero is allowed", o.Port)))
}
return errs
}

View File

@ -1,151 +0,0 @@
/*
Copyright 2018 The Kubernetes Authors.
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 options
import (
"fmt"
"net"
"strconv"
"github.com/spf13/pflag"
apiserveroptions "k8s.io/apiserver/pkg/server/options"
schedulerappconfig "k8s.io/kubernetes/cmd/kube-scheduler/app/config"
kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
netutils "k8s.io/utils/net"
)
// CombinedInsecureServingOptions sets up to two insecure listeners for healthz and metrics. The flags
// override the ComponentConfig and DeprecatedInsecureServingOptions values for both.
type CombinedInsecureServingOptions struct {
Healthz *apiserveroptions.DeprecatedInsecureServingOptionsWithLoopback
Metrics *apiserveroptions.DeprecatedInsecureServingOptionsWithLoopback
BindPort int // overrides the structs above on ApplyTo, ignored on ApplyToFromLoadedConfig
BindAddress string // overrides the structs above on ApplyTo, ignored on ApplyToFromLoadedConfig
}
// AddFlags adds flags for the insecure serving options.
func (o *CombinedInsecureServingOptions) AddFlags(fs *pflag.FlagSet) {
if o == nil {
return
}
fs.StringVar(&o.BindAddress, "address", o.BindAddress, "DEPRECATED: the IP address on which to listen for the --port port (set to 0.0.0.0 or :: for listening in all interfaces and IP families). See --bind-address instead. This parameter is ignored if a config file is specified in --config.")
// MarkDeprecated hides the flag from the help. We don't want that:
// fs.MarkDeprecated("address", "see --bind-address instead.")
fs.IntVar(&o.BindPort, "port", o.BindPort, "DEPRECATED: the port on which to serve HTTP insecurely without authentication and authorization. If 0, don't serve plain HTTP at all. See --secure-port instead. This parameter is ignored if a config file is specified in --config.")
// MarkDeprecated hides the flag from the help. We don't want that:
// fs.MarkDeprecated("port", "see --secure-port instead.")
}
func (o *CombinedInsecureServingOptions) applyTo(c *schedulerappconfig.Config, componentConfig *kubeschedulerconfig.KubeSchedulerConfiguration) error {
updateAddressFromDeprecatedInsecureServingOptions(&componentConfig.HealthzBindAddress, o.Healthz)
updateAddressFromDeprecatedInsecureServingOptions(&componentConfig.MetricsBindAddress, o.Metrics)
if err := o.Healthz.ApplyTo(&c.InsecureServing, &c.LoopbackClientConfig); err != nil {
return err
}
if o.Metrics != nil && (c.ComponentConfig.MetricsBindAddress != c.ComponentConfig.HealthzBindAddress || o.Healthz == nil) {
if err := o.Metrics.ApplyTo(&c.InsecureMetricsServing, &c.LoopbackClientConfig); err != nil {
return err
}
}
return nil
}
// ApplyTo applies the insecure serving options to the given scheduler app configuration, and updates the componentConfig.
func (o *CombinedInsecureServingOptions) ApplyTo(c *schedulerappconfig.Config, componentConfig *kubeschedulerconfig.KubeSchedulerConfiguration) error {
if o == nil {
componentConfig.HealthzBindAddress = ""
componentConfig.MetricsBindAddress = ""
return nil
}
if o.Healthz != nil {
o.Healthz.BindPort = o.BindPort
o.Healthz.BindAddress = netutils.ParseIPSloppy(o.BindAddress)
}
if o.Metrics != nil {
o.Metrics.BindPort = o.BindPort
o.Metrics.BindAddress = netutils.ParseIPSloppy(o.BindAddress)
}
return o.applyTo(c, componentConfig)
}
// ApplyToFromLoadedConfig updates the insecure serving options from the component config and then applies it to the given scheduler app configuration.
func (o *CombinedInsecureServingOptions) ApplyToFromLoadedConfig(c *schedulerappconfig.Config, componentConfig *kubeschedulerconfig.KubeSchedulerConfiguration) error {
if o == nil {
return nil
}
updateDeprecatedInsecureServingOptionsFromAddress(o.Healthz, componentConfig.HealthzBindAddress)
updateDeprecatedInsecureServingOptionsFromAddress(o.Metrics, componentConfig.MetricsBindAddress)
return o.applyTo(c, componentConfig)
}
func updateAddressFromDeprecatedInsecureServingOptions(addr *string, is *apiserveroptions.DeprecatedInsecureServingOptionsWithLoopback) {
if is == nil {
*addr = ""
return
}
if is.Listener != nil {
*addr = is.Listener.Addr().String()
} else if is.BindPort == 0 {
*addr = ""
} else {
*addr = net.JoinHostPort(is.BindAddress.String(), strconv.Itoa(is.BindPort))
}
}
func updateDeprecatedInsecureServingOptionsFromAddress(is *apiserveroptions.DeprecatedInsecureServingOptionsWithLoopback, addr string) {
if is == nil {
return
}
if len(addr) == 0 {
is.BindPort = 0
} else {
// In the previous `validate` process, we can ensure that the `addr` is legal, so ignore the error
host, portInt, _ := splitHostIntPort(addr)
is.BindAddress = netutils.ParseIPSloppy(host)
is.BindPort = portInt
}
}
// Validate validates the insecure serving options.
func (o *CombinedInsecureServingOptions) Validate() []error {
if o == nil {
return nil
}
errors := []error{}
if o.BindPort < 0 || o.BindPort > 65535 {
errors = append(errors, fmt.Errorf("--port %v must be between 0 and 65535, inclusive. 0 for turning off insecure (HTTP) port", o.BindPort))
}
if len(o.BindAddress) > 0 && netutils.ParseIPSloppy(o.BindAddress) == nil {
errors = append(errors, fmt.Errorf("--address %v is an invalid IP address", o.BindAddress))
}
return errors
}

View File

@ -1,276 +0,0 @@
/*
Copyright 2018 The Kubernetes Authors.
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 options
import (
"fmt"
"net"
"strconv"
"testing"
"k8s.io/apimachinery/pkg/util/rand"
apiserveroptions "k8s.io/apiserver/pkg/server/options"
schedulerappconfig "k8s.io/kubernetes/cmd/kube-scheduler/app/config"
kubeschedulerconfig "k8s.io/kubernetes/pkg/scheduler/apis/config"
)
func TestOptions_ApplyTo(t *testing.T) {
tests := []struct {
name string
options Options
configLoaded bool
expectHealthzBindAddress, expectMetricsBindAddress string
expectInsecureServingAddress, expectInsecureMetricsServingAddress string
expectInsecureServingPort, expectInsecureMetricsServingPort int
wantErr bool
}{
{
name: "no config, zero port",
options: Options{
ComponentConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
HealthzBindAddress: "1.2.3.4:1234",
MetricsBindAddress: "1.2.3.4:1234",
},
CombinedInsecureServing: &CombinedInsecureServingOptions{
Healthz: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
Metrics: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
BindPort: 0,
},
},
configLoaded: false,
},
{
name: "config loaded, non-nil healthz",
options: Options{
ComponentConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
HealthzBindAddress: "1.2.3.4:1234",
MetricsBindAddress: "1.2.3.4:1234",
},
CombinedInsecureServing: &CombinedInsecureServingOptions{
Healthz: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
BindPort: 0,
},
},
configLoaded: true,
expectHealthzBindAddress: "1.2.3.4:1234",
expectInsecureServingPort: 1234,
expectInsecureServingAddress: "1.2.3.4",
},
{
name: "config loaded, non-nil metrics",
options: Options{
ComponentConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
HealthzBindAddress: "1.2.3.4:1234",
MetricsBindAddress: "1.2.3.4:1234",
},
CombinedInsecureServing: &CombinedInsecureServingOptions{
Metrics: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
BindPort: 0,
},
},
configLoaded: true,
expectMetricsBindAddress: "1.2.3.4:1234",
expectInsecureMetricsServingPort: 1234,
expectInsecureMetricsServingAddress: "1.2.3.4",
},
{
name: "config loaded, all set, zero BindPort",
options: Options{
ComponentConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
HealthzBindAddress: "1.2.3.4:1234",
MetricsBindAddress: "1.2.3.4:1234",
},
CombinedInsecureServing: &CombinedInsecureServingOptions{
Healthz: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
Metrics: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
BindPort: 0,
},
},
configLoaded: true,
expectHealthzBindAddress: "1.2.3.4:1234",
expectInsecureServingPort: 1234,
expectInsecureServingAddress: "1.2.3.4",
expectMetricsBindAddress: "1.2.3.4:1234",
},
{
name: "config loaded, all set, different addresses",
options: Options{
ComponentConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
HealthzBindAddress: "1.2.3.4:1234",
MetricsBindAddress: "1.2.3.4:1235",
},
CombinedInsecureServing: &CombinedInsecureServingOptions{
Healthz: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
Metrics: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
BindPort: 0,
},
},
configLoaded: true,
expectHealthzBindAddress: "1.2.3.4:1234",
expectInsecureServingPort: 1234,
expectInsecureServingAddress: "1.2.3.4",
expectMetricsBindAddress: "1.2.3.4:1235",
expectInsecureMetricsServingPort: 1235,
expectInsecureMetricsServingAddress: "1.2.3.4",
},
{
name: "no config, all set, port passed",
options: Options{
ComponentConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
HealthzBindAddress: "1.2.3.4:1234",
MetricsBindAddress: "1.2.3.4:1234",
},
CombinedInsecureServing: &CombinedInsecureServingOptions{
Healthz: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
Metrics: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
BindPort: 1236,
BindAddress: "1.2.3.4",
},
},
configLoaded: false,
expectHealthzBindAddress: "1.2.3.4:1236",
expectInsecureServingPort: 1236,
expectInsecureServingAddress: "1.2.3.4",
expectMetricsBindAddress: "1.2.3.4:1236",
},
{
name: "no config, all set, address passed",
options: Options{
ComponentConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
HealthzBindAddress: "1.2.3.4:1234",
MetricsBindAddress: "1.2.3.4:1234",
},
CombinedInsecureServing: &CombinedInsecureServingOptions{
Healthz: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
Metrics: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
BindAddress: "2.3.4.5",
BindPort: 1234,
},
},
configLoaded: false,
expectHealthzBindAddress: "2.3.4.5:1234",
expectInsecureServingPort: 1234,
expectInsecureServingAddress: "2.3.4.5",
expectMetricsBindAddress: "2.3.4.5:1234",
},
{
name: "no config, all set, zero port passed",
options: Options{
ComponentConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
HealthzBindAddress: "1.2.3.4:1234",
MetricsBindAddress: "1.2.3.4:1234",
},
CombinedInsecureServing: &CombinedInsecureServingOptions{
Healthz: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
Metrics: (&apiserveroptions.DeprecatedInsecureServingOptions{}).WithLoopback(),
BindAddress: "2.3.4.5",
BindPort: 0,
},
},
configLoaded: false,
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("%d-%s", i, tt.name), func(t *testing.T) {
c := schedulerappconfig.Config{
ComponentConfig: tt.options.ComponentConfig,
}
if tt.options.CombinedInsecureServing != nil {
if tt.options.CombinedInsecureServing.Healthz != nil {
tt.options.CombinedInsecureServing.Healthz.ListenFunc = createMockListener
}
if tt.options.CombinedInsecureServing.Metrics != nil {
tt.options.CombinedInsecureServing.Metrics.ListenFunc = createMockListener
}
}
if tt.configLoaded {
if err := tt.options.CombinedInsecureServing.ApplyToFromLoadedConfig(&c, &c.ComponentConfig); (err != nil) != tt.wantErr {
t.Fatalf("%d - Options.ApplyTo() error = %v, wantErr %v", i, err, tt.wantErr)
}
} else {
if err := tt.options.CombinedInsecureServing.ApplyTo(&c, &c.ComponentConfig); (err != nil) != tt.wantErr {
t.Fatalf("%d - Options.ApplyTo() error = %v, wantErr %v", i, err, tt.wantErr)
}
}
if got, expect := c.ComponentConfig.HealthzBindAddress, tt.expectHealthzBindAddress; got != expect {
t.Errorf("%d - expected HealthzBindAddress %q, got %q", i, expect, got)
}
if got, expect := c.ComponentConfig.MetricsBindAddress, tt.expectMetricsBindAddress; got != expect {
t.Errorf("%d - expected MetricsBindAddress %q, got %q", i, expect, got)
}
if got, expect := c.InsecureServing != nil, tt.expectInsecureServingPort != 0; got != expect {
t.Errorf("%d - expected InsecureServing != nil to be %v, got %v", i, expect, got)
} else if c.InsecureServing != nil {
if got, expect := c.InsecureServing.Listener.(*mockListener).address, tt.expectInsecureServingAddress; got != expect {
t.Errorf("%d - expected healthz address %q, got %q", i, expect, got)
}
if got, expect := c.InsecureServing.Listener.(*mockListener).port, tt.expectInsecureServingPort; got != expect {
t.Errorf("%d - expected healthz port %v, got %v", i, expect, got)
}
}
if got, expect := c.InsecureMetricsServing != nil, tt.expectInsecureMetricsServingPort != 0; got != expect {
t.Errorf("%d - expected Metrics != nil to be %v, got %v", i, expect, got)
} else if c.InsecureMetricsServing != nil {
if got, expect := c.InsecureMetricsServing.Listener.(*mockListener).address, tt.expectInsecureMetricsServingAddress; got != expect {
t.Errorf("%d - expected metrics address %q, got %q", i, expect, got)
}
if got, expect := c.InsecureMetricsServing.Listener.(*mockListener).port, tt.expectInsecureMetricsServingPort; got != expect {
t.Errorf("%d - expected metrics port %v, got %v", i, expect, got)
}
}
})
}
}
type mockListener struct {
address string
port int
}
func createMockListener(network, addr string, config net.ListenConfig) (net.Listener, int, error) {
host, portInt, err := splitHostIntPort(addr)
if err != nil {
return nil, 0, err
}
if portInt == 0 {
portInt = rand.IntnRange(1, 32767)
}
return &mockListener{host, portInt}, portInt, nil
}
func (l *mockListener) Accept() (net.Conn, error) { return nil, nil }
func (l *mockListener) Close() error { return nil }
func (l *mockListener) Addr() net.Addr {
return mockAddr(net.JoinHostPort(l.address, strconv.Itoa(l.port)))
}
type mockAddr string
func (a mockAddr) Network() string { return "tcp" }
func (a mockAddr) String() string { return string(a) }

View File

@ -20,7 +20,6 @@ import (
"fmt"
"net"
"os"
"strconv"
"time"
corev1 "k8s.io/api/core/v1"
@ -50,16 +49,15 @@ import (
// Options has all the params needed to run a Scheduler
type Options struct {
// The default values. These are overridden if ConfigFile is set or by values in InsecureServing.
// The default values.
ComponentConfig kubeschedulerconfig.KubeSchedulerConfiguration
SecureServing *apiserveroptions.SecureServingOptionsWithLoopback
CombinedInsecureServing *CombinedInsecureServingOptions
Authentication *apiserveroptions.DelegatingAuthenticationOptions
Authorization *apiserveroptions.DelegatingAuthorizationOptions
Metrics *metrics.Options
Logs *logs.Options
Deprecated *DeprecatedOptions
SecureServing *apiserveroptions.SecureServingOptionsWithLoopback
Authentication *apiserveroptions.DelegatingAuthenticationOptions
Authorization *apiserveroptions.DelegatingAuthorizationOptions
Metrics *metrics.Options
Logs *logs.Options
Deprecated *DeprecatedOptions
// ConfigFile is the location of the scheduler server's configuration file.
ConfigFile string
@ -73,14 +71,7 @@ type Options struct {
// NewOptions returns default scheduler app options.
func NewOptions() (*Options, error) {
o := &Options{
SecureServing: apiserveroptions.NewSecureServingOptions().WithLoopback(),
CombinedInsecureServing: &CombinedInsecureServingOptions{
Healthz: (&apiserveroptions.DeprecatedInsecureServingOptions{
BindNetwork: "tcp",
}).WithLoopback(),
Metrics: (&apiserveroptions.DeprecatedInsecureServingOptions{
BindNetwork: "tcp"}).WithLoopback(),
},
SecureServing: apiserveroptions.NewSecureServingOptions().WithLoopback(),
Authentication: apiserveroptions.NewDelegatingAuthenticationOptions(),
Authorization: apiserveroptions.NewDelegatingAuthorizationOptions(),
Deprecated: &DeprecatedOptions{
@ -111,19 +102,6 @@ func (o *Options) Complete(nfs *cliflag.NamedFlagSets) error {
return err
}
hhost, hport, err := splitHostIntPort(cfg.HealthzBindAddress)
if err != nil {
return err
}
// Obtain CLI args related with insecure serving.
// If not specified in command line, derive the default settings from cfg.
insecureServing := nfs.FlagSet("insecure serving")
if !insecureServing.Changed("address") {
o.CombinedInsecureServing.BindAddress = hhost
}
if !insecureServing.Changed("port") {
o.CombinedInsecureServing.BindPort = hport
}
// Obtain deprecated CLI args. Set them to cfg if specified in command line.
deprecated := nfs.FlagSet("deprecated")
if deprecated.Changed("profiling") {
@ -178,18 +156,6 @@ func (o *Options) Complete(nfs *cliflag.NamedFlagSets) error {
return nil
}
func splitHostIntPort(s string) (string, int, error) {
host, port, err := net.SplitHostPort(s)
if err != nil {
return "", 0, err
}
portInt, err := strconv.Atoi(port)
if err != nil {
return "", 0, err
}
return host, portInt, err
}
// Flags returns flags for a specific scheduler by section name
func (o *Options) Flags() (nfs cliflag.NamedFlagSets) {
fs := nfs.FlagSet("misc")
@ -201,7 +167,6 @@ func (o *Options) Flags() (nfs cliflag.NamedFlagSets) {
fs.StringVar(&o.Master, "master", o.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)")
o.SecureServing.AddFlags(nfs.FlagSet("secure serving"))
o.CombinedInsecureServing.AddFlags(nfs.FlagSet("insecure serving"))
o.Authentication.AddFlags(nfs.FlagSet("authentication"))
o.Authorization.AddFlags(nfs.FlagSet("authorization"))
o.Deprecated.AddFlags(nfs.FlagSet("deprecated"), &o.ComponentConfig)
@ -220,10 +185,6 @@ func (o *Options) ApplyTo(c *schedulerappconfig.Config) error {
c.ComponentConfig = o.ComponentConfig
o.Deprecated.ApplyTo(c)
if err := o.CombinedInsecureServing.ApplyTo(c, &c.ComponentConfig); err != nil {
return err
}
} else {
cfg, err := loadConfigFromFile(o.ConfigFile)
if err != nil {
@ -237,11 +198,6 @@ func (o *Options) ApplyTo(c *schedulerappconfig.Config) error {
// apply any deprecated Policy flags, if applicable
o.Deprecated.ApplyTo(c)
// use the loaded config file only, with the exception of --address and --port.
if err := o.CombinedInsecureServing.ApplyToFromLoadedConfig(c, &c.ComponentConfig); err != nil {
return err
}
}
// If the user is using the legacy policy config, clear the profiles, they will be set
@ -274,7 +230,6 @@ func (o *Options) Validate() []error {
errs = append(errs, err.Errors()...)
}
errs = append(errs, o.SecureServing.Validate()...)
errs = append(errs, o.CombinedInsecureServing.Validate()...)
errs = append(errs, o.Authentication.Validate()...)
errs = append(errs, o.Authorization.Validate()...)
errs = append(errs, o.Deprecated.Validate()...)

View File

@ -379,9 +379,7 @@ profiles:
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta2.SchemeGroupVersion.String(),
},
Parallelism: 16,
HealthzBindAddress: "0.0.0.0:10251",
MetricsBindAddress: "0.0.0.0:10251",
Parallelism: 16,
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: true,
EnableContentionProfiling: true,
@ -452,9 +450,7 @@ profiles:
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta1.SchemeGroupVersion.String(),
},
Parallelism: 16,
HealthzBindAddress: "0.0.0.0:10251",
MetricsBindAddress: "0.0.0.0:10251",
Parallelism: 16,
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: true,
EnableContentionProfiling: true,
@ -556,9 +552,7 @@ profiles:
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta2.SchemeGroupVersion.String(),
},
Parallelism: 16,
HealthzBindAddress: "", // defaults empty when not running from config file
MetricsBindAddress: "", // defaults empty when not running from config file
Parallelism: 16,
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: true,
EnableContentionProfiling: true,
@ -628,9 +622,7 @@ profiles:
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta2.SchemeGroupVersion.String(),
},
Parallelism: 16,
HealthzBindAddress: "", // defaults empty when not running from config file
MetricsBindAddress: "", // defaults empty when not running from config file
Parallelism: 16,
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: true,
EnableContentionProfiling: true,
@ -674,9 +666,7 @@ profiles:
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta2.SchemeGroupVersion.String(),
},
Parallelism: 16,
HealthzBindAddress: "0.0.0.0:10251",
MetricsBindAddress: "0.0.0.0:10251",
Parallelism: 16,
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: true,
EnableContentionProfiling: true,
@ -790,9 +780,7 @@ profiles:
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta1.SchemeGroupVersion.String(),
},
Parallelism: 16,
HealthzBindAddress: "0.0.0.0:10251",
MetricsBindAddress: "0.0.0.0:10251",
Parallelism: 16,
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: true,
EnableContentionProfiling: true,
@ -919,9 +907,7 @@ profiles:
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta2.SchemeGroupVersion.String(),
},
Parallelism: 16,
HealthzBindAddress: "0.0.0.0:10251",
MetricsBindAddress: "0.0.0.0:10251",
Parallelism: 16,
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: true,
EnableContentionProfiling: true,
@ -1041,9 +1027,7 @@ profiles:
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta1.SchemeGroupVersion.String(),
},
Parallelism: 16,
HealthzBindAddress: "0.0.0.0:10251",
MetricsBindAddress: "0.0.0.0:10251",
Parallelism: 16,
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: true,
EnableContentionProfiling: true,
@ -1172,9 +1156,7 @@ profiles:
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta2.SchemeGroupVersion.String(),
},
Parallelism: 16,
HealthzBindAddress: "0.0.0.0:10251",
MetricsBindAddress: "0.0.0.0:10251",
Parallelism: 16,
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: true,
EnableContentionProfiling: true,

View File

@ -169,21 +169,8 @@ func Run(ctx context.Context, cc *schedulerserverconfig.CompletedConfig, sched *
}
// Start up the healthz server.
if cc.InsecureServing != nil {
separateMetrics := cc.InsecureMetricsServing != nil
handler := buildHandlerChain(newHealthzHandler(&cc.ComponentConfig, cc.InformerFactory, isLeader, separateMetrics, checks...), nil, nil)
if err := cc.InsecureServing.Serve(handler, 0, ctx.Done()); err != nil {
return fmt.Errorf("failed to start healthz server: %v", err)
}
}
if cc.InsecureMetricsServing != nil {
handler := buildHandlerChain(newMetricsHandler(&cc.ComponentConfig, cc.InformerFactory, isLeader), nil, nil)
if err := cc.InsecureMetricsServing.Serve(handler, 0, ctx.Done()); err != nil {
return fmt.Errorf("failed to start metrics server: %v", err)
}
}
if cc.SecureServing != nil {
handler := buildHandlerChain(newHealthzHandler(&cc.ComponentConfig, cc.InformerFactory, isLeader, false, checks...), cc.Authentication.Authenticator, cc.Authorization.Authorizer)
handler := buildHandlerChain(newHealthzAndMetricsHandler(&cc.ComponentConfig, cc.InformerFactory, isLeader, checks...), cc.Authentication.Authenticator, cc.Authorization.Authorizer)
// TODO: handle stoppedCh returned by c.SecureServing.Serve
if _, err := cc.SecureServing.Serve(handler, 0, ctx.Done()); err != nil {
// fail early for secure handlers, removing the old error loop from above
@ -260,29 +247,12 @@ func installMetricHandler(pathRecorderMux *mux.PathRecorderMux, informers inform
})
}
// newMetricsHandler builds a metrics server from the config.
func newMetricsHandler(config *kubeschedulerconfig.KubeSchedulerConfiguration, informers informers.SharedInformerFactory, isLeader func() bool) http.Handler {
pathRecorderMux := mux.NewPathRecorderMux("kube-scheduler")
installMetricHandler(pathRecorderMux, informers, isLeader)
if config.EnableProfiling {
routes.Profiling{}.Install(pathRecorderMux)
if config.EnableContentionProfiling {
goruntime.SetBlockProfileRate(1)
}
routes.DebugFlags{}.Install(pathRecorderMux, "v", routes.StringFlagPutHandler(logs.GlogSetter))
}
return pathRecorderMux
}
// newHealthzHandler creates a healthz server from the config, and will also
// embed the metrics handler if the healthz and metrics address configurations
// are the same.
func newHealthzHandler(config *kubeschedulerconfig.KubeSchedulerConfiguration, informers informers.SharedInformerFactory, isLeader func() bool, separateMetrics bool, checks ...healthz.HealthChecker) http.Handler {
// newHealthzAndMetricsHandler creates a healthz server from the config, and will also
// embed the metrics handler.
func newHealthzAndMetricsHandler(config *kubeschedulerconfig.KubeSchedulerConfiguration, informers informers.SharedInformerFactory, isLeader func() bool, checks ...healthz.HealthChecker) http.Handler {
pathRecorderMux := mux.NewPathRecorderMux("kube-scheduler")
healthz.InstallHandler(pathRecorderMux, checks...)
if !separateMetrics {
installMetricHandler(pathRecorderMux, informers, isLeader)
}
installMetricHandler(pathRecorderMux, informers, isLeader)
if config.EnableProfiling {
routes.Profiling{}.Install(pathRecorderMux)
if config.EnableContentionProfiling {

View File

@ -264,10 +264,6 @@ profiles:
// use listeners instead of static ports so parallel test runs don't conflict
opts.SecureServing.Listener = makeListener(t)
defer opts.SecureServing.Listener.Close()
opts.CombinedInsecureServing.Metrics.Listener = makeListener(t)
defer opts.CombinedInsecureServing.Metrics.Listener.Close()
opts.CombinedInsecureServing.Healthz.Listener = makeListener(t)
defer opts.CombinedInsecureServing.Healthz.Listener.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

View File

@ -107,17 +107,6 @@ func StartTestServer(t Logger, customFlags []string) (result TestServer, err err
t.Logf("kube-scheduler will listen securely on port %d...", opts.SecureServing.BindPort)
}
if opts.CombinedInsecureServing.BindPort != 0 {
listener, port, err := createListenerOnFreePort()
if err != nil {
return result, fmt.Errorf("failed to create listener: %v", err)
}
opts.CombinedInsecureServing.BindPort = port
opts.CombinedInsecureServing.Healthz.Listener = listener
opts.CombinedInsecureServing.Metrics.Listener = listener
t.Logf("kube-scheduler will listen insecurely on port %d...", opts.CombinedInsecureServing.BindPort)
}
cc, sched, err := app.Setup(ctx, opts)
if err != nil {
return result, fmt.Errorf("failed to create config from options: %v", err)

View File

@ -347,7 +347,7 @@ func (s componentStatusStorage) serversToValidate() map[string]*componentstatus.
// TODO: switch to secure port until these components remove the ability to serve insecurely.
serversToValidate := map[string]*componentstatus.Server{
"controller-manager": {EnableHTTPS: true, TLSConfig: &tls.Config{InsecureSkipVerify: true}, Addr: "127.0.0.1", Port: ports.KubeControllerManagerPort, Path: "/healthz"},
"scheduler": {Addr: "127.0.0.1", Port: kubeschedulerconfig.DefaultInsecureSchedulerPort, Path: "/healthz"},
"scheduler": {EnableHTTPS: true, TLSConfig: &tls.Config{InsecureSkipVerify: true}, Addr: "127.0.0.1", Port: kubeschedulerconfig.DefaultKubeSchedulerPort, Path: "/healthz"},
}
for ix, machine := range s.storageFactory.Backends() {

View File

@ -30,11 +30,6 @@ const (
// scheduler's policy ConfigMap that contains scheduler's policy config.
SchedulerPolicyConfigMapKey = "policy.cfg"
// DefaultInsecureSchedulerPort is the default port for the scheduler status server.
// May be overridden by a flag at startup.
// Deprecated: use the secure KubeSchedulerPort instead.
DefaultInsecureSchedulerPort = 10251
// DefaultKubeSchedulerPort is the default port for the scheduler status server.
// May be overridden by a flag at startup.
DefaultKubeSchedulerPort = 10259
@ -63,11 +58,9 @@ type KubeSchedulerConfiguration struct {
// ClientConnection specifies the kubeconfig file and client connection
// settings for the proxy server to use when communicating with the apiserver.
ClientConnection componentbaseconfig.ClientConnectionConfiguration
// HealthzBindAddress is the IP address and port for the health check server to serve on,
// defaulting to 0.0.0.0:10251
// HealthzBindAddress is the IP address and port for the health check server to serve on.
HealthzBindAddress string
// MetricsBindAddress is the IP address and port for the metrics server to
// serve on, defaulting to 0.0.0.0:10251.
// MetricsBindAddress is the IP address and port for the metrics server to serve on.
MetricsBindAddress string
// DebuggingConfiguration holds configuration for Debugging related features

View File

@ -17,9 +17,6 @@ limitations under the License.
package v1beta1
import (
"net"
"strconv"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
@ -28,7 +25,6 @@ import (
"k8s.io/kube-scheduler/config/v1beta1"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/scheduler/apis/config"
netutils "k8s.io/utils/net"
"k8s.io/utils/pointer"
)
@ -126,56 +122,6 @@ func SetDefaults_KubeSchedulerConfiguration(obj *v1beta1.KubeSchedulerConfigurat
setDefaults_KubeSchedulerProfile(prof)
}
// For Healthz and Metrics bind addresses, we want to check:
// 1. If the value is nil, default to 0.0.0.0 and default scheduler port
// 2. If there is a value set, attempt to split it. If it's just a port (ie, ":1234"), default to 0.0.0.0 with that port
// 3. If splitting the value fails, check if the value is even a valid IP. If so, use that with the default port.
// Otherwise use the default bind address
defaultBindAddress := net.JoinHostPort("0.0.0.0", strconv.Itoa(config.DefaultInsecureSchedulerPort))
if obj.HealthzBindAddress == nil {
obj.HealthzBindAddress = &defaultBindAddress
} else {
if host, port, err := net.SplitHostPort(*obj.HealthzBindAddress); err == nil {
if len(host) == 0 {
host = "0.0.0.0"
}
hostPort := net.JoinHostPort(host, port)
obj.HealthzBindAddress = &hostPort
} else {
// Something went wrong splitting the host/port, could just be a missing port so check if the
// existing value is a valid IP address. If so, use that with the default scheduler port
if host := netutils.ParseIPSloppy(*obj.HealthzBindAddress); host != nil {
hostPort := net.JoinHostPort(*obj.HealthzBindAddress, strconv.Itoa(config.DefaultInsecureSchedulerPort))
obj.HealthzBindAddress = &hostPort
} else {
// TODO: in v1beta1 we should let this error instead of stomping with a default value
obj.HealthzBindAddress = &defaultBindAddress
}
}
}
if obj.MetricsBindAddress == nil {
obj.MetricsBindAddress = &defaultBindAddress
} else {
if host, port, err := net.SplitHostPort(*obj.MetricsBindAddress); err == nil {
if len(host) == 0 {
host = "0.0.0.0"
}
hostPort := net.JoinHostPort(host, port)
obj.MetricsBindAddress = &hostPort
} else {
// Something went wrong splitting the host/port, could just be a missing port so check if the
// existing value is a valid IP address. If so, use that with the default scheduler port
if host := netutils.ParseIPSloppy(*obj.MetricsBindAddress); host != nil {
hostPort := net.JoinHostPort(*obj.MetricsBindAddress, strconv.Itoa(config.DefaultInsecureSchedulerPort))
obj.MetricsBindAddress = &hostPort
} else {
// TODO: in v1beta1 we should let this error instead of stomping with a default value
obj.MetricsBindAddress = &defaultBindAddress
}
}
}
if obj.PercentageOfNodesToScore == nil {
percentageOfNodesToScore := int32(config.DefaultPercentageOfNodesToScore)
obj.PercentageOfNodesToScore = &percentageOfNodesToScore

View File

@ -134,9 +134,7 @@ func TestSchedulerDefaults(t *testing.T) {
name: "empty config",
config: &v1beta1.KubeSchedulerConfiguration{},
expected: &v1beta1.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"),
Parallelism: pointer.Int32Ptr(16),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
@ -173,9 +171,7 @@ func TestSchedulerDefaults(t *testing.T) {
Profiles: []v1beta1.KubeSchedulerProfile{{}},
},
expected: &v1beta1.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"),
Parallelism: pointer.Int32Ptr(16),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
@ -229,9 +225,7 @@ func TestSchedulerDefaults(t *testing.T) {
},
},
expected: &v1beta1.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"),
Parallelism: pointer.Int32Ptr(16),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
@ -430,96 +424,13 @@ func TestSchedulerDefaults(t *testing.T) {
},
},
},
{
name: "metrics and healthz address with no port",
config: &v1beta1.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
MetricsBindAddress: pointer.StringPtr("1.2.3.4"),
HealthzBindAddress: pointer.StringPtr("1.2.3.4"),
},
expected: &v1beta1.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("1.2.3.4:10251"),
MetricsBindAddress: pointer.StringPtr("1.2.3.4:10251"),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
},
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
LeaderElect: pointer.BoolPtr(true),
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "leases",
ResourceNamespace: "kube-system",
ResourceName: "kube-scheduler",
},
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
QPS: 50,
Burst: 100,
ContentType: "application/vnd.kubernetes.protobuf",
},
PercentageOfNodesToScore: pointer.Int32Ptr(0),
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
Profiles: []v1beta1.KubeSchedulerProfile{
{
SchedulerName: pointer.StringPtr("default-scheduler"),
Plugins: getDefaultPlugins(),
PluginConfig: pluginConfigs,
},
},
},
},
{
name: "metrics and healthz port with no address",
config: &v1beta1.KubeSchedulerConfiguration{
MetricsBindAddress: pointer.StringPtr(":12345"),
HealthzBindAddress: pointer.StringPtr(":12345"),
},
expected: &v1beta1.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:12345"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:12345"),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
},
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
LeaderElect: pointer.BoolPtr(true),
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "leases",
ResourceNamespace: "kube-system",
ResourceName: "kube-scheduler",
},
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
QPS: 50,
Burst: 100,
ContentType: "application/vnd.kubernetes.protobuf",
},
PercentageOfNodesToScore: pointer.Int32Ptr(0),
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
Profiles: []v1beta1.KubeSchedulerProfile{
{
SchedulerName: pointer.StringPtr("default-scheduler"),
Plugins: getDefaultPlugins(),
PluginConfig: pluginConfigs,
},
},
},
},
{
name: "set non default parallelism",
config: &v1beta1.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(8),
},
expected: &v1beta1.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(8),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"),
Parallelism: pointer.Int32Ptr(8),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,

View File

@ -17,9 +17,6 @@ limitations under the License.
package v1beta2
import (
"net"
"strconv"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets"
@ -28,7 +25,6 @@ import (
"k8s.io/kube-scheduler/config/v1beta2"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/scheduler/apis/config"
netutils "k8s.io/utils/net"
"k8s.io/utils/pointer"
)
@ -124,50 +120,6 @@ func SetDefaults_KubeSchedulerConfiguration(obj *v1beta2.KubeSchedulerConfigurat
setDefaults_KubeSchedulerProfile(prof)
}
// For Healthz and Metrics bind addresses, we want to check:
// 1. If the value is nil, default to 0.0.0.0 and default scheduler port
// 2. If there is a value set, attempt to split it. If it's just a port (ie, ":1234"), default to 0.0.0.0 with that port
// 3. If splitting the value fails, check if the value is even a valid IP. If so, use that with the default port.
// Otherwise leave the address as-is, it will be caught during validation.
defaultBindAddress := net.JoinHostPort("0.0.0.0", strconv.Itoa(config.DefaultInsecureSchedulerPort))
if obj.HealthzBindAddress == nil {
obj.HealthzBindAddress = &defaultBindAddress
} else {
if host, port, err := net.SplitHostPort(*obj.HealthzBindAddress); err == nil {
if len(host) == 0 {
host = "0.0.0.0"
}
hostPort := net.JoinHostPort(host, port)
obj.HealthzBindAddress = &hostPort
} else {
// Something went wrong splitting the host/port, could just be a missing port so check if the
// existing value is a valid IP address. If so, use that with the default scheduler port
if host := netutils.ParseIPSloppy(*obj.HealthzBindAddress); host != nil {
hostPort := net.JoinHostPort(*obj.HealthzBindAddress, strconv.Itoa(config.DefaultInsecureSchedulerPort))
obj.HealthzBindAddress = &hostPort
}
}
}
if obj.MetricsBindAddress == nil {
obj.MetricsBindAddress = &defaultBindAddress
} else {
if host, port, err := net.SplitHostPort(*obj.MetricsBindAddress); err == nil {
if len(host) == 0 {
host = "0.0.0.0"
}
hostPort := net.JoinHostPort(host, port)
obj.MetricsBindAddress = &hostPort
} else {
// Something went wrong splitting the host/port, could just be a missing port so check if the
// existing value is a valid IP address. If so, use that with the default scheduler port
if host := netutils.ParseIPSloppy(*obj.MetricsBindAddress); host != nil {
hostPort := net.JoinHostPort(*obj.MetricsBindAddress, strconv.Itoa(config.DefaultInsecureSchedulerPort))
obj.MetricsBindAddress = &hostPort
}
}
}
if obj.PercentageOfNodesToScore == nil {
percentageOfNodesToScore := int32(config.DefaultPercentageOfNodesToScore)
obj.PercentageOfNodesToScore = &percentageOfNodesToScore

View File

@ -125,9 +125,7 @@ func TestSchedulerDefaults(t *testing.T) {
name: "empty config",
config: &v1beta2.KubeSchedulerConfiguration{},
expected: &v1beta2.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"),
Parallelism: pointer.Int32Ptr(16),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
@ -164,9 +162,7 @@ func TestSchedulerDefaults(t *testing.T) {
Profiles: []v1beta2.KubeSchedulerProfile{{}},
},
expected: &v1beta2.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"),
Parallelism: pointer.Int32Ptr(16),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
@ -222,9 +218,7 @@ func TestSchedulerDefaults(t *testing.T) {
},
},
expected: &v1beta2.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"),
Parallelism: pointer.Int32Ptr(16),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
@ -411,136 +405,13 @@ func TestSchedulerDefaults(t *testing.T) {
},
},
},
{
name: "metrics and healthz address with no port",
config: &v1beta2.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
MetricsBindAddress: pointer.StringPtr("1.2.3.4"),
HealthzBindAddress: pointer.StringPtr("1.2.3.4"),
},
expected: &v1beta2.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("1.2.3.4:10251"),
MetricsBindAddress: pointer.StringPtr("1.2.3.4:10251"),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
},
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
LeaderElect: pointer.BoolPtr(true),
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "leases",
ResourceNamespace: "kube-system",
ResourceName: "kube-scheduler",
},
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
QPS: 50,
Burst: 100,
ContentType: "application/vnd.kubernetes.protobuf",
},
PercentageOfNodesToScore: pointer.Int32Ptr(0),
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
Profiles: []v1beta2.KubeSchedulerProfile{
{
Plugins: getDefaultPlugins(),
PluginConfig: pluginConfigs,
SchedulerName: pointer.StringPtr("default-scheduler"),
},
},
},
},
{
name: "metrics and healthz port with no address",
config: &v1beta2.KubeSchedulerConfiguration{
MetricsBindAddress: pointer.StringPtr(":12345"),
HealthzBindAddress: pointer.StringPtr(":12345"),
},
expected: &v1beta2.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:12345"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:12345"),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
},
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
LeaderElect: pointer.BoolPtr(true),
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "leases",
ResourceNamespace: "kube-system",
ResourceName: "kube-scheduler",
},
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
QPS: 50,
Burst: 100,
ContentType: "application/vnd.kubernetes.protobuf",
},
PercentageOfNodesToScore: pointer.Int32Ptr(0),
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
Profiles: []v1beta2.KubeSchedulerProfile{
{
Plugins: getDefaultPlugins(),
PluginConfig: pluginConfigs,
SchedulerName: pointer.StringPtr("default-scheduler"),
},
},
},
},
{
name: "metrics and healthz with invalid IP",
config: &v1beta2.KubeSchedulerConfiguration{
MetricsBindAddress: pointer.StringPtr("999.888.777"),
HealthzBindAddress: pointer.StringPtr("999.888.777"),
},
expected: &v1beta2.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(16),
HealthzBindAddress: pointer.StringPtr("999.888.777"),
MetricsBindAddress: pointer.StringPtr("999.888.777"),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,
},
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
LeaderElect: pointer.BoolPtr(true),
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
ResourceLock: "leases",
ResourceNamespace: "kube-system",
ResourceName: "kube-scheduler",
},
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
QPS: 50,
Burst: 100,
ContentType: "application/vnd.kubernetes.protobuf",
},
PercentageOfNodesToScore: pointer.Int32Ptr(0),
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
Profiles: []v1beta2.KubeSchedulerProfile{
{
Plugins: getDefaultPlugins(),
PluginConfig: pluginConfigs,
SchedulerName: pointer.StringPtr("default-scheduler"),
},
},
},
},
{
name: "set non default parallelism",
config: &v1beta2.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(8),
},
expected: &v1beta2.KubeSchedulerConfiguration{
Parallelism: pointer.Int32Ptr(8),
HealthzBindAddress: pointer.StringPtr("0.0.0.0:10251"),
MetricsBindAddress: pointer.StringPtr("0.0.0.0:10251"),
Parallelism: pointer.Int32Ptr(8),
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
EnableProfiling: &enable,
EnableContentionProfiling: &enable,

View File

@ -18,7 +18,10 @@ package validation
import (
"fmt"
"net"
"reflect"
"strconv"
"strings"
"github.com/google/go-cmp/cmp"
v1 "k8s.io/api/core/v1"
@ -59,11 +62,31 @@ func ValidateKubeSchedulerConfiguration(cc *config.KubeSchedulerConfiguration) u
}
errs = append(errs, validateCommonQueueSort(profilesPath, cc.Profiles)...)
}
for _, msg := range validation.IsValidSocketAddr(cc.HealthzBindAddress) {
errs = append(errs, field.Invalid(field.NewPath("healthzBindAddress"), cc.HealthzBindAddress, msg))
if len(cc.HealthzBindAddress) > 0 {
host, port, err := splitHostIntPort(cc.HealthzBindAddress)
if err != nil {
errs = append(errs, field.Invalid(field.NewPath("healthzBindAddress"), cc.HealthzBindAddress, err.Error()))
} else {
if errMsgs := validation.IsValidIP(host); errMsgs != nil {
errs = append(errs, field.Invalid(field.NewPath("healthzBindAddress"), cc.HealthzBindAddress, strings.Join(errMsgs, ",")))
}
if port != 0 {
errs = append(errs, field.Invalid(field.NewPath("healthzBindAddress"), cc.HealthzBindAddress, "must be empty or with an explicit 0 port"))
}
}
}
for _, msg := range validation.IsValidSocketAddr(cc.MetricsBindAddress) {
errs = append(errs, field.Invalid(field.NewPath("metricsBindAddress"), cc.MetricsBindAddress, msg))
if len(cc.MetricsBindAddress) > 0 {
host, port, err := splitHostIntPort(cc.MetricsBindAddress)
if err != nil {
errs = append(errs, field.Invalid(field.NewPath("metricsBindAddress"), cc.MetricsBindAddress, err.Error()))
} else {
if errMsgs := validation.IsValidIP(host); errMsgs != nil {
errs = append(errs, field.Invalid(field.NewPath("metricsBindAddress"), cc.MetricsBindAddress, strings.Join(errMsgs, ",")))
}
if port != 0 {
errs = append(errs, field.Invalid(field.NewPath("metricsBindAddress"), cc.MetricsBindAddress, "must be empty or with an explicit 0 port"))
}
}
}
if cc.PercentageOfNodesToScore < 0 || cc.PercentageOfNodesToScore > 100 {
errs = append(errs, field.Invalid(field.NewPath("percentageOfNodesToScore"),
@ -82,6 +105,18 @@ func ValidateKubeSchedulerConfiguration(cc *config.KubeSchedulerConfiguration) u
return utilerrors.Flatten(utilerrors.NewAggregate(errs))
}
func splitHostIntPort(s string) (string, int, error) {
host, port, err := net.SplitHostPort(s)
if err != nil {
return "", 0, err
}
portInt, err := strconv.Atoi(port)
if err != nil {
return "", 0, err
}
return host, portInt, err
}
type removedPlugins struct {
schemeGroupVersion string
plugins []string

View File

@ -36,9 +36,7 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) {
TypeMeta: metav1.TypeMeta{
APIVersion: v1beta2.SchemeGroupVersion.String(),
},
Parallelism: 8,
HealthzBindAddress: "0.0.0.0:10254",
MetricsBindAddress: "0.0.0.0:10254",
Parallelism: 8,
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
AcceptContentTypes: "application/json",
ContentType: "application/json",
@ -104,28 +102,16 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) {
resourceNamespaceNotSet := validConfig.DeepCopy()
resourceNamespaceNotSet.LeaderElection.ResourceNamespace = ""
metricsBindAddrHostInvalid := validConfig.DeepCopy()
metricsBindAddrHostInvalid.MetricsBindAddress = "0.0.0.0.0:9090"
metricsBindAddrPortInvalid := validConfig.DeepCopy()
metricsBindAddrPortInvalid.MetricsBindAddress = "0.0.0.0:909090"
metricsBindAddrHostOnlyInvalid := validConfig.DeepCopy()
metricsBindAddrHostOnlyInvalid.MetricsBindAddress = "999.999.999.999"
healthzBindAddrHostInvalid := validConfig.DeepCopy()
healthzBindAddrHostInvalid.HealthzBindAddress = "0.0.0.0.0:9090"
healthzBindAddrPortInvalid := validConfig.DeepCopy()
healthzBindAddrPortInvalid.HealthzBindAddress = "0.0.0.0:909090"
healthzBindAddrHostOnlyInvalid := validConfig.DeepCopy()
healthzBindAddrHostOnlyInvalid.HealthzBindAddress = "999.999.999.999"
enableContentProfilingSetWithoutEnableProfiling := validConfig.DeepCopy()
enableContentProfilingSetWithoutEnableProfiling.EnableProfiling = false
enableContentProfilingSetWithoutEnableProfiling.EnableContentionProfiling = true
metricsBindAddrInvalid := validConfig.DeepCopy()
metricsBindAddrInvalid.MetricsBindAddress = "0.0.0.0:9090"
healthzBindAddrInvalid := validConfig.DeepCopy()
healthzBindAddrInvalid.HealthzBindAddress = "0.0.0.0:9090"
percentageOfNodesToScore101 := validConfig.DeepCopy()
percentageOfNodesToScore101.PercentageOfNodesToScore = int32(101)
@ -281,29 +267,13 @@ func TestValidateKubeSchedulerConfiguration(t *testing.T) {
expectedToFail: true,
config: resourceNamespaceNotSet,
},
"bad-healthz-port-invalid": {
"non-empty-metrics-bind-addr": {
expectedToFail: true,
config: healthzBindAddrPortInvalid,
config: metricsBindAddrInvalid,
},
"bad-healthz-host-invalid": {
"non-empty-healthz-bind-addr": {
expectedToFail: true,
config: healthzBindAddrHostInvalid,
},
"bad-healthz-host-only-invalid": {
expectedToFail: true,
config: healthzBindAddrHostOnlyInvalid,
},
"bad-metrics-port-invalid": {
expectedToFail: true,
config: metricsBindAddrPortInvalid,
},
"bad-metrics-host-invalid": {
expectedToFail: true,
config: metricsBindAddrHostInvalid,
},
"bad-metrics-host-only-invalid": {
expectedToFail: true,
config: metricsBindAddrHostOnlyInvalid,
config: healthzBindAddrInvalid,
},
"bad-percentage-of-nodes-to-score": {
expectedToFail: true,

View File

@ -53,11 +53,12 @@ type KubeSchedulerConfiguration struct {
// ClientConnection specifies the kubeconfig file and client connection
// settings for the proxy server to use when communicating with the apiserver.
ClientConnection componentbaseconfigv1alpha1.ClientConnectionConfiguration `json:"clientConnection"`
// HealthzBindAddress is the IP address and port for the health check server to serve on,
// defaulting to 0.0.0.0:10251
// Note: Both HealthzBindAddress and MetricsBindAddress fields are deprecated.
// Only empty address or port 0 is allowed. Anything else will fail validation.
// HealthzBindAddress is the IP address and port for the health check server to serve on.
HealthzBindAddress *string `json:"healthzBindAddress,omitempty"`
// MetricsBindAddress is the IP address and port for the metrics server to
// serve on, defaulting to 0.0.0.0:10251.
// MetricsBindAddress is the IP address and port for the metrics server to serve on.
MetricsBindAddress *string `json:"metricsBindAddress,omitempty"`
// DebuggingConfiguration holds configuration for Debugging related features

View File

@ -53,11 +53,12 @@ type KubeSchedulerConfiguration struct {
// ClientConnection specifies the kubeconfig file and client connection
// settings for the proxy server to use when communicating with the apiserver.
ClientConnection componentbaseconfigv1alpha1.ClientConnectionConfiguration `json:"clientConnection"`
// HealthzBindAddress is the IP address and port for the health check server to serve on,
// defaulting to 0.0.0.0:10251
// Note: Both HealthzBindAddress and MetricsBindAddress fields are deprecated.
// Only empty address or port 0 is allowed. Anything else will fail validation.
// HealthzBindAddress is the IP address and port for the health check server to serve on.
HealthzBindAddress *string `json:"healthzBindAddress,omitempty"`
// MetricsBindAddress is the IP address and port for the metrics server to
// serve on, defaulting to 0.0.0.0:10251.
// MetricsBindAddress is the IP address and port for the metrics server to serve on.
MetricsBindAddress *string `json:"metricsBindAddress,omitempty"`
// DebuggingConfiguration holds configuration for Debugging related features