Merge pull request #42835 from deads2k/server-01-remove-insecure

Automatic merge from submit-queue (batch tested with PRs 42835, 42974)

remove legacy insecure port options from genericapiserver

The insecure port has been a source of problems and it will prevent proper aggregation into a cluster, so the genericapiserver has no need for it.  In addition, there's no reason for it to be in the main kube-apiserver flow either.  This pull removes it from genericapiserver and removes it from the shared kube-apiserver code.  It's still wired up in the command, but its no longer possible for someone to mess up and start using in mainline code.

@kubernetes/sig-api-machinery-misc @ncdc
This commit is contained in:
Kubernetes Submit Queue 2017-03-27 17:00:21 -07:00 committed by GitHub
commit 4159cb57b6
23 changed files with 397 additions and 262 deletions

View File

@ -32,6 +32,8 @@ go_library(
"//pkg/kubeapiserver:go_default_library", "//pkg/kubeapiserver:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library", "//pkg/kubeapiserver/admission:go_default_library",
"//pkg/kubeapiserver/authenticator:go_default_library", "//pkg/kubeapiserver/authenticator:go_default_library",
"//pkg/kubeapiserver/options:go_default_library",
"//pkg/kubeapiserver/server:go_default_library",
"//pkg/master:go_default_library", "//pkg/master:go_default_library",
"//pkg/master/thirdparty:go_default_library", "//pkg/master/thirdparty:go_default_library",
"//pkg/master/tunneler:go_default_library", "//pkg/master/tunneler:go_default_library",

View File

@ -44,7 +44,7 @@ type ServerRunOptions struct {
GenericServerRunOptions *genericoptions.ServerRunOptions GenericServerRunOptions *genericoptions.ServerRunOptions
Etcd *genericoptions.EtcdOptions Etcd *genericoptions.EtcdOptions
SecureServing *genericoptions.SecureServingOptions SecureServing *genericoptions.SecureServingOptions
InsecureServing *genericoptions.ServingOptions InsecureServing *kubeoptions.InsecureServingOptions
Audit *genericoptions.AuditLogOptions Audit *genericoptions.AuditLogOptions
Features *genericoptions.FeatureOptions Features *genericoptions.FeatureOptions
Authentication *kubeoptions.BuiltInAuthenticationOptions Authentication *kubeoptions.BuiltInAuthenticationOptions
@ -74,7 +74,7 @@ func NewServerRunOptions() *ServerRunOptions {
GenericServerRunOptions: genericoptions.NewServerRunOptions(), GenericServerRunOptions: genericoptions.NewServerRunOptions(),
Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, api.Scheme, nil)), Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, api.Scheme, nil)),
SecureServing: kubeoptions.NewSecureServingOptions(), SecureServing: kubeoptions.NewSecureServingOptions(),
InsecureServing: genericoptions.NewInsecureServingOptions(), InsecureServing: kubeoptions.NewInsecureServingOptions(),
Audit: genericoptions.NewAuditLogOptions(), Audit: genericoptions.NewAuditLogOptions(),
Features: genericoptions.NewFeatureOptions(), Features: genericoptions.NewFeatureOptions(),
Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(), Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),

View File

@ -66,6 +66,8 @@ import (
"k8s.io/kubernetes/pkg/kubeapiserver" "k8s.io/kubernetes/pkg/kubeapiserver"
kubeadmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" kubeadmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator" kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
kubeserver "k8s.io/kubernetes/pkg/kubeapiserver/server"
"k8s.io/kubernetes/pkg/master" "k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/pkg/master/tunneler" "k8s.io/kubernetes/pkg/master/tunneler"
"k8s.io/kubernetes/pkg/registry/cachesize" "k8s.io/kubernetes/pkg/registry/cachesize"
@ -95,7 +97,7 @@ cluster's shared state through which all other components interact.`,
// Run runs the specified APIServer. This should never exit. // Run runs the specified APIServer. This should never exit.
func Run(runOptions *options.ServerRunOptions, stopCh <-chan struct{}) error { func Run(runOptions *options.ServerRunOptions, stopCh <-chan struct{}) error {
kubeAPIServerConfig, sharedInformers, err := CreateKubeAPIServerConfig(runOptions) kubeAPIServerConfig, sharedInformers, insecureServingOptions, err := CreateKubeAPIServerConfig(runOptions)
if err != nil { if err != nil {
return err return err
} }
@ -104,6 +106,14 @@ func Run(runOptions *options.ServerRunOptions, stopCh <-chan struct{}) error {
return err return err
} }
// run the insecure server now, don't block. It doesn't have any aggregator goodies since authentication wouldn't work
if insecureServingOptions != nil {
insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(kubeAPIServer.GenericAPIServer.HandlerContainer.ServeMux, kubeAPIServerConfig.GenericConfig)
if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, stopCh); err != nil {
return err
}
}
// if we're starting up a hacked up version of this API server for a weird test case, // if we're starting up a hacked up version of this API server for a weird test case,
// just start the API server as is because clients don't get built correctly when you do this // just start the API server as is because clients don't get built correctly when you do this
if len(os.Getenv("KUBE_API_VERSIONS")) > 0 { if len(os.Getenv("KUBE_API_VERSIONS")) > 0 {
@ -140,24 +150,24 @@ func CreateKubeAPIServer(kubeAPIServerConfig *master.Config, sharedInformers inf
} }
// CreateKubeAPIServerConfig creates all the resources for running the API server, but runs none of them // CreateKubeAPIServerConfig creates all the resources for running the API server, but runs none of them
func CreateKubeAPIServerConfig(s *options.ServerRunOptions) (*master.Config, informers.SharedInformerFactory, error) { func CreateKubeAPIServerConfig(s *options.ServerRunOptions) (*master.Config, informers.SharedInformerFactory, *kubeserver.InsecureServingInfo, error) {
// set defaults in the options before trying to create the generic config // set defaults in the options before trying to create the generic config
if err := defaultOptions(s); err != nil { if err := defaultOptions(s); err != nil {
return nil, nil, err return nil, nil, nil, err
} }
// validate options // validate options
if errs := s.Validate(); len(errs) != 0 { if errs := s.Validate(); len(errs) != 0 {
return nil, nil, utilerrors.NewAggregate(errs) return nil, nil, nil, utilerrors.NewAggregate(errs)
} }
genericConfig, sharedInformers, err := BuildGenericConfig(s) genericConfig, sharedInformers, insecureServingOptions, err := BuildGenericConfig(s)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, err
} }
if err := utilwait.PollImmediate(etcdRetryInterval, etcdRetryLimit*etcdRetryInterval, preflight.EtcdConnection{ServerList: s.Etcd.StorageConfig.ServerList}.CheckEtcdServers); err != nil { if err := utilwait.PollImmediate(etcdRetryInterval, etcdRetryLimit*etcdRetryInterval, preflight.EtcdConnection{ServerList: s.Etcd.StorageConfig.ServerList}.CheckEtcdServers); err != nil {
return nil, nil, fmt.Errorf("error waiting for etcd connection: %v", err) return nil, nil, nil, fmt.Errorf("error waiting for etcd connection: %v", err)
} }
capabilities.Initialize(capabilities.Capabilities{ capabilities.Initialize(capabilities.Capabilities{
@ -179,7 +189,7 @@ func CreateKubeAPIServerConfig(s *options.ServerRunOptions) (*master.Config, inf
var installSSHKey tunneler.InstallSSHKey var installSSHKey tunneler.InstallSSHKey
cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider.CloudProvider, s.CloudProvider.CloudConfigFile) cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider.CloudProvider, s.CloudProvider.CloudConfigFile)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("cloud provider could not be initialized: %v", err) return nil, nil, nil, fmt.Errorf("cloud provider could not be initialized: %v", err)
} }
if cloud != nil { if cloud != nil {
if instances, supported := cloud.Instances(); supported { if instances, supported := cloud.Instances(); supported {
@ -187,10 +197,10 @@ func CreateKubeAPIServerConfig(s *options.ServerRunOptions) (*master.Config, inf
} }
} }
if s.KubeletConfig.Port == 0 { if s.KubeletConfig.Port == 0 {
return nil, nil, fmt.Errorf("must enable kubelet port if proxy ssh-tunneling is specified") return nil, nil, nil, fmt.Errorf("must enable kubelet port if proxy ssh-tunneling is specified")
} }
if s.KubeletConfig.ReadOnlyPort == 0 { if s.KubeletConfig.ReadOnlyPort == 0 {
return nil, nil, fmt.Errorf("must enable kubelet readonly port if proxy ssh-tunneling is specified") return nil, nil, nil, fmt.Errorf("must enable kubelet readonly port if proxy ssh-tunneling is specified")
} }
// Set up the nodeTunneler // Set up the nodeTunneler
// TODO(cjcullen): If we want this to handle per-kubelet ports or other // TODO(cjcullen): If we want this to handle per-kubelet ports or other
@ -216,21 +226,21 @@ func CreateKubeAPIServerConfig(s *options.ServerRunOptions) (*master.Config, inf
serviceIPRange, apiServerServiceIP, err := master.DefaultServiceIPRange(s.ServiceClusterIPRange) serviceIPRange, apiServerServiceIP, err := master.DefaultServiceIPRange(s.ServiceClusterIPRange)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, err
} }
storageFactory, err := BuildStorageFactory(s) storageFactory, err := BuildStorageFactory(s)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, err
} }
clientCA, err := readCAorNil(s.Authentication.ClientCert.ClientCA) clientCA, err := readCAorNil(s.Authentication.ClientCert.ClientCA)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, err
} }
requestHeaderProxyCA, err := readCAorNil(s.Authentication.RequestHeader.ClientCAFile) requestHeaderProxyCA, err := readCAorNil(s.Authentication.RequestHeader.ClientCAFile)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, err
} }
config := &master.Config{ config := &master.Config{
@ -266,29 +276,30 @@ func CreateKubeAPIServerConfig(s *options.ServerRunOptions) (*master.Config, inf
MasterCount: s.MasterCount, MasterCount: s.MasterCount,
} }
return config, sharedInformers, nil return config, sharedInformers, insecureServingOptions, nil
} }
// BuildGenericConfig takes the master server options and produces the genericapiserver.Config associated with it // BuildGenericConfig takes the master server options and produces the genericapiserver.Config associated with it
func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config, informers.SharedInformerFactory, error) { func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config, informers.SharedInformerFactory, *kubeserver.InsecureServingInfo, error) {
genericConfig := genericapiserver.NewConfig(api.Codecs) genericConfig := genericapiserver.NewConfig(api.Codecs)
if err := s.GenericServerRunOptions.ApplyTo(genericConfig); err != nil { if err := s.GenericServerRunOptions.ApplyTo(genericConfig); err != nil {
return nil, nil, err return nil, nil, nil, err
} }
if err := s.InsecureServing.ApplyTo(genericConfig); err != nil { insecureServingOptions, err := s.InsecureServing.ApplyTo(genericConfig)
return nil, nil, err if err != nil {
return nil, nil, nil, err
} }
if err := s.SecureServing.ApplyTo(genericConfig); err != nil { if err := s.SecureServing.ApplyTo(genericConfig); err != nil {
return nil, nil, err return nil, nil, nil, err
} }
if err := s.Authentication.ApplyTo(genericConfig); err != nil { if err := s.Authentication.ApplyTo(genericConfig); err != nil {
return nil, nil, err return nil, nil, nil, err
} }
if err := s.Audit.ApplyTo(genericConfig); err != nil { if err := s.Audit.ApplyTo(genericConfig); err != nil {
return nil, nil, err return nil, nil, nil, err
} }
if err := s.Features.ApplyTo(genericConfig); err != nil { if err := s.Features.ApplyTo(genericConfig); err != nil {
return nil, nil, err return nil, nil, nil, err
} }
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(generatedopenapi.GetOpenAPIDefinitions, api.Scheme) genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(generatedopenapi.GetOpenAPIDefinitions, api.Scheme)
@ -306,10 +317,10 @@ func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config,
storageFactory, err := BuildStorageFactory(s) storageFactory, err := BuildStorageFactory(s)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, err
} }
if err := s.Etcd.ApplyWithStorageFactoryTo(storageFactory, genericConfig); err != nil { if err := s.Etcd.ApplyWithStorageFactoryTo(storageFactory, genericConfig); err != nil {
return nil, nil, err return nil, nil, nil, err
} }
// Use protobufs for self-communication. // Use protobufs for self-communication.
@ -322,7 +333,7 @@ func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config,
if err != nil { if err != nil {
kubeAPIVersions := os.Getenv("KUBE_API_VERSIONS") kubeAPIVersions := os.Getenv("KUBE_API_VERSIONS")
if len(kubeAPIVersions) == 0 { if len(kubeAPIVersions) == 0 {
return nil, nil, fmt.Errorf("failed to create clientset: %v", err) return nil, nil, nil, fmt.Errorf("failed to create clientset: %v", err)
} }
// KUBE_API_VERSIONS is used in test-update-storage-objects.sh, disabling a number of API // KUBE_API_VERSIONS is used in test-update-storage-objects.sh, disabling a number of API
@ -335,20 +346,20 @@ func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config,
genericConfig.Authenticator, genericConfig.OpenAPIConfig.SecurityDefinitions, err = BuildAuthenticator(s, storageFactory, client, sharedInformers) genericConfig.Authenticator, genericConfig.OpenAPIConfig.SecurityDefinitions, err = BuildAuthenticator(s, storageFactory, client, sharedInformers)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("invalid authentication config: %v", err) return nil, nil, nil, fmt.Errorf("invalid authentication config: %v", err)
} }
genericConfig.Authorizer, err = BuildAuthorizer(s, sharedInformers) genericConfig.Authorizer, err = BuildAuthorizer(s, sharedInformers)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("invalid authorization config: %v", err) return nil, nil, nil, fmt.Errorf("invalid authorization config: %v", err)
} }
genericConfig.AdmissionControl, err = BuildAdmission(s, client, sharedInformers, genericConfig.Authorizer) genericConfig.AdmissionControl, err = BuildAdmission(s, client, sharedInformers, genericConfig.Authorizer)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to initialize admission: %v", err) return nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err)
} }
return genericConfig, sharedInformers, nil return genericConfig, sharedInformers, insecureServingOptions, nil
} }
// BuildAdmission constructs the admission chain // BuildAdmission constructs the admission chain
@ -442,7 +453,11 @@ func BuildStorageFactory(s *options.ServerRunOptions) (*serverstorage.DefaultSto
} }
func defaultOptions(s *options.ServerRunOptions) error { func defaultOptions(s *options.ServerRunOptions) error {
if err := s.GenericServerRunOptions.DefaultAdvertiseAddress(s.SecureServing, s.InsecureServing); err != nil { // set defaults
if err := s.GenericServerRunOptions.DefaultAdvertiseAddress(s.SecureServing); err != nil {
return err
}
if err := kubeoptions.DefaultAdvertiseAddress(s.GenericServerRunOptions, s.InsecureServing); err != nil {
return err return err
} }
_, apiServerServiceIP, err := master.DefaultServiceIPRange(s.ServiceClusterIPRange) _, apiServerServiceIP, err := master.DefaultServiceIPRange(s.ServiceClusterIPRange)

View File

@ -41,6 +41,8 @@ go_library(
"//pkg/generated/openapi:go_default_library", "//pkg/generated/openapi:go_default_library",
"//pkg/kubeapiserver:go_default_library", "//pkg/kubeapiserver:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library", "//pkg/kubeapiserver/admission:go_default_library",
"//pkg/kubeapiserver/options:go_default_library",
"//pkg/kubeapiserver/server:go_default_library",
"//pkg/registry/autoscaling/horizontalpodautoscaler/storage:go_default_library", "//pkg/registry/autoscaling/horizontalpodautoscaler/storage:go_default_library",
"//pkg/registry/batch/job/storage:go_default_library", "//pkg/registry/batch/job/storage:go_default_library",
"//pkg/registry/cachesize:go_default_library", "//pkg/registry/cachesize:go_default_library",

View File

@ -36,7 +36,7 @@ type ServerRunOptions struct {
GenericServerRunOptions *genericoptions.ServerRunOptions GenericServerRunOptions *genericoptions.ServerRunOptions
Etcd *genericoptions.EtcdOptions Etcd *genericoptions.EtcdOptions
SecureServing *genericoptions.SecureServingOptions SecureServing *genericoptions.SecureServingOptions
InsecureServing *genericoptions.ServingOptions InsecureServing *kubeoptions.InsecureServingOptions
Audit *genericoptions.AuditLogOptions Audit *genericoptions.AuditLogOptions
Features *genericoptions.FeatureOptions Features *genericoptions.FeatureOptions
Authentication *kubeoptions.BuiltInAuthenticationOptions Authentication *kubeoptions.BuiltInAuthenticationOptions
@ -54,7 +54,7 @@ func NewServerRunOptions() *ServerRunOptions {
GenericServerRunOptions: genericoptions.NewServerRunOptions(), GenericServerRunOptions: genericoptions.NewServerRunOptions(),
Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, api.Scheme, nil)), Etcd: genericoptions.NewEtcdOptions(storagebackend.NewDefaultConfig(kubeoptions.DefaultEtcdPathPrefix, api.Scheme, nil)),
SecureServing: kubeoptions.NewSecureServingOptions(), SecureServing: kubeoptions.NewSecureServingOptions(),
InsecureServing: genericoptions.NewInsecureServingOptions(), InsecureServing: kubeoptions.NewInsecureServingOptions(),
Audit: genericoptions.NewAuditLogOptions(), Audit: genericoptions.NewAuditLogOptions(),
Features: genericoptions.NewFeatureOptions(), Features: genericoptions.NewFeatureOptions(),
Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(), Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),

View File

@ -45,6 +45,8 @@ import (
"k8s.io/kubernetes/pkg/generated/openapi" "k8s.io/kubernetes/pkg/generated/openapi"
"k8s.io/kubernetes/pkg/kubeapiserver" "k8s.io/kubernetes/pkg/kubeapiserver"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
kubeserver "k8s.io/kubernetes/pkg/kubeapiserver/server"
"k8s.io/kubernetes/pkg/registry/cachesize" "k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/routes" "k8s.io/kubernetes/pkg/routes"
"k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/pkg/version"
@ -81,7 +83,10 @@ func Run(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
// stop with the given channel. // stop with the given channel.
func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error { func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
// set defaults // set defaults
if err := s.GenericServerRunOptions.DefaultAdvertiseAddress(s.SecureServing, s.InsecureServing); err != nil { if err := s.GenericServerRunOptions.DefaultAdvertiseAddress(s.SecureServing); err != nil {
return err
}
if err := kubeoptions.DefaultAdvertiseAddress(s.GenericServerRunOptions, s.InsecureServing); err != nil {
return err return err
} }
if err := s.SecureServing.MaybeDefaultWithSelfSignedCerts(s.GenericServerRunOptions.AdvertiseAddress.String(), nil, nil); err != nil { if err := s.SecureServing.MaybeDefaultWithSelfSignedCerts(s.GenericServerRunOptions.AdvertiseAddress.String(), nil, nil); err != nil {
@ -102,7 +107,8 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
if err := s.GenericServerRunOptions.ApplyTo(genericConfig); err != nil { if err := s.GenericServerRunOptions.ApplyTo(genericConfig); err != nil {
return err return err
} }
if err := s.InsecureServing.ApplyTo(genericConfig); err != nil { insecureServingOptions, err := s.InsecureServing.ApplyTo(genericConfig)
if err != nil {
return err return err
} }
if err := s.SecureServing.ApplyTo(genericConfig); err != nil { if err := s.SecureServing.ApplyTo(genericConfig); err != nil {
@ -232,6 +238,14 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
// installBatchAPIs(m, genericConfig.RESTOptionsGetter) // installBatchAPIs(m, genericConfig.RESTOptionsGetter)
// installAutoscalingAPIs(m, genericConfig.RESTOptionsGetter) // installAutoscalingAPIs(m, genericConfig.RESTOptionsGetter)
// run the insecure server now
if insecureServingOptions != nil {
insecureHandlerChain := kubeserver.BuildInsecureHandlerChain(m.HandlerContainer.ServeMux, genericConfig)
if err := kubeserver.NonBlockingRun(insecureServingOptions, insecureHandlerChain, stopCh); err != nil {
return err
}
}
err = m.PrepareRun().NonBlockingRun(stopCh) err = m.PrepareRun().NonBlockingRun(stopCh)
if err == nil { if err == nil {
sharedInformers.Start(stopCh) sharedInformers.Start(stopCh)

View File

@ -40,6 +40,7 @@ filegroup(
"//pkg/kubeapiserver/authenticator:all-srcs", "//pkg/kubeapiserver/authenticator:all-srcs",
"//pkg/kubeapiserver/authorizer:all-srcs", "//pkg/kubeapiserver/authorizer:all-srcs",
"//pkg/kubeapiserver/options:all-srcs", "//pkg/kubeapiserver/options:all-srcs",
"//pkg/kubeapiserver/server:all-srcs",
], ],
tags = ["automanaged"], tags = ["automanaged"],
) )

View File

@ -27,9 +27,12 @@ go_library(
"//pkg/kubeapiserver/authenticator:go_default_library", "//pkg/kubeapiserver/authenticator:go_default_library",
"//pkg/kubeapiserver/authorizer:go_default_library", "//pkg/kubeapiserver/authorizer:go_default_library",
"//pkg/kubeapiserver/authorizer/modes:go_default_library", "//pkg/kubeapiserver/authorizer/modes:go_default_library",
"//pkg/kubeapiserver/server:go_default_library",
"//vendor:github.com/golang/glog", "//vendor:github.com/golang/glog",
"//vendor:github.com/pborman/uuid",
"//vendor:github.com/spf13/pflag", "//vendor:github.com/spf13/pflag",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/util/net",
"//vendor:k8s.io/apiserver/pkg/server", "//vendor:k8s.io/apiserver/pkg/server",
"//vendor:k8s.io/apiserver/pkg/server/options", "//vendor:k8s.io/apiserver/pkg/server/options",
"//vendor:k8s.io/apiserver/pkg/util/flag", "//vendor:k8s.io/apiserver/pkg/util/flag",

View File

@ -18,22 +18,118 @@ limitations under the License.
package options package options
import ( import (
"fmt"
"net" "net"
"strconv"
"github.com/pborman/uuid"
"github.com/spf13/pflag"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apiserver/pkg/server"
genericoptions "k8s.io/apiserver/pkg/server/options" genericoptions "k8s.io/apiserver/pkg/server/options"
kubeserver "k8s.io/kubernetes/pkg/kubeapiserver/server"
) )
// NewSecureServingOptions gives default values for the kube-apiserver and federation-apiserver which are not the options wanted by // NewSecureServingOptions gives default values for the kube-apiserver and federation-apiserver which are not the options wanted by
// "normal" API servers running on the platform // "normal" API servers running on the platform
func NewSecureServingOptions() *genericoptions.SecureServingOptions { func NewSecureServingOptions() *genericoptions.SecureServingOptions {
return &genericoptions.SecureServingOptions{ return &genericoptions.SecureServingOptions{
ServingOptions: genericoptions.ServingOptions{ BindAddress: net.ParseIP("0.0.0.0"),
BindAddress: net.ParseIP("0.0.0.0"), BindPort: 6443,
BindPort: 6443,
},
ServerCert: genericoptions.GeneratableKeyCert{ ServerCert: genericoptions.GeneratableKeyCert{
PairName: "apiserver", PairName: "apiserver",
CertDirectory: "/var/run/kubernetes", CertDirectory: "/var/run/kubernetes",
}, },
} }
} }
// DefaultAdvertiseAddress sets the field AdvertiseAddress if
// unset. The field will be set based on the SecureServingOptions. If
// the SecureServingOptions is not present, DefaultExternalAddress
// will fall back to the insecure ServingOptions.
func DefaultAdvertiseAddress(s *genericoptions.ServerRunOptions, insecure *InsecureServingOptions) error {
if insecure == nil {
return nil
}
if s.AdvertiseAddress == nil || s.AdvertiseAddress.IsUnspecified() {
hostIP, err := insecure.DefaultExternalAddress()
if err != nil {
return fmt.Errorf("Unable to find suitable network address.error='%v'. "+
"Try to set the AdvertiseAddress directly or provide a valid BindAddress to fix this.", err)
}
s.AdvertiseAddress = hostIP
}
return nil
}
// InsecureServingOptions are for creating an unauthenticated, unauthorized, insecure port.
// No one should be using these anymore.
type InsecureServingOptions struct {
BindAddress net.IP
BindPort int
}
// NewInsecureServingOptions is for creating an unauthenticated, unauthorized, insecure port.
// No one should be using these anymore.
func NewInsecureServingOptions() *InsecureServingOptions {
return &InsecureServingOptions{
BindAddress: net.ParseIP("127.0.0.1"),
BindPort: 8080,
}
}
func (s InsecureServingOptions) Validate(portArg string) []error {
errors := []error{}
if s.BindPort < 0 || s.BindPort > 65535 {
errors = append(errors, fmt.Errorf("--insecure-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port.", s.BindPort))
}
return errors
}
func (s *InsecureServingOptions) DefaultExternalAddress() (net.IP, error) {
return utilnet.ChooseBindAddress(s.BindAddress)
}
func (s *InsecureServingOptions) AddFlags(fs *pflag.FlagSet) {
fs.IPVar(&s.BindAddress, "insecure-bind-address", s.BindAddress, ""+
"The IP address on which to serve the --insecure-port (set to 0.0.0.0 for all interfaces). "+
"Defaults to localhost.")
fs.IntVar(&s.BindPort, "insecure-port", s.BindPort, ""+
"The port on which to serve unsecured, unauthenticated access. Default 8080. It is assumed "+
"that firewall rules are set up such that this port is not reachable from outside of "+
"the cluster and that port 443 on the cluster's public address is proxied to this "+
"port. This is performed by nginx in the default setup.")
}
func (s *InsecureServingOptions) AddDeprecatedFlags(fs *pflag.FlagSet) {
fs.IPVar(&s.BindAddress, "address", s.BindAddress,
"DEPRECATED: see --insecure-bind-address instead.")
fs.MarkDeprecated("address", "see --insecure-bind-address instead.")
fs.IntVar(&s.BindPort, "port", s.BindPort, "DEPRECATED: see --insecure-port instead.")
fs.MarkDeprecated("port", "see --insecure-port instead.")
}
func (s *InsecureServingOptions) ApplyTo(c *server.Config) (*kubeserver.InsecureServingInfo, error) {
if s.BindPort <= 0 {
return nil, nil
}
ret := &kubeserver.InsecureServingInfo{
BindAddress: net.JoinHostPort(s.BindAddress.String(), strconv.Itoa(s.BindPort)),
}
var err error
privilegedLoopbackToken := uuid.NewRandom().String()
if c.LoopbackClientConfig, err = ret.NewLoopbackClientConfig(privilegedLoopbackToken); err != nil {
return nil, err
}
return ret, nil
}

View File

@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["insecure_handler.go"],
tags = ["automanaged"],
deps = [
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apiserver/pkg/endpoints/filters",
"//vendor:k8s.io/apiserver/pkg/endpoints/request",
"//vendor:k8s.io/apiserver/pkg/server",
"//vendor:k8s.io/apiserver/pkg/server/filters",
"//vendor:k8s.io/client-go/rest",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,113 @@
/*
Copyright 2016 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 server
import (
"net"
"net/http"
"github.com/golang/glog"
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
apirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/server"
genericfilters "k8s.io/apiserver/pkg/server/filters"
"k8s.io/client-go/rest"
)
// InsecureServingInfo is required to serve http. HTTP does NOT include authentication or authorization.
// You shouldn't be using this. It makes sig-auth sad.
// InsecureServingInfo *ServingInfo
func BuildInsecureHandlerChain(apiHandler http.Handler, c *server.Config) http.Handler {
handler := genericapifilters.WithAudit(apiHandler, c.RequestContextMapper, c.AuditWriter)
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper)
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc)
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.RequestContextMapper, c.LongRunningFunc)
handler = genericapifilters.WithRequestInfo(handler, server.NewRequestInfoResolver(c), c.RequestContextMapper)
handler = apirequest.WithRequestContext(handler, c.RequestContextMapper)
return handler
}
type InsecureServingInfo struct {
// BindAddress is the ip:port to serve on
BindAddress string
// BindNetwork is the type of network to bind to - defaults to "tcp", accepts "tcp",
// "tcp4", and "tcp6".
BindNetwork string
}
func (s *InsecureServingInfo) NewLoopbackClientConfig(token string) (*rest.Config, error) {
if s == nil {
return nil, nil
}
host, port, err := server.LoopbackHostPort(s.BindAddress)
if err != nil {
return nil, err
}
return &rest.Config{
Host: "http://" + net.JoinHostPort(host, port),
// Increase QPS limits. The client is currently passed to all admission plugins,
// and those can be throttled in case of higher load on apiserver - see #22340 and #22422
// for more details. Once #22422 is fixed, we may want to remove it.
QPS: 50,
Burst: 100,
}, nil
}
// NonBlockingRun spawns the insecure http server. An error is
// returned if the ports cannot be listened on.
func NonBlockingRun(insecureServingInfo *InsecureServingInfo, insecureHandler http.Handler, stopCh <-chan struct{}) error {
// Use an internal stop channel to allow cleanup of the listeners on error.
internalStopCh := make(chan struct{})
if insecureServingInfo != nil && insecureHandler != nil {
if err := serveInsecurely(insecureServingInfo, insecureHandler, internalStopCh); err != nil {
close(internalStopCh)
return err
}
}
// Now that the listener has bound successfully, it is the
// responsibility of the caller to close the provided channel to
// ensure cleanup.
go func() {
<-stopCh
close(internalStopCh)
}()
return nil
}
// serveInsecurely run the insecure http server. It fails only if the initial listen
// call fails. The actual server loop (stoppable by closing stopCh) runs in a go
// routine, i.e. serveInsecurely does not block.
func serveInsecurely(insecureServingInfo *InsecureServingInfo, insecureHandler http.Handler, stopCh <-chan struct{}) error {
insecureServer := &http.Server{
Addr: insecureServingInfo.BindAddress,
Handler: insecureHandler,
MaxHeaderBytes: 1 << 20,
}
glog.Infof("Serving insecurely on %s", insecureServingInfo.BindAddress)
var err error
_, err = server.RunServer(insecureServer, insecureServingInfo.BindNetwork, stopCh)
return err
}

View File

@ -148,7 +148,7 @@ func TestVersion(t *testing.T) {
req, _ := http.NewRequest("GET", "/version", nil) req, _ := http.NewRequest("GET", "/version", nil)
resp := httptest.NewRecorder() resp := httptest.NewRecorder()
s.GenericAPIServer.InsecureHandler.ServeHTTP(resp, req) s.GenericAPIServer.Handler.ServeHTTP(resp, req)
if resp.Code != 200 { if resp.Code != 200 {
t.Fatalf("expected http 200, got: %d", resp.Code) t.Fatalf("expected http 200, got: %d", resp.Code)
} }

View File

@ -116,8 +116,8 @@ type Config struct {
// Fields you probably don't care about changing // Fields you probably don't care about changing
//=========================================================================== //===========================================================================
// BuildHandlerChainsFunc allows you to build custom handler chains by decorating the apiHandler. // BuildHandlerChainFunc allows you to build custom handler chains by decorating the apiHandler.
BuildHandlerChainsFunc func(apiHandler http.Handler, c *Config) (secure, insecure http.Handler) BuildHandlerChainFunc func(apiHandler http.Handler, c *Config) (secure http.Handler)
// DiscoveryAddresses is used to build the IPs pass to discovery. If nil, the ExternalAddress is // DiscoveryAddresses is used to build the IPs pass to discovery. If nil, the ExternalAddress is
// always reported // always reported
DiscoveryAddresses DiscoveryAddresses DiscoveryAddresses DiscoveryAddresses
@ -152,10 +152,6 @@ type Config struct {
// Predicate which is true for paths of long-running http requests // Predicate which is true for paths of long-running http requests
LongRunningFunc genericfilters.LongRunningRequestCheck LongRunningFunc genericfilters.LongRunningRequestCheck
// InsecureServingInfo is required to serve http. HTTP does NOT include authentication or authorization.
// You shouldn't be using this. It makes sig-auth sad.
InsecureServingInfo *ServingInfo
//=========================================================================== //===========================================================================
// values below here are targets for removal // values below here are targets for removal
//=========================================================================== //===========================================================================
@ -169,16 +165,12 @@ type Config struct {
PublicAddress net.IP PublicAddress net.IP
} }
type ServingInfo struct { type SecureServingInfo struct {
// BindAddress is the ip:port to serve on // BindAddress is the ip:port to serve on
BindAddress string BindAddress string
// BindNetwork is the type of network to bind to - defaults to "tcp", accepts "tcp", // BindNetwork is the type of network to bind to - defaults to "tcp", accepts "tcp",
// "tcp4", and "tcp6". // "tcp4", and "tcp6".
BindNetwork string BindNetwork string
}
type SecureServingInfo struct {
ServingInfo
// Cert is the main server cert which is used if SNI does not match. Cert must be non-nil and is // Cert is the main server cert which is used if SNI does not match. Cert must be non-nil and is
// allowed to be in SNICerts. // allowed to be in SNICerts.
@ -201,7 +193,7 @@ func NewConfig(codecs serializer.CodecFactory) *Config {
Serializer: codecs, Serializer: codecs,
ReadWritePort: 443, ReadWritePort: 443,
RequestContextMapper: apirequest.NewRequestContextMapper(), RequestContextMapper: apirequest.NewRequestContextMapper(),
BuildHandlerChainsFunc: DefaultBuildHandlerChain, BuildHandlerChainFunc: DefaultBuildHandlerChain,
LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix), LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix),
HealthzChecks: []healthz.HealthzChecker{healthz.PingHealthz}, HealthzChecks: []healthz.HealthzChecker{healthz.PingHealthz},
EnableIndex: true, EnableIndex: true,
@ -402,9 +394,8 @@ func (c completedConfig) constructServer() (*GenericAPIServer, error) {
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second, minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
SecureServingInfo: c.SecureServingInfo, SecureServingInfo: c.SecureServingInfo,
InsecureServingInfo: c.InsecureServingInfo, ExternalAddress: c.ExternalAddress,
ExternalAddress: c.ExternalAddress,
apiGroupsForDiscovery: map[string]metav1.APIGroup{}, apiGroupsForDiscovery: map[string]metav1.APIGroup{},
@ -477,33 +468,23 @@ func (c completedConfig) buildHandlers(s *GenericAPIServer, delegate http.Handle
installAPI(s, c.Config, delegate) installAPI(s, c.Config, delegate)
s.Handler, s.InsecureHandler = c.BuildHandlerChainsFunc(s.HandlerContainer.ServeMux, c.Config) s.Handler = c.BuildHandlerChainFunc(s.HandlerContainer.ServeMux, c.Config)
return s, nil return s, nil
} }
func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) (secure, insecure http.Handler) { func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
generic := func(handler http.Handler) http.Handler { handler := genericapifilters.WithAuthorization(apiHandler, c.RequestContextMapper, c.Authorizer)
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true") handler = genericapifilters.WithImpersonation(handler, c.RequestContextMapper, c.Authorizer)
handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper) handler = genericapifilters.WithAudit(handler, c.RequestContextMapper, c.AuditWriter)
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc) handler = genericapifilters.WithAuthentication(handler, c.RequestContextMapper, c.Authenticator, genericapifilters.Unauthorized(c.SupportsBasicAuth))
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.RequestContextMapper, c.LongRunningFunc) handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
handler = genericapifilters.WithRequestInfo(handler, NewRequestInfoResolver(c), c.RequestContextMapper) handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper)
handler = apirequest.WithRequestContext(handler, c.RequestContextMapper) handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc)
return handler handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.RequestContextMapper, c.LongRunningFunc)
} handler = genericapifilters.WithRequestInfo(handler, NewRequestInfoResolver(c), c.RequestContextMapper)
audit := func(handler http.Handler) http.Handler { handler = apirequest.WithRequestContext(handler, c.RequestContextMapper)
return genericapifilters.WithAudit(handler, c.RequestContextMapper, c.AuditWriter) return handler
}
protect := func(handler http.Handler) http.Handler {
handler = genericapifilters.WithAuthorization(handler, c.RequestContextMapper, c.Authorizer)
handler = genericapifilters.WithImpersonation(handler, c.RequestContextMapper, c.Authorizer)
handler = audit(handler) // before impersonation to read original user
handler = genericapifilters.WithAuthentication(handler, c.RequestContextMapper, c.Authenticator, genericapifilters.Unauthorized(c.SupportsBasicAuth))
return handler
}
return generic(protect(apiHandler)), generic(audit(apiHandler))
} }
func installAPI(s *GenericAPIServer, c *Config, delegate http.Handler) { func installAPI(s *GenericAPIServer, c *Config, delegate http.Handler) {

View File

@ -33,7 +33,7 @@ func (s *SecureServingInfo) NewLoopbackClientConfig(token string, loopbackCert [
return nil, nil return nil, nil
} }
host, port, err := s.ServingInfo.loopbackHostPort() host, port, err := LoopbackHostPort(s.BindAddress)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -90,13 +90,13 @@ func findCA(chain []*x509.Certificate) (*x509.Certificate, error) {
return nil, fmt.Errorf("no certificate with CA:TRUE found in chain") return nil, fmt.Errorf("no certificate with CA:TRUE found in chain")
} }
// loopbackHostPort returns the host and port loopback REST clients should use // LoopbackHostPort returns the host and port loopback REST clients should use
// to contact the server. // to contact the server.
func (s *ServingInfo) loopbackHostPort() (string, string, error) { func LoopbackHostPort(bindAddress string) (string, string, error) {
host, port, err := net.SplitHostPort(s.BindAddress) host, port, err := net.SplitHostPort(bindAddress)
if err != nil { if err != nil {
// should never happen // should never happen
return "", "", fmt.Errorf("invalid server bind address: %q", s.BindAddress) return "", "", fmt.Errorf("invalid server bind address: %q", bindAddress)
} }
// Value is expected to be an IP or DNS name, not "0.0.0.0". // Value is expected to be an IP or DNS name, not "0.0.0.0".
@ -107,26 +107,6 @@ func (s *ServingInfo) loopbackHostPort() (string, string, error) {
return host, port, nil return host, port, nil
} }
func (s *ServingInfo) NewLoopbackClientConfig(token string) (*restclient.Config, error) {
if s == nil {
return nil, nil
}
host, port, err := s.loopbackHostPort()
if err != nil {
return nil, err
}
return &restclient.Config{
Host: "http://" + net.JoinHostPort(host, port),
// Increase QPS limits. The client is currently passed to all admission plugins,
// and those can be throttled in case of higher load on apiserver - see #22340 and #22422
// for more details. Once #22422 is fixed, we may want to remove it.
QPS: 50,
Burst: 100,
}, nil
}
func certMatchesName(cert *x509.Certificate, name string) bool { func certMatchesName(cert *x509.Certificate, name string) bool {
for _, certName := range cert.DNSNames { for _, certName := range cert.DNSNames {
if certName == name { if certName == name {

View File

@ -105,11 +105,10 @@ type GenericAPIServer struct {
// The registered APIs // The registered APIs
HandlerContainer *genericmux.APIContainer HandlerContainer *genericmux.APIContainer
SecureServingInfo *SecureServingInfo SecureServingInfo *SecureServingInfo
InsecureServingInfo *ServingInfo
// numerical ports, set after listening // numerical ports, set after listening
effectiveSecurePort, effectiveInsecurePort int effectiveSecurePort int
// ExternalAddress is the address (hostname or IP and port) that should be used in // ExternalAddress is the address (hostname or IP and port) that should be used in
// external (public internet) URLs for this GenericAPIServer. // external (public internet) URLs for this GenericAPIServer.
@ -123,8 +122,7 @@ type GenericAPIServer struct {
Serializer runtime.NegotiatedSerializer Serializer runtime.NegotiatedSerializer
// "Outputs" // "Outputs"
Handler http.Handler Handler http.Handler
InsecureHandler http.Handler
// FallThroughHandler is the final HTTP handler in the chain. // FallThroughHandler is the final HTTP handler in the chain.
// It comes after all filters and the API handling // It comes after all filters and the API handling
FallThroughHandler *mux.PathRecorderMux FallThroughHandler *mux.PathRecorderMux
@ -277,13 +275,6 @@ func (s preparedGenericAPIServer) NonBlockingRun(stopCh <-chan struct{}) error {
} }
} }
if s.InsecureServingInfo != nil && s.InsecureHandler != nil {
if err := s.serveInsecurely(internalStopCh); err != nil {
close(internalStopCh)
return err
}
}
// Now that both listeners have bound successfully, it is the // Now that both listeners have bound successfully, it is the
// responsibility of the caller to close the provided channel to // responsibility of the caller to close the provided channel to
// ensure cleanup. // ensure cleanup.

View File

@ -202,7 +202,7 @@ func TestInstallAPIGroups(t *testing.T) {
groupPaths = append(groupPaths, APIGroupPrefix+"/"+api.GroupMeta.GroupVersion.Group) // /apis/<group> groupPaths = append(groupPaths, APIGroupPrefix+"/"+api.GroupMeta.GroupVersion.Group) // /apis/<group>
} }
server := httptest.NewServer(s.InsecureHandler) server := httptest.NewServer(s.Handler)
defer server.Close() defer server.Close()
for i := range apis { for i := range apis {
@ -336,14 +336,11 @@ func TestCustomHandlerChain(t *testing.T) {
var protected, called bool var protected, called bool
config.BuildHandlerChainsFunc = func(apiHandler http.Handler, c *Config) (secure, insecure http.Handler) { config.BuildHandlerChainFunc = func(apiHandler http.Handler, c *Config) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
protected = true protected = true
apiHandler.ServeHTTP(w, req) apiHandler.ServeHTTP(w, req)
}), http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { })
protected = false
apiHandler.ServeHTTP(w, req)
})
} }
handler := http.HandlerFunc(func(r http.ResponseWriter, req *http.Request) { handler := http.HandlerFunc(func(r http.ResponseWriter, req *http.Request) {
called = true called = true
@ -365,8 +362,6 @@ func TestCustomHandlerChain(t *testing.T) {
for i, test := range []Test{ for i, test := range []Test{
{s.Handler, "/nonswagger", true}, {s.Handler, "/nonswagger", true},
{s.Handler, "/secret", true}, {s.Handler, "/secret", true},
{s.InsecureHandler, "/nonswagger", false},
{s.InsecureHandler, "/secret", false},
} { } {
protected, called = false, false protected, called = false, false
@ -485,7 +480,7 @@ func TestDiscoveryAtAPIS(t *testing.T) {
master, etcdserver, _, assert := newMaster(t) master, etcdserver, _, assert := newMaster(t)
defer etcdserver.Terminate(t) defer etcdserver.Terminate(t)
server := httptest.NewServer(master.InsecureHandler) server := httptest.NewServer(master.Handler)
groupList, err := getGroupList(server) groupList, err := getGroupList(server)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@ -535,7 +530,7 @@ func TestDiscoveryOrdering(t *testing.T) {
master, etcdserver, _, assert := newMaster(t) master, etcdserver, _, assert := newMaster(t)
defer etcdserver.Terminate(t) defer etcdserver.Terminate(t)
server := httptest.NewServer(master.InsecureHandler) server := httptest.NewServer(master.Handler)
groupList, err := getGroupList(server) groupList, err := getGroupList(server)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)

View File

@ -71,29 +71,19 @@ func (s *ServerRunOptions) ApplyTo(c *server.Config) error {
return nil return nil
} }
// DefaultAdvertiseAddress sets the field AdvertiseAddress if // DefaultAdvertiseAddress sets the field AdvertiseAddress if unset. The field will be set based on the SecureServingOptions.
// unset. The field will be set based on the SecureServingOptions. If func (s *ServerRunOptions) DefaultAdvertiseAddress(secure *SecureServingOptions) error {
// the SecureServingOptions is not present, DefaultExternalAddress if secure == nil {
// will fall back to the insecure ServingOptions. return nil
func (s *ServerRunOptions) DefaultAdvertiseAddress(secure *SecureServingOptions, insecure *ServingOptions) error { }
if s.AdvertiseAddress == nil || s.AdvertiseAddress.IsUnspecified() {
switch {
case secure != nil:
hostIP, err := secure.ServingOptions.DefaultExternalAddress()
if err != nil {
return fmt.Errorf("Unable to find suitable network address.error='%v'. "+
"Try to set the AdvertiseAddress directly or provide a valid BindAddress to fix this.", err)
}
s.AdvertiseAddress = hostIP
case insecure != nil: if s.AdvertiseAddress == nil || s.AdvertiseAddress.IsUnspecified() {
hostIP, err := insecure.DefaultExternalAddress() hostIP, err := secure.DefaultExternalAddress()
if err != nil { if err != nil {
return fmt.Errorf("Unable to find suitable network address.error='%v'. "+ return fmt.Errorf("Unable to find suitable network address.error='%v'. "+
"Try to set the AdvertiseAddress directly or provide a valid BindAddress to fix this.", err) "Try to set the AdvertiseAddress directly or provide a valid BindAddress to fix this.", err)
}
s.AdvertiseAddress = hostIP
} }
s.AdvertiseAddress = hostIP
} }
return nil return nil

View File

@ -35,13 +35,9 @@ import (
certutil "k8s.io/client-go/util/cert" certutil "k8s.io/client-go/util/cert"
) )
type ServingOptions struct { type SecureServingOptions struct {
BindAddress net.IP BindAddress net.IP
BindPort int BindPort int
}
type SecureServingOptions struct {
ServingOptions ServingOptions
// ServerCert is the TLS cert info for serving secure traffic // ServerCert is the TLS cert info for serving secure traffic
ServerCert GeneratableKeyCert ServerCert GeneratableKeyCert
@ -71,10 +67,8 @@ type GeneratableKeyCert struct {
func NewSecureServingOptions() *SecureServingOptions { func NewSecureServingOptions() *SecureServingOptions {
return &SecureServingOptions{ return &SecureServingOptions{
ServingOptions: ServingOptions{ BindAddress: net.ParseIP("0.0.0.0"),
BindAddress: net.ParseIP("0.0.0.0"), BindPort: 443,
BindPort: 443,
},
ServerCert: GeneratableKeyCert{ ServerCert: GeneratableKeyCert{
PairName: "apiserver", PairName: "apiserver",
CertDirectory: "apiserver.local.config/certificates", CertDirectory: "apiserver.local.config/certificates",
@ -82,23 +76,27 @@ func NewSecureServingOptions() *SecureServingOptions {
} }
} }
func (s *SecureServingOptions) DefaultExternalAddress() (net.IP, error) {
return utilnet.ChooseBindAddress(s.BindAddress)
}
func (s *SecureServingOptions) Validate() []error { func (s *SecureServingOptions) Validate() []error {
errors := []error{} errors := []error{}
if s == nil {
return errors if s.BindPort < 0 || s.BindPort > 65535 {
errors = append(errors, fmt.Errorf("--secure-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port.", s.BindPort))
} }
errors = append(errors, s.ServingOptions.Validate("secure-port")...)
return errors return errors
} }
func (s *SecureServingOptions) AddFlags(fs *pflag.FlagSet) { func (s *SecureServingOptions) AddFlags(fs *pflag.FlagSet) {
fs.IPVar(&s.ServingOptions.BindAddress, "bind-address", s.ServingOptions.BindAddress, ""+ fs.IPVar(&s.BindAddress, "bind-address", s.BindAddress, ""+
"The IP address on which to listen for the --secure-port port. The "+ "The IP address on which to listen for the --secure-port port. The "+
"associated interface(s) must be reachable by the rest of the cluster, and by CLI/web "+ "associated interface(s) must be reachable by the rest of the cluster, and by CLI/web "+
"clients. If blank, all interfaces will be used (0.0.0.0).") "clients. If blank, all interfaces will be used (0.0.0.0).")
fs.IntVar(&s.ServingOptions.BindPort, "secure-port", s.ServingOptions.BindPort, ""+ fs.IntVar(&s.BindPort, "secure-port", s.BindPort, ""+
"The port on which to serve HTTPS with authentication and authorization. If 0, "+ "The port on which to serve HTTPS with authentication and authorization. If 0, "+
"don't serve HTTPS at all.") "don't serve HTTPS at all.")
@ -131,13 +129,13 @@ func (s *SecureServingOptions) AddFlags(fs *pflag.FlagSet) {
} }
func (s *SecureServingOptions) AddDeprecatedFlags(fs *pflag.FlagSet) { func (s *SecureServingOptions) AddDeprecatedFlags(fs *pflag.FlagSet) {
fs.IPVar(&s.ServingOptions.BindAddress, "public-address-override", s.ServingOptions.BindAddress, fs.IPVar(&s.BindAddress, "public-address-override", s.BindAddress,
"DEPRECATED: see --bind-address instead.") "DEPRECATED: see --bind-address instead.")
fs.MarkDeprecated("public-address-override", "see --bind-address instead.") fs.MarkDeprecated("public-address-override", "see --bind-address instead.")
} }
func (s *SecureServingOptions) ApplyTo(c *server.Config) error { func (s *SecureServingOptions) ApplyTo(c *server.Config) error {
if s.ServingOptions.BindPort <= 0 { if s.BindPort <= 0 {
return nil return nil
} }
if err := s.applyServingInfoTo(c); err != nil { if err := s.applyServingInfoTo(c); err != nil {
@ -173,14 +171,12 @@ func (s *SecureServingOptions) ApplyTo(c *server.Config) error {
} }
func (s *SecureServingOptions) applyServingInfoTo(c *server.Config) error { func (s *SecureServingOptions) applyServingInfoTo(c *server.Config) error {
if s.ServingOptions.BindPort <= 0 { if s.BindPort <= 0 {
return nil return nil
} }
secureServingInfo := &server.SecureServingInfo{ secureServingInfo := &server.SecureServingInfo{
ServingInfo: server.ServingInfo{ BindAddress: net.JoinHostPort(s.BindAddress.String(), strconv.Itoa(s.BindPort)),
BindAddress: net.JoinHostPort(s.ServingOptions.BindAddress.String(), strconv.Itoa(s.ServingOptions.BindPort)),
},
} }
serverCertFile, serverKeyFile := s.ServerCert.CertKey.CertFile, s.ServerCert.CertKey.KeyFile serverCertFile, serverKeyFile := s.ServerCert.CertKey.CertFile, s.ServerCert.CertKey.KeyFile
@ -231,67 +227,7 @@ func (s *SecureServingOptions) applyServingInfoTo(c *server.Config) error {
} }
c.SecureServingInfo = secureServingInfo c.SecureServingInfo = secureServingInfo
c.ReadWritePort = s.ServingOptions.BindPort c.ReadWritePort = s.BindPort
return nil
}
func NewInsecureServingOptions() *ServingOptions {
return &ServingOptions{
BindAddress: net.ParseIP("127.0.0.1"),
BindPort: 8080,
}
}
func (s ServingOptions) Validate(portArg string) []error {
errors := []error{}
if s.BindPort < 0 || s.BindPort > 65535 {
errors = append(errors, fmt.Errorf("--%v %v must be between 0 and 65535, inclusive. 0 for turning off secure port.", portArg, s.BindPort))
}
return errors
}
func (s *ServingOptions) DefaultExternalAddress() (net.IP, error) {
return utilnet.ChooseBindAddress(s.BindAddress)
}
func (s *ServingOptions) AddFlags(fs *pflag.FlagSet) {
fs.IPVar(&s.BindAddress, "insecure-bind-address", s.BindAddress, ""+
"The IP address on which to serve the --insecure-port (set to 0.0.0.0 for all interfaces). "+
"Defaults to localhost.")
fs.IntVar(&s.BindPort, "insecure-port", s.BindPort, ""+
"The port on which to serve unsecured, unauthenticated access. Default 8080. It is assumed "+
"that firewall rules are set up such that this port is not reachable from outside of "+
"the cluster and that port 443 on the cluster's public address is proxied to this "+
"port. This is performed by nginx in the default setup.")
}
func (s *ServingOptions) AddDeprecatedFlags(fs *pflag.FlagSet) {
fs.IPVar(&s.BindAddress, "address", s.BindAddress,
"DEPRECATED: see --insecure-bind-address instead.")
fs.MarkDeprecated("address", "see --insecure-bind-address instead.")
fs.IntVar(&s.BindPort, "port", s.BindPort, "DEPRECATED: see --insecure-port instead.")
fs.MarkDeprecated("port", "see --insecure-port instead.")
}
func (s *ServingOptions) ApplyTo(c *server.Config) error {
if s.BindPort <= 0 {
return nil
}
c.InsecureServingInfo = &server.ServingInfo{
BindAddress: net.JoinHostPort(s.BindAddress.String(), strconv.Itoa(s.BindPort)),
}
var err error
privilegedLoopbackToken := uuid.NewRandom().String()
if c.LoopbackClientConfig, err = c.InsecureServingInfo.NewLoopbackClientConfig(privilegedLoopbackToken); err != nil {
return err
}
return nil return nil
} }
@ -301,7 +237,7 @@ func (s *SecureServingOptions) MaybeDefaultWithSelfSignedCerts(publicAddress str
return nil return nil
} }
keyCert := &s.ServerCert.CertKey keyCert := &s.ServerCert.CertKey
if s.ServingOptions.BindPort == 0 || len(keyCert.CertFile) != 0 || len(keyCert.KeyFile) != 0 { if s.BindPort == 0 || len(keyCert.CertFile) != 0 || len(keyCert.KeyFile) != 0 {
return nil return nil
} }
@ -314,11 +250,11 @@ func (s *SecureServingOptions) MaybeDefaultWithSelfSignedCerts(publicAddress str
} }
if !canReadCertAndKey { if !canReadCertAndKey {
// add either the bind address or localhost to the valid alternates // add either the bind address or localhost to the valid alternates
bindIP := s.ServingOptions.BindAddress.String() bindIP := s.BindAddress.String()
if bindIP == "0.0.0.0" { if bindIP == "0.0.0.0" {
alternateDNS = append(alternateDNS, "localhost") alternateDNS = append(alternateDNS, "localhost")
} else { } else {
alternateIPs = append(alternateIPs, s.ServingOptions.BindAddress) alternateIPs = append(alternateIPs, s.BindAddress)
} }
if cert, key, err := certutil.GenerateSelfSignedCertKey(publicAddress, alternateIPs, alternateDNS); err != nil { if cert, key, err := certutil.GenerateSelfSignedCertKey(publicAddress, alternateIPs, alternateDNS); err != nil {

View File

@ -459,10 +459,8 @@ NextTest:
config.EnableIndex = true config.EnableIndex = true
secureOptions := &SecureServingOptions{ secureOptions := &SecureServingOptions{
ServingOptions: ServingOptions{ BindAddress: net.ParseIP("127.0.0.1"),
BindAddress: net.ParseIP("127.0.0.1"), BindPort: 6443,
BindPort: 6443,
},
ServerCert: GeneratableKeyCert{ ServerCert: GeneratableKeyCert{
CertKey: CertKey{ CertKey: CertKey{
CertFile: serverCertBundleFile, CertFile: serverCertBundleFile,
@ -476,7 +474,6 @@ NextTest:
t.Errorf("%q - failed applying the SecureServingOptions: %v", title, err) t.Errorf("%q - failed applying the SecureServingOptions: %v", title, err)
return return
} }
config.InsecureServingInfo = nil
s, err := config.Complete().New() s, err := config.Complete().New()
if err != nil { if err != nil {

View File

@ -78,28 +78,13 @@ func (s *GenericAPIServer) serveSecurely(stopCh <-chan struct{}) error {
glog.Infof("Serving securely on %s", s.SecureServingInfo.BindAddress) glog.Infof("Serving securely on %s", s.SecureServingInfo.BindAddress)
var err error var err error
s.effectiveSecurePort, err = runServer(secureServer, s.SecureServingInfo.BindNetwork, stopCh) s.effectiveSecurePort, err = RunServer(secureServer, s.SecureServingInfo.BindNetwork, stopCh)
return err return err
} }
// serveInsecurely run the insecure http server. It fails only if the initial listen // RunServer listens on the given port, then spawns a go-routine continuously serving
// call fails. The actual server loop (stoppable by closing stopCh) runs in a go
// routine, i.e. serveInsecurely does not block.
func (s *GenericAPIServer) serveInsecurely(stopCh <-chan struct{}) error {
insecureServer := &http.Server{
Addr: s.InsecureServingInfo.BindAddress,
Handler: s.InsecureHandler,
MaxHeaderBytes: 1 << 20,
}
glog.Infof("Serving insecurely on %s", s.InsecureServingInfo.BindAddress)
var err error
s.effectiveInsecurePort, err = runServer(insecureServer, s.InsecureServingInfo.BindNetwork, stopCh)
return err
}
// runServer listens on the given port, then spawns a go-routine continuously serving
// until the stopCh is closed. The port is returned. This function does not block. // until the stopCh is closed. The port is returned. This function does not block.
func runServer(server *http.Server, network string, stopCh <-chan struct{}) (int, error) { func RunServer(server *http.Server, network string, stopCh <-chan struct{}) (int, error) {
if len(server.Addr) == 0 { if len(server.Addr) == 0 {
return 0, errors.New("address cannot be empty") return 0, errors.New("address cannot be empty")
} }

View File

@ -96,7 +96,6 @@ func NewDefaultOptions(out, err io.Writer) *AggregatorOptions {
StdOut: out, StdOut: out,
StdErr: err, StdErr: err,
} }
o.RecommendedOptions.SecureServing.ServingOptions.BindPort = 443
return o return o
} }

View File

@ -97,8 +97,8 @@ func TestAggregatedAPIServer(t *testing.T) {
} }
kubeAPIServerOptions := options.NewServerRunOptions() kubeAPIServerOptions := options.NewServerRunOptions()
kubeAPIServerOptions.SecureServing.ServingOptions.BindAddress = net.ParseIP("127.0.0.1") kubeAPIServerOptions.SecureServing.BindAddress = net.ParseIP("127.0.0.1")
kubeAPIServerOptions.SecureServing.ServingOptions.BindPort = kubePort kubeAPIServerOptions.SecureServing.BindPort = kubePort
kubeAPIServerOptions.SecureServing.ServerCert.CertDirectory = certDir kubeAPIServerOptions.SecureServing.ServerCert.CertDirectory = certDir
kubeAPIServerOptions.InsecureServing.BindPort = 0 kubeAPIServerOptions.InsecureServing.BindPort = 0
kubeAPIServerOptions.Etcd.StorageConfig.ServerList = []string{framework.GetEtcdURLFromEnv()} kubeAPIServerOptions.Etcd.StorageConfig.ServerList = []string{framework.GetEtcdURLFromEnv()}
@ -111,7 +111,7 @@ func TestAggregatedAPIServer(t *testing.T) {
kubeAPIServerOptions.Authentication.ClientCert.ClientCA = clientCACertFile.Name() kubeAPIServerOptions.Authentication.ClientCert.ClientCA = clientCACertFile.Name()
kubeAPIServerOptions.Authorization.Mode = "RBAC" kubeAPIServerOptions.Authorization.Mode = "RBAC"
kubeAPIServerConfig, sharedInformers, err := app.CreateKubeAPIServerConfig(kubeAPIServerOptions) kubeAPIServerConfig, sharedInformers, _, err := app.CreateKubeAPIServerConfig(kubeAPIServerOptions)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -41,7 +41,7 @@ func getRunOptions() *options.ServerRunOptions {
// Use a unique prefix to ensure isolation from other tests using the same etcd instance // Use a unique prefix to ensure isolation from other tests using the same etcd instance
r.Etcd.StorageConfig.Prefix = uuid.New() r.Etcd.StorageConfig.Prefix = uuid.New()
// Disable secure serving // Disable secure serving
r.SecureServing.ServingOptions.BindPort = 0 r.SecureServing.BindPort = 0
return r return r
} }