From 25a00cd3c1ed28e15c328421ddfff567740994be Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Wed, 4 Jul 2018 17:01:49 +0200 Subject: [PATCH 1/3] apiserver: get rid of ReadWritePort in config Kubernetes-commit: e32f380fa5df4361894570787814d0459baada93 --- pkg/server/config.go | 39 +++++++++++++++------ pkg/server/options/serving_with_loopback.go | 2 -- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/pkg/server/config.go b/pkg/server/config.go index 5097a98b6..43fb57cd4 100644 --- a/pkg/server/config.go +++ b/pkg/server/config.go @@ -181,9 +181,6 @@ type Config struct { // values below here are targets for removal //=========================================================================== - // The port on PublicAddress where a read-write server will be installed. - // Defaults to 6443 if not set. - ReadWritePort int // PublicAddress is the IP address where members of the cluster (kubelet, // kube-proxy, services, etc.) can reach the GenericAPIServer. // If nil or 0.0.0.0, the host's default interface will be used. @@ -250,7 +247,6 @@ type AuthorizationInfo struct { func NewConfig(codecs serializer.CodecFactory) *Config { return &Config{ Serializer: codecs, - ReadWritePort: 443, BuildHandlerChainFunc: DefaultBuildHandlerChain, HandlerChainWaitGroup: new(utilwaitgroup.SafeWaitGroup), LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix), @@ -354,16 +350,21 @@ type CompletedConfig struct { // Complete fills in any fields not set that are required to have valid data and can be derived // from other fields. If you're going to `ApplyOptions`, do that first. It's mutating the receiver. func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedConfig { - host := c.ExternalAddress - if host == "" && c.PublicAddress != nil { - host = c.PublicAddress.String() + if len(c.ExternalAddress) == 0 && c.PublicAddress != nil { + c.ExternalAddress = c.PublicAddress.String() } - // if there is no port, and we have a ReadWritePort, use that - if _, _, err := net.SplitHostPort(host); err != nil && c.ReadWritePort != 0 { - host = net.JoinHostPort(host, strconv.Itoa(c.ReadWritePort)) + // if there is no port, and we listen on one securely, use that one + if _, _, err := net.SplitHostPort(c.ExternalAddress); err != nil { + if c.SecureServing == nil { + glog.Fatalf("cannot derive external address port without listening on a secure port.") + } + _, port, err := c.SecureServing.HostPort() + if err != nil { + glog.Fatalf("cannot derive external address from the secure port: %v", err) + } + c.ExternalAddress = net.JoinHostPort(c.ExternalAddress, strconv.Itoa(port)) } - c.ExternalAddress = host if c.OpenAPIConfig != nil && c.OpenAPIConfig.SecurityDefinitions != nil { // Setup OpenAPI security: all APIs will have the same authentication for now. @@ -615,3 +616,19 @@ func NewRequestInfoResolver(c *Config) *apirequest.RequestInfoFactory { GrouplessAPIPrefixes: legacyAPIPrefixes, } } + +func (s *SecureServingInfo) HostPort() (string, int, error) { + if s == nil || s.Listener == nil { + return "", 0, fmt.Errorf("no listener found") + } + addr := s.Listener.Addr().String() + host, portStr, err := net.SplitHostPort(addr) + if err != nil { + return "", 0, fmt.Errorf("failed to get port from listener address %q: %v", addr, err) + } + port, err := strconv.Atoi(portStr) + if err != nil { + return "", 0, fmt.Errorf("invalid non-numeric port %q", portStr) + } + return host, port, nil +} diff --git a/pkg/server/options/serving_with_loopback.go b/pkg/server/options/serving_with_loopback.go index 8d249cb54..dd6e0e1a7 100644 --- a/pkg/server/options/serving_with_loopback.go +++ b/pkg/server/options/serving_with_loopback.go @@ -48,8 +48,6 @@ func (s *SecureServingOptionsWithLoopback) ApplyTo(c *server.Config) error { return nil } - c.ReadWritePort = s.BindPort - // create self-signed cert+key with the fake server.LoopbackClientServerNameOverride and // let the server return it when the loopback client connects. certPem, keyPem, err := certutil.GenerateSelfSignedCertKey(server.LoopbackClientServerNameOverride, nil, nil) From ad29bd83ae91efccfb40578445e26104b814bbb4 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Fri, 6 Jul 2018 12:58:59 +0200 Subject: [PATCH 2/3] kube-apiserver: disallow --secure-port 0 Kubernetes-commit: e15ac9eb72c4e105e7a3d84711e5a6056c0f6a48 --- pkg/server/options/serving.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pkg/server/options/serving.go b/pkg/server/options/serving.go index ee9cebacd..7a2f570fc 100644 --- a/pkg/server/options/serving.go +++ b/pkg/server/options/serving.go @@ -40,6 +40,8 @@ type SecureServingOptions struct { // BindNetwork is the type of network to bind to - defaults to "tcp", accepts "tcp", // "tcp4", and "tcp6". BindNetwork string + // Required set to true means that BindPort cannot be zero. + Required bool // Listener is the secure server network listener. // either Listener or BindAddress/BindPort/BindNetwork is set, @@ -102,7 +104,9 @@ func (s *SecureServingOptions) Validate() []error { errors := []error{} - if s.BindPort < 0 || s.BindPort > 65535 { + if s.Required && s.BindPort < 1 || s.BindPort > 65535 { + errors = append(errors, fmt.Errorf("--secure-port %v must be between 1 and 65535, inclusive. It cannot turned off with 0", s.BindPort)) + } else 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)) } @@ -118,9 +122,14 @@ func (s *SecureServingOptions) AddFlags(fs *pflag.FlagSet) { "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 "+ "clients. If blank, all interfaces will be used (0.0.0.0 for all IPv4 interfaces and :: for all IPv6 interfaces).") - fs.IntVar(&s.BindPort, "secure-port", s.BindPort, ""+ - "The port on which to serve HTTPS with authentication and authorization. If 0, "+ - "don't serve HTTPS at all.") + + desc := "The port on which to serve HTTPS with authentication and authorization." + if s.Required { + desc += "It cannot switched off with 0." + } else { + desc += "If 0, don't serve HTTPS at all." + } + fs.IntVar(&s.BindPort, "secure-port", s.BindPort, desc) fs.StringVar(&s.ServerCert.CertDirectory, "cert-dir", s.ServerCert.CertDirectory, ""+ "The directory where the TLS certs are located. "+ From 9fb7dcda85426bcd551f4b0abe86e255029fd506 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Fri, 6 Jul 2018 19:20:45 +0200 Subject: [PATCH 3/3] kube-apiserver: fix tests which don't use tls yet Kubernetes-commit: 6bb3aba23dfbfd8b145a33e9d1a461658bd60fc0 --- pkg/server/config_test.go | 2 ++ pkg/server/genericapiserver_test.go | 1 + 2 files changed, 3 insertions(+) diff --git a/pkg/server/config_test.go b/pkg/server/config_test.go index 13f0c7409..07fece4c7 100644 --- a/pkg/server/config_test.go +++ b/pkg/server/config_test.go @@ -34,6 +34,7 @@ import ( func TestNewWithDelegate(t *testing.T) { delegateConfig := NewConfig(codecs) + delegateConfig.ExternalAddress = "192.168.10.4:443" delegateConfig.PublicAddress = net.ParseIP("192.168.10.4") delegateConfig.LegacyAPIGroupPrefixes = sets.NewString("/api") delegateConfig.LoopbackClientConfig = &rest.Config{} @@ -64,6 +65,7 @@ func TestNewWithDelegate(t *testing.T) { delegateServer.PrepareRun() wrappingConfig := NewConfig(codecs) + wrappingConfig.ExternalAddress = "192.168.10.4:443" wrappingConfig.PublicAddress = net.ParseIP("192.168.10.4") wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api") wrappingConfig.LoopbackClientConfig = &rest.Config{} diff --git a/pkg/server/genericapiserver_test.go b/pkg/server/genericapiserver_test.go index bde27d483..a3dda1a44 100644 --- a/pkg/server/genericapiserver_test.go +++ b/pkg/server/genericapiserver_test.go @@ -125,6 +125,7 @@ func testGetOpenAPIDefinitions(_ kubeopenapi.ReferenceCallback) map[string]kubeo // setUp is a convience function for setting up for (most) tests. func setUp(t *testing.T) (Config, *assert.Assertions) { config := NewConfig(codecs) + config.ExternalAddress = "192.168.10.4:443" config.PublicAddress = net.ParseIP("192.168.10.4") config.LegacyAPIGroupPrefixes = sets.NewString("/api") config.LoopbackClientConfig = &restclient.Config{}