Add EndpointReconcilerConfig to master Config

Add EndpointReconcilerConfig to master Config to allow downstream integrators to customize the reconciler
and reconciliation interval when starting a customized master.
pull/6/head
Andy Goldstein 2016-06-24 11:25:46 -04:00
parent eedc438da9
commit b55cede866
3 changed files with 56 additions and 12 deletions

View File

@ -115,19 +115,33 @@ import (
"k8s.io/kubernetes/pkg/registry/service/portallocator" "k8s.io/kubernetes/pkg/registry/service/portallocator"
) )
const (
// DefaultEndpointReconcilerInterval is the default amount of time for how often the endpoints for
// the kubernetes Service are reconciled.
DefaultEndpointReconcilerInterval = 10 * time.Second
)
type Config struct { type Config struct {
*genericapiserver.Config *genericapiserver.Config
EnableCoreControllers bool EnableCoreControllers bool
DeleteCollectionWorkers int EndpointReconcilerConfig EndpointReconcilerConfig
EventTTL time.Duration DeleteCollectionWorkers int
KubeletClient kubeletclient.KubeletClient EventTTL time.Duration
KubeletClient kubeletclient.KubeletClient
// Used to start and monitor tunneling // Used to start and monitor tunneling
Tunneler genericapiserver.Tunneler Tunneler genericapiserver.Tunneler
disableThirdPartyControllerForTesting bool disableThirdPartyControllerForTesting bool
} }
// EndpointReconcilerConfig holds the endpoint reconciler and endpoint reconciliation interval to be
// used by the master.
type EndpointReconcilerConfig struct {
Reconciler EndpointReconciler
Interval time.Duration
}
// Master contains state for a Kubernetes cluster master/api server. // Master contains state for a Kubernetes cluster master/api server.
type Master struct { type Master struct {
*genericapiserver.GenericAPIServer *genericapiserver.GenericAPIServer
@ -193,7 +207,7 @@ func New(c *Config) (*Master, error) {
// TODO: Attempt clean shutdown? // TODO: Attempt clean shutdown?
if m.enableCoreControllers { if m.enableCoreControllers {
m.NewBootstrapController().Start() m.NewBootstrapController(c.EndpointReconcilerConfig).Start()
} }
return m, nil return m, nil
@ -585,14 +599,27 @@ func (m *Master) initV1ResourcesStorage(c *Config) {
} }
} }
// NewBootstrapController returns a controller for watching the core capabilities of the master. // NewBootstrapController returns a controller for watching the core capabilities of the master. If
func (m *Master) NewBootstrapController() *Controller { // endpointReconcilerConfig.Interval is 0, the default value of DefaultEndpointReconcilerInterval
// will be used instead. If endpointReconcilerConfig.Reconciler is nil, the default
// MasterCountEndpointReconciler will be used.
func (m *Master) NewBootstrapController(endpointReconcilerConfig EndpointReconcilerConfig) *Controller {
if endpointReconcilerConfig.Interval == 0 {
endpointReconcilerConfig.Interval = DefaultEndpointReconcilerInterval
}
if endpointReconcilerConfig.Reconciler == nil {
// use a default endpoint reconciler if nothing is set
// m.endpointRegistry is set via m.InstallAPIs -> m.initV1ResourcesStorage
endpointReconcilerConfig.Reconciler = NewMasterCountEndpointReconciler(m.MasterCount, m.endpointRegistry)
}
return &Controller{ return &Controller{
NamespaceRegistry: m.namespaceRegistry, NamespaceRegistry: m.namespaceRegistry,
ServiceRegistry: m.serviceRegistry, ServiceRegistry: m.serviceRegistry,
EndpointReconciler: NewMasterCountEndpointReconciler(m.MasterCount, m.endpointRegistry), EndpointReconciler: endpointReconcilerConfig.Reconciler,
EndpointInterval: 10 * time.Second, EndpointInterval: endpointReconcilerConfig.Interval,
SystemNamespaces: []string{api.NamespaceSystem}, SystemNamespaces: []string{api.NamespaceSystem},
SystemNamespacesInterval: 1 * time.Minute, SystemNamespacesInterval: 1 * time.Minute,

View File

@ -28,6 +28,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
"time"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
@ -237,6 +238,12 @@ func TestFindExternalAddress(t *testing.T) {
assert.Error(err, "expected findExternalAddress to fail on a node with missing ip information") assert.Error(err, "expected findExternalAddress to fail on a node with missing ip information")
} }
type fakeEndpointReconciler struct{}
func (*fakeEndpointReconciler) ReconcileEndpoints(serviceName string, ip net.IP, endpointPorts []api.EndpointPort, reconcilePorts bool) error {
return nil
}
// TestNewBootstrapController verifies master fields are properly copied into controller // TestNewBootstrapController verifies master fields are properly copied into controller
func TestNewBootstrapController(t *testing.T) { func TestNewBootstrapController(t *testing.T) {
// Tests a subset of inputs to ensure they are set properly in the controller // Tests a subset of inputs to ensure they are set properly in the controller
@ -254,14 +261,24 @@ func TestNewBootstrapController(t *testing.T) {
master.ServiceReadWritePort = 1000 master.ServiceReadWritePort = 1000
master.PublicReadWritePort = 1010 master.PublicReadWritePort = 1010
controller := master.NewBootstrapController() // test with an empty EndpointReconcilerConfig to ensure the defaults are applied
controller := master.NewBootstrapController(EndpointReconcilerConfig{})
assert.Equal(controller.NamespaceRegistry, master.namespaceRegistry) assert.Equal(controller.NamespaceRegistry, master.namespaceRegistry)
assert.Equal(controller.EndpointReconciler, NewMasterCountEndpointReconciler(master.MasterCount, master.endpointRegistry)) assert.Equal(controller.EndpointReconciler, NewMasterCountEndpointReconciler(master.MasterCount, master.endpointRegistry))
assert.Equal(controller.EndpointInterval, DefaultEndpointReconcilerInterval)
assert.Equal(controller.ServiceRegistry, master.serviceRegistry) assert.Equal(controller.ServiceRegistry, master.serviceRegistry)
assert.Equal(controller.ServiceNodePortRange, portRange) assert.Equal(controller.ServiceNodePortRange, portRange)
assert.Equal(controller.ServicePort, master.ServiceReadWritePort) assert.Equal(controller.ServicePort, master.ServiceReadWritePort)
assert.Equal(controller.PublicServicePort, master.PublicReadWritePort) assert.Equal(controller.PublicServicePort, master.PublicReadWritePort)
// test with a filled-in EndpointReconcilerConfig to make sure its values are used
controller = master.NewBootstrapController(EndpointReconcilerConfig{
Reconciler: &fakeEndpointReconciler{},
Interval: 5 * time.Second,
})
assert.Equal(controller.EndpointReconciler, &fakeEndpointReconciler{})
assert.Equal(controller.EndpointInterval, 5*time.Second)
} }
// TestControllerServicePorts verifies master extraServicePorts are // TestControllerServicePorts verifies master extraServicePorts are
@ -289,7 +306,7 @@ func TestControllerServicePorts(t *testing.T) {
}, },
} }
controller := master.NewBootstrapController() controller := master.NewBootstrapController(EndpointReconcilerConfig{})
assert.Equal(int32(1000), controller.ExtraServicePorts[0].Port) assert.Equal(int32(1000), controller.ExtraServicePorts[0].Port)
assert.Equal(int32(1010), controller.ExtraServicePorts[1].Port) assert.Equal(int32(1010), controller.ExtraServicePorts[1].Port)

View File

@ -37,5 +37,5 @@ func TestMasterExportsSymbols(t *testing.T) {
m := &master.Master{ m := &master.Master{
GenericAPIServer: &genericapiserver.GenericAPIServer{}, GenericAPIServer: &genericapiserver.GenericAPIServer{},
} }
_ = (m).NewBootstrapController() _ = (m).NewBootstrapController(master.EndpointReconcilerConfig{})
} }