mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
remove non-generic options from genericapiserver.Config
This commit is contained in:
parent
4c12c3b130
commit
d82f98c9b3
@ -86,7 +86,11 @@ func Run(s *options.ServerRunOptions) error {
|
|||||||
ApplyOptions(s.GenericServerRunOptions). // apply the options selected
|
ApplyOptions(s.GenericServerRunOptions). // apply the options selected
|
||||||
Complete() // set default values based on the known values
|
Complete() // set default values based on the known values
|
||||||
|
|
||||||
if err := genericConfig.MaybeGenerateServingCerts(); err != nil {
|
serviceIPRange, apiServerServiceIP, err := genericapiserver.DefaultServiceIPRange(s.GenericServerRunOptions.ServiceClusterIPRange)
|
||||||
|
if err != nil {
|
||||||
|
glog.Fatalf("Error determining service IP ranges: %v", err)
|
||||||
|
}
|
||||||
|
if err := genericConfig.MaybeGenerateServingCerts(apiServerServiceIP); err != nil {
|
||||||
glog.Fatalf("Failed to generate service certificate: %v", err)
|
glog.Fatalf("Failed to generate service certificate: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,6 +326,15 @@ func Run(s *options.ServerRunOptions) error {
|
|||||||
ProxyTransport: proxyTransport,
|
ProxyTransport: proxyTransport,
|
||||||
|
|
||||||
Tunneler: tunneler,
|
Tunneler: tunneler,
|
||||||
|
|
||||||
|
ServiceIPRange: serviceIPRange,
|
||||||
|
APIServerServiceIP: apiServerServiceIP,
|
||||||
|
APIServerServicePort: 443,
|
||||||
|
|
||||||
|
ServiceNodePortRange: s.GenericServerRunOptions.ServiceNodePortRange,
|
||||||
|
KubernetesServiceNodePort: s.GenericServerRunOptions.KubernetesServiceNodePort,
|
||||||
|
|
||||||
|
MasterCount: s.GenericServerRunOptions.MasterCount,
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.GenericServerRunOptions.EnableWatchCache {
|
if s.GenericServerRunOptions.EnableWatchCache {
|
||||||
|
@ -15,6 +15,7 @@ go_library(
|
|||||||
srcs = [
|
srcs = [
|
||||||
"config.go",
|
"config.go",
|
||||||
"default_storage_factory_builder.go",
|
"default_storage_factory_builder.go",
|
||||||
|
"discovery.go",
|
||||||
"doc.go",
|
"doc.go",
|
||||||
"genericapiserver.go",
|
"genericapiserver.go",
|
||||||
"healthz.go",
|
"healthz.go",
|
||||||
@ -23,6 +24,7 @@ go_library(
|
|||||||
"resource_encoding_config.go",
|
"resource_encoding_config.go",
|
||||||
"reststorage_interfaces.go",
|
"reststorage_interfaces.go",
|
||||||
"serve.go",
|
"serve.go",
|
||||||
|
"services.go",
|
||||||
"storage_factory.go",
|
"storage_factory.go",
|
||||||
"tunneler.go",
|
"tunneler.go",
|
||||||
],
|
],
|
||||||
@ -102,11 +104,11 @@ go_test(
|
|||||||
"//pkg/auth/user:go_default_library",
|
"//pkg/auth/user:go_default_library",
|
||||||
"//pkg/generated/openapi:go_default_library",
|
"//pkg/generated/openapi:go_default_library",
|
||||||
"//pkg/genericapiserver/options:go_default_library",
|
"//pkg/genericapiserver/options:go_default_library",
|
||||||
"//pkg/registry/core/service/ipallocator:go_default_library",
|
|
||||||
"//pkg/storage/etcd/testing:go_default_library",
|
"//pkg/storage/etcd/testing:go_default_library",
|
||||||
"//pkg/storage/storagebackend:go_default_library",
|
"//pkg/storage/storagebackend:go_default_library",
|
||||||
"//pkg/util/cert:go_default_library",
|
"//pkg/util/cert:go_default_library",
|
||||||
"//pkg/util/clock:go_default_library",
|
"//pkg/util/clock:go_default_library",
|
||||||
|
"//pkg/util/net:go_default_library",
|
||||||
"//pkg/util/sets:go_default_library",
|
"//pkg/util/sets:go_default_library",
|
||||||
"//pkg/version:go_default_library",
|
"//pkg/version:go_default_library",
|
||||||
"//vendor:github.com/go-openapi/spec",
|
"//vendor:github.com/go-openapi/spec",
|
||||||
|
@ -50,7 +50,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/genericapiserver/options"
|
"k8s.io/kubernetes/pkg/genericapiserver/options"
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver/routes"
|
"k8s.io/kubernetes/pkg/genericapiserver/routes"
|
||||||
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
|
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
|
||||||
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
certutil "k8s.io/kubernetes/pkg/util/cert"
|
certutil "k8s.io/kubernetes/pkg/util/cert"
|
||||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
@ -107,13 +106,13 @@ type Config struct {
|
|||||||
// Note that it is up to the request handlers to ignore or honor this timeout. In seconds.
|
// Note that it is up to the request handlers to ignore or honor this timeout. In seconds.
|
||||||
MinRequestTimeout int
|
MinRequestTimeout int
|
||||||
|
|
||||||
// Number of masters running; all masters must be started with the
|
|
||||||
// same value for this field. (Numbers > 1 currently untested.)
|
|
||||||
MasterCount int
|
|
||||||
|
|
||||||
SecureServingInfo *SecureServingInfo
|
SecureServingInfo *SecureServingInfo
|
||||||
InsecureServingInfo *ServingInfo
|
InsecureServingInfo *ServingInfo
|
||||||
|
|
||||||
|
// DiscoveryAddresses is used to build the IPs pass to discovery. If nil, the ExternalAddress is
|
||||||
|
// always reported
|
||||||
|
DiscoveryAddresses DiscoveryAddresses
|
||||||
|
|
||||||
// The port on PublicAddress where a read-write server will be installed.
|
// The port on PublicAddress where a read-write server will be installed.
|
||||||
// Defaults to 6443 if not set.
|
// Defaults to 6443 if not set.
|
||||||
ReadWritePort int
|
ReadWritePort int
|
||||||
@ -126,34 +125,6 @@ type Config struct {
|
|||||||
// If nil or 0.0.0.0, the host's default interface will be used.
|
// If nil or 0.0.0.0, the host's default interface will be used.
|
||||||
PublicAddress net.IP
|
PublicAddress net.IP
|
||||||
|
|
||||||
// The range of IPs to be assigned to services with type=ClusterIP or greater
|
|
||||||
ServiceClusterIPRange *net.IPNet
|
|
||||||
|
|
||||||
// The IP address for the GenericAPIServer service (must be inside ServiceClusterIPRange)
|
|
||||||
ServiceReadWriteIP net.IP
|
|
||||||
|
|
||||||
// Port for the apiserver service.
|
|
||||||
ServiceReadWritePort int
|
|
||||||
|
|
||||||
// The range of ports to be assigned to services with type=NodePort or greater
|
|
||||||
ServiceNodePortRange utilnet.PortRange
|
|
||||||
|
|
||||||
// Additional ports to be exposed on the GenericAPIServer service
|
|
||||||
// extraServicePorts is injectable in the event that more ports
|
|
||||||
// (other than the default 443/tcp) are exposed on the GenericAPIServer
|
|
||||||
// and those ports need to be load balanced by the GenericAPIServer
|
|
||||||
// service because this pkg is linked by out-of-tree projects
|
|
||||||
// like openshift which want to use the GenericAPIServer but also do
|
|
||||||
// more stuff.
|
|
||||||
ExtraServicePorts []api.ServicePort
|
|
||||||
// Additional ports to be exposed on the GenericAPIServer endpoints
|
|
||||||
// Port names should align with ports defined in ExtraServicePorts
|
|
||||||
ExtraEndpointPorts []api.EndpointPort
|
|
||||||
|
|
||||||
// If non-zero, the "kubernetes" services uses this port as NodePort.
|
|
||||||
// TODO(sttts): move into master
|
|
||||||
KubernetesServiceNodePort int
|
|
||||||
|
|
||||||
// EnableOpenAPISupport enables OpenAPI support. Allow downstream customers to disable OpenAPI spec.
|
// EnableOpenAPISupport enables OpenAPI support. Allow downstream customers to disable OpenAPI spec.
|
||||||
EnableOpenAPISupport bool
|
EnableOpenAPISupport bool
|
||||||
|
|
||||||
@ -221,9 +192,7 @@ func NewConfig() *Config {
|
|||||||
|
|
||||||
config := &Config{
|
config := &Config{
|
||||||
Serializer: api.Codecs,
|
Serializer: api.Codecs,
|
||||||
MasterCount: 1,
|
|
||||||
ReadWritePort: 6443,
|
ReadWritePort: 6443,
|
||||||
ServiceReadWritePort: 443,
|
|
||||||
RequestContextMapper: api.NewRequestContextMapper(),
|
RequestContextMapper: api.NewRequestContextMapper(),
|
||||||
BuildHandlerChainsFunc: DefaultBuildHandlerChain,
|
BuildHandlerChainsFunc: DefaultBuildHandlerChain,
|
||||||
LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix),
|
LegacyAPIGroupPrefixes: sets.NewString(DefaultLegacyAPIPrefix),
|
||||||
@ -318,13 +287,9 @@ func (c *Config) ApplyOptions(options *options.ServerRunOptions) *Config {
|
|||||||
c.EnableProfiling = options.EnableProfiling
|
c.EnableProfiling = options.EnableProfiling
|
||||||
c.EnableSwaggerUI = options.EnableSwaggerUI
|
c.EnableSwaggerUI = options.EnableSwaggerUI
|
||||||
c.ExternalAddress = options.ExternalHost
|
c.ExternalAddress = options.ExternalHost
|
||||||
c.KubernetesServiceNodePort = options.KubernetesServiceNodePort
|
|
||||||
c.MasterCount = options.MasterCount
|
|
||||||
c.MaxRequestsInFlight = options.MaxRequestsInFlight
|
c.MaxRequestsInFlight = options.MaxRequestsInFlight
|
||||||
c.MinRequestTimeout = options.MinRequestTimeout
|
c.MinRequestTimeout = options.MinRequestTimeout
|
||||||
c.PublicAddress = options.AdvertiseAddress
|
c.PublicAddress = options.AdvertiseAddress
|
||||||
c.ServiceClusterIPRange = &options.ServiceClusterIPRange
|
|
||||||
c.ServiceNodePortRange = options.ServiceNodePortRange
|
|
||||||
c.SupportsBasicAuth = len(options.BasicAuthFile) > 0
|
c.SupportsBasicAuth = len(options.BasicAuthFile) > 0
|
||||||
|
|
||||||
return c
|
return c
|
||||||
@ -337,35 +302,6 @@ type completedConfig struct {
|
|||||||
// Complete fills in any fields not set that are required to have valid data and can be derived
|
// 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.
|
// from other fields. If you're going to `ApplyOptions`, do that first. It's mutating the receiver.
|
||||||
func (c *Config) Complete() completedConfig {
|
func (c *Config) Complete() completedConfig {
|
||||||
if c.ServiceClusterIPRange == nil || c.ServiceClusterIPRange.IP == nil {
|
|
||||||
defaultNet := "10.0.0.0/24"
|
|
||||||
glog.Warningf("Network range for service cluster IPs is unspecified. Defaulting to %v.", defaultNet)
|
|
||||||
_, serviceClusterIPRange, err := net.ParseCIDR(defaultNet)
|
|
||||||
if err != nil {
|
|
||||||
glog.Fatalf("Unable to parse CIDR: %v", err)
|
|
||||||
}
|
|
||||||
if size := ipallocator.RangeSize(serviceClusterIPRange); size < 8 {
|
|
||||||
glog.Fatalf("The service cluster IP range must be at least %d IP addresses", 8)
|
|
||||||
}
|
|
||||||
c.ServiceClusterIPRange = serviceClusterIPRange
|
|
||||||
}
|
|
||||||
if c.ServiceReadWriteIP == nil {
|
|
||||||
// Select the first valid IP from ServiceClusterIPRange to use as the GenericAPIServer service IP.
|
|
||||||
serviceReadWriteIP, err := ipallocator.GetIndexedIP(c.ServiceClusterIPRange, 1)
|
|
||||||
if err != nil {
|
|
||||||
glog.Fatalf("Failed to generate service read-write IP for GenericAPIServer service: %v", err)
|
|
||||||
}
|
|
||||||
glog.V(4).Infof("Setting GenericAPIServer service IP to %q (read-write).", serviceReadWriteIP)
|
|
||||||
c.ServiceReadWriteIP = serviceReadWriteIP
|
|
||||||
}
|
|
||||||
if c.ServiceNodePortRange.Size == 0 {
|
|
||||||
// TODO: Currently no way to specify an empty range (do we need to allow this?)
|
|
||||||
// We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE)
|
|
||||||
// but then that breaks the strict nestedness of ServiceType.
|
|
||||||
// Review post-v1
|
|
||||||
c.ServiceNodePortRange = options.DefaultServiceNodePortRange
|
|
||||||
glog.Infof("Node port range unspecified. Defaulting to %v.", c.ServiceNodePortRange)
|
|
||||||
}
|
|
||||||
if len(c.ExternalAddress) == 0 && c.PublicAddress != nil {
|
if len(c.ExternalAddress) == 0 && c.PublicAddress != nil {
|
||||||
hostAndPort := c.PublicAddress.String()
|
hostAndPort := c.PublicAddress.String()
|
||||||
if c.ReadWritePort != 0 {
|
if c.ReadWritePort != 0 {
|
||||||
@ -395,6 +331,10 @@ func (c *Config) Complete() completedConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if c.DiscoveryAddresses == nil {
|
||||||
|
c.DiscoveryAddresses = DefaultDiscoveryAddresses{DefaultAddress: c.ExternalAddress}
|
||||||
|
}
|
||||||
|
|
||||||
return completedConfig{c}
|
return completedConfig{c}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,14 +370,8 @@ func (c completedConfig) New() (*GenericAPIServer, error) {
|
|||||||
return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil")
|
return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
discoveryAddresses := DefaultDiscoveryAddresses{DefaultAddress: c.ExternalAddress}
|
|
||||||
if c.ServiceClusterIPRange != nil {
|
|
||||||
discoveryAddresses.DiscoveryCIDRRules = append(discoveryAddresses.DiscoveryCIDRRules,
|
|
||||||
DiscoveryCIDRRule{IPRange: *c.ServiceClusterIPRange, Address: net.JoinHostPort(c.ServiceReadWriteIP.String(), strconv.Itoa(c.ServiceReadWritePort))})
|
|
||||||
}
|
|
||||||
|
|
||||||
s := &GenericAPIServer{
|
s := &GenericAPIServer{
|
||||||
discoveryAddresses: discoveryAddresses,
|
discoveryAddresses: c.DiscoveryAddresses,
|
||||||
LoopbackClientConfig: c.LoopbackClientConfig,
|
LoopbackClientConfig: c.LoopbackClientConfig,
|
||||||
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
|
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
|
||||||
admissionControl: c.AdmissionControl,
|
admissionControl: c.AdmissionControl,
|
||||||
@ -447,7 +381,6 @@ func (c completedConfig) New() (*GenericAPIServer, error) {
|
|||||||
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
|
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
|
||||||
enableSwaggerSupport: c.EnableSwaggerSupport,
|
enableSwaggerSupport: c.EnableSwaggerSupport,
|
||||||
|
|
||||||
MasterCount: c.MasterCount,
|
|
||||||
SecureServingInfo: c.SecureServingInfo,
|
SecureServingInfo: c.SecureServingInfo,
|
||||||
InsecureServingInfo: c.InsecureServingInfo,
|
InsecureServingInfo: c.InsecureServingInfo,
|
||||||
ExternalAddress: c.ExternalAddress,
|
ExternalAddress: c.ExternalAddress,
|
||||||
@ -470,12 +403,11 @@ func (c completedConfig) New() (*GenericAPIServer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MaybeGenerateServingCerts generates serving certificates if requested and needed.
|
// MaybeGenerateServingCerts generates serving certificates if requested and needed.
|
||||||
func (c completedConfig) MaybeGenerateServingCerts() error {
|
func (c completedConfig) MaybeGenerateServingCerts(alternateIPs ...net.IP) error {
|
||||||
// It would be nice to set a fqdn subject alt name, but only the kubelets know, the apiserver is clueless
|
// It would be nice to set a fqdn subject alt name, but only the kubelets know, the apiserver is clueless
|
||||||
// alternateDNS = append(alternateDNS, "kubernetes.default.svc.CLUSTER.DNS.NAME")
|
// alternateDNS = append(alternateDNS, "kubernetes.default.svc.CLUSTER.DNS.NAME")
|
||||||
if c.SecureServingInfo != nil && c.SecureServingInfo.ServerCert.Generate && !certutil.CanReadCertOrKey(c.SecureServingInfo.ServerCert.CertFile, c.SecureServingInfo.ServerCert.KeyFile) {
|
if c.SecureServingInfo != nil && c.SecureServingInfo.ServerCert.Generate && !certutil.CanReadCertOrKey(c.SecureServingInfo.ServerCert.CertFile, c.SecureServingInfo.ServerCert.KeyFile) {
|
||||||
// TODO (cjcullen): Is ClusterIP the right address to sign a cert with?
|
// TODO (cjcullen): Is ClusterIP the right address to sign a cert with?
|
||||||
alternateIPs := []net.IP{c.ServiceReadWriteIP}
|
|
||||||
alternateDNS := []string{"kubernetes.default.svc", "kubernetes.default", "kubernetes", "localhost"}
|
alternateDNS := []string{"kubernetes.default.svc", "kubernetes.default", "kubernetes", "localhost"}
|
||||||
|
|
||||||
if cert, key, err := certutil.GenerateSelfSignedCertKey(c.PublicAddress.String(), alternateIPs, alternateDNS); err != nil {
|
if cert, key, err := certutil.GenerateSelfSignedCertKey(c.PublicAddress.String(), alternateIPs, alternateDNS); err != nil {
|
||||||
|
@ -19,7 +19,6 @@ package genericapiserver
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"mime"
|
"mime"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@ -147,10 +146,6 @@ type GenericAPIServer struct {
|
|||||||
healthzLock sync.Mutex
|
healthzLock sync.Mutex
|
||||||
healthzChecks []healthz.HealthzChecker
|
healthzChecks []healthz.HealthzChecker
|
||||||
healthzCreated bool
|
healthzCreated bool
|
||||||
|
|
||||||
// See Config.$name for documentation of these flags:
|
|
||||||
|
|
||||||
MasterCount int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@ -376,20 +375,17 @@ func TestDiscoveryAtAPIS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetServerAddressByClientCIDRs(t *testing.T) {
|
func TestGetServerAddressByClientCIDRs(t *testing.T) {
|
||||||
s, etcdserver, config, _ := newMaster(t)
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
|
|
||||||
publicAddressCIDRMap := []unversioned.ServerAddressByClientCIDR{
|
publicAddressCIDRMap := []unversioned.ServerAddressByClientCIDR{
|
||||||
{
|
{
|
||||||
ClientCIDR: "0.0.0.0/0",
|
ClientCIDR: "0.0.0.0/0",
|
||||||
ServerAddress: config.ExternalAddress,
|
ServerAddress: "ExternalAddress",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
internalAddressCIDRMap := []unversioned.ServerAddressByClientCIDR{
|
internalAddressCIDRMap := []unversioned.ServerAddressByClientCIDR{
|
||||||
publicAddressCIDRMap[0],
|
publicAddressCIDRMap[0],
|
||||||
{
|
{
|
||||||
ClientCIDR: config.ServiceClusterIPRange.String(),
|
ClientCIDR: "10.0.0.0/24",
|
||||||
ServerAddress: net.JoinHostPort(config.ServiceReadWriteIP.String(), strconv.Itoa(config.ServiceReadWritePort)),
|
ServerAddress: "serviceIP",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
internalIP := "10.0.0.1"
|
internalIP := "10.0.0.1"
|
||||||
@ -455,8 +451,13 @@ func TestGetServerAddressByClientCIDRs(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, ipRange, _ := net.ParseCIDR("10.0.0.0/24")
|
||||||
|
discoveryAddresses := DefaultDiscoveryAddresses{DefaultAddress: "ExternalAddress"}
|
||||||
|
discoveryAddresses.DiscoveryCIDRRules = append(discoveryAddresses.DiscoveryCIDRRules,
|
||||||
|
DiscoveryCIDRRule{IPRange: *ipRange, Address: "serviceIP"})
|
||||||
|
|
||||||
for i, test := range testCases {
|
for i, test := range testCases {
|
||||||
if a, e := s.discoveryAddresses.ServerAddressByClientCIDRs(utilnet.GetClientIP(&test.Request)), test.ExpectedMap; reflect.DeepEqual(e, a) != true {
|
if a, e := discoveryAddresses.ServerAddressByClientCIDRs(utilnet.GetClientIP(&test.Request)), test.ExpectedMap; reflect.DeepEqual(e, a) != true {
|
||||||
t.Fatalf("test case %d failed. expected: %v, actual: %v", i+1, e, a)
|
t.Fatalf("test case %d failed. expected: %v, actual: %v", i+1, e, a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
54
pkg/genericapiserver/services.go
Normal file
54
pkg/genericapiserver/services.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
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 genericapiserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DefaultServiceIPRange takes a the serviceIPRange flag and returns the defaulted service ip range (if needed),
|
||||||
|
// api server service IP, and an error
|
||||||
|
// TODO move this out of the genericapiserver package
|
||||||
|
func DefaultServiceIPRange(passedServiceClusterIPRange net.IPNet) (net.IPNet, net.IP, error) {
|
||||||
|
serviceClusterIPRange := passedServiceClusterIPRange
|
||||||
|
if passedServiceClusterIPRange.IP == nil {
|
||||||
|
defaultNet := "10.0.0.0/24"
|
||||||
|
glog.Infof("Network range for service cluster IPs is unspecified. Defaulting to %v.", defaultNet)
|
||||||
|
_, defaultServiceClusterIPRange, err := net.ParseCIDR(defaultNet)
|
||||||
|
if err != nil {
|
||||||
|
return net.IPNet{}, net.IP{}, err
|
||||||
|
}
|
||||||
|
serviceClusterIPRange = *defaultServiceClusterIPRange
|
||||||
|
}
|
||||||
|
if size := ipallocator.RangeSize(&serviceClusterIPRange); size < 8 {
|
||||||
|
return net.IPNet{}, net.IP{}, fmt.Errorf("The service cluster IP range must be at least %d IP addresses", 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the first valid IP from ServiceClusterIPRange to use as the GenericAPIServer service IP.
|
||||||
|
apiServerServiceIP, err := ipallocator.GetIndexedIP(&serviceClusterIPRange, 1)
|
||||||
|
if err != nil {
|
||||||
|
return net.IPNet{}, net.IP{}, err
|
||||||
|
}
|
||||||
|
glog.V(4).Infof("Setting service IP to %q (read-write).", apiServerServiceIP)
|
||||||
|
|
||||||
|
return serviceClusterIPRange, apiServerServiceIP, nil
|
||||||
|
}
|
@ -52,6 +52,7 @@ go_library(
|
|||||||
"//pkg/apis/storage/v1beta1:go_default_library",
|
"//pkg/apis/storage/v1beta1:go_default_library",
|
||||||
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
||||||
"//pkg/genericapiserver:go_default_library",
|
"//pkg/genericapiserver:go_default_library",
|
||||||
|
"//pkg/genericapiserver/options:go_default_library",
|
||||||
"//pkg/healthz:go_default_library",
|
"//pkg/healthz:go_default_library",
|
||||||
"//pkg/kubelet/client:go_default_library",
|
"//pkg/kubelet/client:go_default_library",
|
||||||
"//pkg/master/thirdparty:go_default_library",
|
"//pkg/master/thirdparty:go_default_library",
|
||||||
@ -116,7 +117,6 @@ go_test(
|
|||||||
"//pkg/generated/openapi:go_default_library",
|
"//pkg/generated/openapi:go_default_library",
|
||||||
"//pkg/genericapiserver:go_default_library",
|
"//pkg/genericapiserver:go_default_library",
|
||||||
"//pkg/kubelet/client:go_default_library",
|
"//pkg/kubelet/client:go_default_library",
|
||||||
"//pkg/registry/core/service/ipallocator:go_default_library",
|
|
||||||
"//pkg/registry/registrytest:go_default_library",
|
"//pkg/registry/registrytest:go_default_library",
|
||||||
"//pkg/runtime:go_default_library",
|
"//pkg/runtime:go_default_library",
|
||||||
"//pkg/storage/etcd/testing:go_default_library",
|
"//pkg/storage/etcd/testing:go_default_library",
|
||||||
|
@ -50,7 +50,7 @@ type Controller struct {
|
|||||||
|
|
||||||
ServiceClusterIPRegistry rangeallocation.RangeRegistry
|
ServiceClusterIPRegistry rangeallocation.RangeRegistry
|
||||||
ServiceClusterIPInterval time.Duration
|
ServiceClusterIPInterval time.Duration
|
||||||
ServiceClusterIPRange *net.IPNet
|
ServiceClusterIPRange net.IPNet
|
||||||
|
|
||||||
ServiceNodePortRegistry rangeallocation.RangeRegistry
|
ServiceNodePortRegistry rangeallocation.RangeRegistry
|
||||||
ServiceNodePortInterval time.Duration
|
ServiceNodePortInterval time.Duration
|
||||||
@ -87,21 +87,21 @@ func (c *Config) NewBootstrapController(legacyRESTStorage corerest.LegacyRESTSto
|
|||||||
SystemNamespacesInterval: 1 * time.Minute,
|
SystemNamespacesInterval: 1 * time.Minute,
|
||||||
|
|
||||||
ServiceClusterIPRegistry: legacyRESTStorage.ServiceClusterIPAllocator,
|
ServiceClusterIPRegistry: legacyRESTStorage.ServiceClusterIPAllocator,
|
||||||
ServiceClusterIPRange: c.GenericConfig.ServiceClusterIPRange,
|
ServiceClusterIPRange: c.ServiceIPRange,
|
||||||
ServiceClusterIPInterval: 3 * time.Minute,
|
ServiceClusterIPInterval: 3 * time.Minute,
|
||||||
|
|
||||||
ServiceNodePortRegistry: legacyRESTStorage.ServiceNodePortAllocator,
|
ServiceNodePortRegistry: legacyRESTStorage.ServiceNodePortAllocator,
|
||||||
ServiceNodePortRange: c.GenericConfig.ServiceNodePortRange,
|
ServiceNodePortRange: c.ServiceNodePortRange,
|
||||||
ServiceNodePortInterval: 3 * time.Minute,
|
ServiceNodePortInterval: 3 * time.Minute,
|
||||||
|
|
||||||
PublicIP: c.GenericConfig.PublicAddress,
|
PublicIP: c.GenericConfig.PublicAddress,
|
||||||
|
|
||||||
ServiceIP: c.GenericConfig.ServiceReadWriteIP,
|
ServiceIP: c.APIServerServiceIP,
|
||||||
ServicePort: c.GenericConfig.ServiceReadWritePort,
|
ServicePort: c.APIServerServicePort,
|
||||||
ExtraServicePorts: c.GenericConfig.ExtraServicePorts,
|
ExtraServicePorts: c.ExtraServicePorts,
|
||||||
ExtraEndpointPorts: c.GenericConfig.ExtraEndpointPorts,
|
ExtraEndpointPorts: c.ExtraEndpointPorts,
|
||||||
PublicServicePort: c.GenericConfig.ReadWritePort,
|
PublicServicePort: c.GenericConfig.ReadWritePort,
|
||||||
KubernetesServiceNodePort: c.GenericConfig.KubernetesServiceNodePort,
|
KubernetesServiceNodePort: c.KubernetesServiceNodePort,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ func (c *Controller) Start() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
repairClusterIPs := servicecontroller.NewRepair(c.ServiceClusterIPInterval, c.ServiceRegistry, c.ServiceClusterIPRange, c.ServiceClusterIPRegistry)
|
repairClusterIPs := servicecontroller.NewRepair(c.ServiceClusterIPInterval, c.ServiceRegistry, &c.ServiceClusterIPRange, c.ServiceClusterIPRegistry)
|
||||||
repairNodePorts := portallocatorcontroller.NewRepair(c.ServiceNodePortInterval, c.ServiceRegistry, c.ServiceNodePortRange, c.ServiceNodePortRegistry)
|
repairNodePorts := portallocatorcontroller.NewRepair(c.ServiceNodePortInterval, c.ServiceRegistry, c.ServiceNodePortRange, c.ServiceNodePortRegistry)
|
||||||
|
|
||||||
// run all of the controllers once prior to returning from Start.
|
// run all of the controllers once prior to returning from Start.
|
||||||
|
@ -18,8 +18,10 @@ package master
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@ -37,9 +39,11 @@ import (
|
|||||||
storageapiv1beta1 "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
|
storageapiv1beta1 "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver"
|
"k8s.io/kubernetes/pkg/genericapiserver"
|
||||||
|
"k8s.io/kubernetes/pkg/genericapiserver/options"
|
||||||
"k8s.io/kubernetes/pkg/healthz"
|
"k8s.io/kubernetes/pkg/healthz"
|
||||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||||
"k8s.io/kubernetes/pkg/master/thirdparty"
|
"k8s.io/kubernetes/pkg/master/thirdparty"
|
||||||
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic/registry"
|
"k8s.io/kubernetes/pkg/registry/generic/registry"
|
||||||
@ -84,6 +88,38 @@ type Config struct {
|
|||||||
EnableUISupport bool
|
EnableUISupport bool
|
||||||
EnableLogsSupport bool
|
EnableLogsSupport bool
|
||||||
ProxyTransport http.RoundTripper
|
ProxyTransport http.RoundTripper
|
||||||
|
|
||||||
|
// Values to build the IP addresses used by discovery
|
||||||
|
// The range of IPs to be assigned to services with type=ClusterIP or greater
|
||||||
|
ServiceIPRange net.IPNet
|
||||||
|
// The IP address for the GenericAPIServer service (must be inside ServiceIPRange)
|
||||||
|
APIServerServiceIP net.IP
|
||||||
|
// Port for the apiserver service.
|
||||||
|
APIServerServicePort int
|
||||||
|
|
||||||
|
// TODO, we can probably group service related items into a substruct to make it easier to configure
|
||||||
|
// the API server items and `Extra*` fields likely fit nicely together.
|
||||||
|
|
||||||
|
// The range of ports to be assigned to services with type=NodePort or greater
|
||||||
|
ServiceNodePortRange utilnet.PortRange
|
||||||
|
// Additional ports to be exposed on the GenericAPIServer service
|
||||||
|
// extraServicePorts is injectable in the event that more ports
|
||||||
|
// (other than the default 443/tcp) are exposed on the GenericAPIServer
|
||||||
|
// and those ports need to be load balanced by the GenericAPIServer
|
||||||
|
// service because this pkg is linked by out-of-tree projects
|
||||||
|
// like openshift which want to use the GenericAPIServer but also do
|
||||||
|
// more stuff.
|
||||||
|
ExtraServicePorts []api.ServicePort
|
||||||
|
// Additional ports to be exposed on the GenericAPIServer endpoints
|
||||||
|
// Port names should align with ports defined in ExtraServicePorts
|
||||||
|
ExtraEndpointPorts []api.EndpointPort
|
||||||
|
// If non-zero, the "kubernetes" services uses this port as NodePort.
|
||||||
|
// TODO(sttts): move into master
|
||||||
|
KubernetesServiceNodePort int
|
||||||
|
|
||||||
|
// Number of masters running; all masters must be started with the
|
||||||
|
// same value for this field. (Numbers > 1 currently untested.)
|
||||||
|
MasterCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
// EndpointReconcilerConfig holds the endpoint reconciler and endpoint reconciliation interval to be
|
// EndpointReconcilerConfig holds the endpoint reconciler and endpoint reconciliation interval to be
|
||||||
@ -106,6 +142,31 @@ type completedConfig struct {
|
|||||||
func (c *Config) Complete() completedConfig {
|
func (c *Config) Complete() completedConfig {
|
||||||
c.GenericConfig.Complete()
|
c.GenericConfig.Complete()
|
||||||
|
|
||||||
|
serviceIPRange, apiServerServiceIP, err := genericapiserver.DefaultServiceIPRange(c.ServiceIPRange)
|
||||||
|
if err != nil {
|
||||||
|
glog.Fatalf("Error determining service IP ranges: %v", err)
|
||||||
|
}
|
||||||
|
if c.ServiceIPRange.IP == nil {
|
||||||
|
c.ServiceIPRange = serviceIPRange
|
||||||
|
}
|
||||||
|
if c.APIServerServiceIP == nil {
|
||||||
|
c.APIServerServiceIP = apiServerServiceIP
|
||||||
|
}
|
||||||
|
|
||||||
|
discoveryAddresses := genericapiserver.DefaultDiscoveryAddresses{DefaultAddress: c.GenericConfig.ExternalAddress}
|
||||||
|
discoveryAddresses.DiscoveryCIDRRules = append(discoveryAddresses.DiscoveryCIDRRules,
|
||||||
|
genericapiserver.DiscoveryCIDRRule{IPRange: c.ServiceIPRange, Address: net.JoinHostPort(c.APIServerServiceIP.String(), strconv.Itoa(c.APIServerServicePort))})
|
||||||
|
c.GenericConfig.DiscoveryAddresses = discoveryAddresses
|
||||||
|
|
||||||
|
if c.ServiceNodePortRange.Size == 0 {
|
||||||
|
// TODO: Currently no way to specify an empty range (do we need to allow this?)
|
||||||
|
// We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE)
|
||||||
|
// but then that breaks the strict nestedness of ServiceType.
|
||||||
|
// Review post-v1
|
||||||
|
c.ServiceNodePortRange = options.DefaultServiceNodePortRange
|
||||||
|
glog.Infof("Node port range unspecified. Defaulting to %v.", c.ServiceNodePortRange)
|
||||||
|
}
|
||||||
|
|
||||||
// enable swagger UI only if general UI support is on
|
// enable swagger UI only if general UI support is on
|
||||||
c.GenericConfig.EnableSwaggerUI = c.GenericConfig.EnableSwaggerUI && c.EnableUISupport
|
c.GenericConfig.EnableSwaggerUI = c.GenericConfig.EnableSwaggerUI && c.EnableUISupport
|
||||||
|
|
||||||
@ -116,7 +177,7 @@ func (c *Config) Complete() completedConfig {
|
|||||||
if c.EndpointReconcilerConfig.Reconciler == nil {
|
if c.EndpointReconcilerConfig.Reconciler == nil {
|
||||||
// use a default endpoint reconciler if nothing is set
|
// use a default endpoint reconciler if nothing is set
|
||||||
endpointClient := coreclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
|
endpointClient := coreclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
|
||||||
c.EndpointReconcilerConfig.Reconciler = NewMasterCountEndpointReconciler(c.GenericConfig.MasterCount, endpointClient)
|
c.EndpointReconcilerConfig.Reconciler = NewMasterCountEndpointReconciler(c.MasterCount, endpointClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this has always been hardcoded true in the past
|
// this has always been hardcoded true in the past
|
||||||
@ -170,13 +231,13 @@ func (c completedConfig) New() (*Master, error) {
|
|||||||
// install legacy rest storage
|
// install legacy rest storage
|
||||||
if c.GenericConfig.APIResourceConfigSource.AnyResourcesForVersionEnabled(apiv1.SchemeGroupVersion) {
|
if c.GenericConfig.APIResourceConfigSource.AnyResourcesForVersionEnabled(apiv1.SchemeGroupVersion) {
|
||||||
legacyRESTStorageProvider := corerest.LegacyRESTStorageProvider{
|
legacyRESTStorageProvider := corerest.LegacyRESTStorageProvider{
|
||||||
StorageFactory: c.StorageFactory,
|
StorageFactory: c.StorageFactory,
|
||||||
ProxyTransport: c.ProxyTransport,
|
ProxyTransport: c.ProxyTransport,
|
||||||
KubeletClientConfig: c.KubeletClientConfig,
|
KubeletClientConfig: c.KubeletClientConfig,
|
||||||
EventTTL: c.EventTTL,
|
EventTTL: c.EventTTL,
|
||||||
ServiceClusterIPRange: c.GenericConfig.ServiceClusterIPRange,
|
ServiceIPRange: c.ServiceIPRange,
|
||||||
ServiceNodePortRange: c.GenericConfig.ServiceNodePortRange,
|
ServiceNodePortRange: c.ServiceNodePortRange,
|
||||||
LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
|
LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
|
||||||
}
|
}
|
||||||
m.InstallLegacyAPI(c.Config, restOptionsFactory.NewFor, legacyRESTStorageProvider)
|
m.InstallLegacyAPI(c.Config, restOptionsFactory.NewFor, legacyRESTStorageProvider)
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,9 @@ func setUp(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.
|
|||||||
server, storageConfig := etcdtesting.NewUnsecuredEtcd3TestClientServer(t)
|
server, storageConfig := etcdtesting.NewUnsecuredEtcd3TestClientServer(t)
|
||||||
|
|
||||||
config := &Config{
|
config := &Config{
|
||||||
GenericConfig: genericapiserver.NewConfig(),
|
GenericConfig: genericapiserver.NewConfig(),
|
||||||
|
APIServerServicePort: 443,
|
||||||
|
MasterCount: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceEncoding := genericapiserver.NewDefaultResourceEncodingConfig()
|
resourceEncoding := genericapiserver.NewDefaultResourceEncodingConfig()
|
||||||
@ -142,16 +144,6 @@ func newLimitedMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Confi
|
|||||||
return master, etcdserver, config, assert
|
return master, etcdserver, config, assert
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestNew verifies that the New function returns a Master
|
|
||||||
// using the configuration properly.
|
|
||||||
func TestNew(t *testing.T) {
|
|
||||||
master, etcdserver, _, assert := newMaster(t)
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
|
|
||||||
// these values get defaulted
|
|
||||||
assert.Equal(master.GenericAPIServer.MasterCount, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestVersion tests /version
|
// TestVersion tests /version
|
||||||
func TestVersion(t *testing.T) {
|
func TestVersion(t *testing.T) {
|
||||||
s, etcdserver, _, _ := newMaster(t)
|
s, etcdserver, _, _ := newMaster(t)
|
||||||
|
@ -75,9 +75,9 @@ type LegacyRESTStorageProvider struct {
|
|||||||
KubeletClientConfig kubeletclient.KubeletClientConfig
|
KubeletClientConfig kubeletclient.KubeletClientConfig
|
||||||
EventTTL time.Duration
|
EventTTL time.Duration
|
||||||
|
|
||||||
// ServiceClusterIPRange is used to build cluster IPs for discovery.
|
// ServiceIPRange is used to build cluster IPs for discovery.
|
||||||
ServiceClusterIPRange *net.IPNet
|
ServiceIPRange net.IPNet
|
||||||
ServiceNodePortRange utilnet.PortRange
|
ServiceNodePortRange utilnet.PortRange
|
||||||
|
|
||||||
LoopbackClientConfig *restclient.Config
|
LoopbackClientConfig *restclient.Config
|
||||||
}
|
}
|
||||||
@ -154,9 +154,9 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter generi
|
|||||||
restStorage.ServiceRegistry = service.NewRegistry(serviceRESTStorage)
|
restStorage.ServiceRegistry = service.NewRegistry(serviceRESTStorage)
|
||||||
|
|
||||||
var serviceClusterIPRegistry rangeallocation.RangeRegistry
|
var serviceClusterIPRegistry rangeallocation.RangeRegistry
|
||||||
serviceClusterIPRange := c.ServiceClusterIPRange
|
serviceClusterIPRange := c.ServiceIPRange
|
||||||
if serviceClusterIPRange == nil {
|
if serviceClusterIPRange.IP == nil {
|
||||||
return LegacyRESTStorage{}, genericapiserver.APIGroupInfo{}, fmt.Errorf("service clusterIPRange is nil")
|
return LegacyRESTStorage{}, genericapiserver.APIGroupInfo{}, fmt.Errorf("service clusterIPRange is missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceStorageConfig, err := c.StorageFactory.NewConfig(api.Resource("services"))
|
serviceStorageConfig, err := c.StorageFactory.NewConfig(api.Resource("services"))
|
||||||
@ -164,7 +164,7 @@ func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(restOptionsGetter generi
|
|||||||
return LegacyRESTStorage{}, genericapiserver.APIGroupInfo{}, err
|
return LegacyRESTStorage{}, genericapiserver.APIGroupInfo{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceClusterIPAllocator := ipallocator.NewAllocatorCIDRRange(serviceClusterIPRange, func(max int, rangeSpec string) allocator.Interface {
|
ServiceClusterIPAllocator := ipallocator.NewAllocatorCIDRRange(&serviceClusterIPRange, func(max int, rangeSpec string) allocator.Interface {
|
||||||
mem := allocator.NewAllocationMap(max, rangeSpec)
|
mem := allocator.NewAllocationMap(max, rangeSpec)
|
||||||
// TODO etcdallocator package to return a storage interface via the storageFactory
|
// TODO etcdallocator package to return a storage interface via the storageFactory
|
||||||
etcd := etcdallocator.NewEtcd(mem, "/ranges/serviceips", api.Resource("serviceipallocations"), serviceStorageConfig)
|
etcd := etcdallocator.NewEtcd(mem, "/ranges/serviceips", api.Resource("serviceipallocations"), serviceStorageConfig)
|
||||||
|
@ -359,6 +359,8 @@ func NewMasterConfig() *master.Config {
|
|||||||
EnableCoreControllers: true,
|
EnableCoreControllers: true,
|
||||||
EnableWatchCache: true,
|
EnableWatchCache: true,
|
||||||
KubeletClientConfig: kubeletclient.KubeletClientConfig{Port: 10250},
|
KubeletClientConfig: kubeletclient.KubeletClientConfig{Port: 10250},
|
||||||
|
APIServerServicePort: 443,
|
||||||
|
MasterCount: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,11 +425,11 @@ func TestMasterService(t *testing.T) {
|
|||||||
|
|
||||||
func TestServiceAlloc(t *testing.T) {
|
func TestServiceAlloc(t *testing.T) {
|
||||||
cfg := framework.NewIntegrationTestMasterConfig()
|
cfg := framework.NewIntegrationTestMasterConfig()
|
||||||
_, cidr, err := net.ParseCIDR("192.168.0.0/30")
|
_, cidr, err := net.ParseCIDR("192.168.0.0/29")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("bad cidr: %v", err)
|
t.Fatalf("bad cidr: %v", err)
|
||||||
}
|
}
|
||||||
cfg.GenericConfig.ServiceClusterIPRange = cidr
|
cfg.ServiceIPRange = *cidr
|
||||||
_, s := framework.RunAMaster(cfg)
|
_, s := framework.RunAMaster(cfg)
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
@ -460,13 +460,15 @@ func TestServiceAlloc(t *testing.T) {
|
|||||||
t.Fatalf("creating kubernetes service timed out")
|
t.Fatalf("creating kubernetes service timed out")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a service.
|
// make 5 more services to take up all IPs
|
||||||
if _, err := client.Core().Services(api.NamespaceDefault).Create(svc(1)); err != nil {
|
for i := 0; i < 5; i++ {
|
||||||
t.Fatalf("got unexpected error: %v", err)
|
if _, err := client.Core().Services(api.NamespaceDefault).Create(svc(i)); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a second service. It will fail because we're out of cluster IPs
|
// Make another service. It will fail because we're out of cluster IPs
|
||||||
if _, err := client.Core().Services(api.NamespaceDefault).Create(svc(2)); err != nil {
|
if _, err := client.Core().Services(api.NamespaceDefault).Create(svc(8)); err != nil {
|
||||||
if !strings.Contains(err.Error(), "range is full") {
|
if !strings.Contains(err.Error(), "range is full") {
|
||||||
t.Errorf("unexpected error text: %v", err)
|
t.Errorf("unexpected error text: %v", err)
|
||||||
}
|
}
|
||||||
@ -488,7 +490,7 @@ func TestServiceAlloc(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This time creating the second service should work.
|
// This time creating the second service should work.
|
||||||
if _, err := client.Core().Services(api.NamespaceDefault).Create(svc(2)); err != nil {
|
if _, err := client.Core().Services(api.NamespaceDefault).Create(svc(8)); err != nil {
|
||||||
t.Fatalf("got unexpected error: %v", err)
|
t.Fatalf("got unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user