Commit 4b07f80d authored by Dan Williams's avatar Dan Williams

proxy: consolidate ServicesHandler/EndpointsHandler into ProxyProvider

Proxies should be able to cleanly figure out when endpoints have been synced, so make all ProxyProviders also implement EndpointsHandler and pass those through to loadbalancers when required.
parent 92a20761
...@@ -501,8 +501,6 @@ type ProxyServer struct { ...@@ -501,8 +501,6 @@ type ProxyServer struct {
OOMScoreAdj *int32 OOMScoreAdj *int32
ResourceContainer string ResourceContainer string
ConfigSyncPeriod time.Duration ConfigSyncPeriod time.Duration
ServiceEventHandler config.ServiceHandler
EndpointsEventHandler config.EndpointsHandler
HealthzServer *healthcheck.HealthzServer HealthzServer *healthcheck.HealthzServer
} }
...@@ -657,11 +655,11 @@ func (s *ProxyServer) Run() error { ...@@ -657,11 +655,11 @@ func (s *ProxyServer) Run() error {
// only notify on changes, and the initial update (on process start) may be lost if no handlers // only notify on changes, and the initial update (on process start) may be lost if no handlers
// are registered yet. // are registered yet.
serviceConfig := config.NewServiceConfig(informerFactory.Core().V1().Services(), s.ConfigSyncPeriod) serviceConfig := config.NewServiceConfig(informerFactory.Core().V1().Services(), s.ConfigSyncPeriod)
serviceConfig.RegisterEventHandler(s.ServiceEventHandler) serviceConfig.RegisterEventHandler(s.Proxier)
go serviceConfig.Run(wait.NeverStop) go serviceConfig.Run(wait.NeverStop)
endpointsConfig := config.NewEndpointsConfig(informerFactory.Core().V1().Endpoints(), s.ConfigSyncPeriod) endpointsConfig := config.NewEndpointsConfig(informerFactory.Core().V1().Endpoints(), s.ConfigSyncPeriod)
endpointsConfig.RegisterEventHandler(s.EndpointsEventHandler) endpointsConfig.RegisterEventHandler(s.Proxier)
go endpointsConfig.Run(wait.NeverStop) go endpointsConfig.Run(wait.NeverStop)
// This has to start after the calls to NewServiceConfig and NewEndpointsConfig because those // This has to start after the calls to NewServiceConfig and NewEndpointsConfig because those
......
...@@ -33,7 +33,6 @@ import ( ...@@ -33,7 +33,6 @@ import (
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/kubernetes/pkg/proxy" "k8s.io/kubernetes/pkg/proxy"
proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config" proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config"
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
"k8s.io/kubernetes/pkg/proxy/healthcheck" "k8s.io/kubernetes/pkg/proxy/healthcheck"
"k8s.io/kubernetes/pkg/proxy/iptables" "k8s.io/kubernetes/pkg/proxy/iptables"
"k8s.io/kubernetes/pkg/proxy/ipvs" "k8s.io/kubernetes/pkg/proxy/ipvs"
...@@ -135,8 +134,6 @@ func newProxyServer( ...@@ -135,8 +134,6 @@ func newProxyServer(
} }
var proxier proxy.ProxyProvider var proxier proxy.ProxyProvider
var serviceEventHandler proxyconfig.ServiceHandler
var endpointsEventHandler proxyconfig.EndpointsHandler
proxyMode := getProxyMode(string(config.Mode), iptInterface, kernelHandler, ipsetInterface, iptables.LinuxKernelCompatTester{}) proxyMode := getProxyMode(string(config.Mode), iptInterface, kernelHandler, ipsetInterface, iptables.LinuxKernelCompatTester{})
nodeIP := net.ParseIP(config.BindAddress) nodeIP := net.ParseIP(config.BindAddress)
...@@ -151,7 +148,7 @@ func newProxyServer( ...@@ -151,7 +148,7 @@ func newProxyServer(
} }
// TODO this has side effects that should only happen when Run() is invoked. // TODO this has side effects that should only happen when Run() is invoked.
proxierIPTables, err := iptables.NewProxier( proxier, err = iptables.NewProxier(
iptInterface, iptInterface,
utilsysctl.New(), utilsysctl.New(),
execer, execer,
...@@ -170,12 +167,9 @@ func newProxyServer( ...@@ -170,12 +167,9 @@ func newProxyServer(
return nil, fmt.Errorf("unable to create proxier: %v", err) return nil, fmt.Errorf("unable to create proxier: %v", err)
} }
metrics.RegisterMetrics() metrics.RegisterMetrics()
proxier = proxierIPTables
serviceEventHandler = proxierIPTables
endpointsEventHandler = proxierIPTables
} else if proxyMode == proxyModeIPVS { } else if proxyMode == proxyModeIPVS {
klog.V(0).Info("Using ipvs Proxier.") klog.V(0).Info("Using ipvs Proxier.")
proxierIPVS, err := ipvs.NewProxier( proxier, err = ipvs.NewProxier(
iptInterface, iptInterface,
ipvsInterface, ipvsInterface,
ipsetInterface, ipsetInterface,
...@@ -199,20 +193,12 @@ func newProxyServer( ...@@ -199,20 +193,12 @@ func newProxyServer(
return nil, fmt.Errorf("unable to create proxier: %v", err) return nil, fmt.Errorf("unable to create proxier: %v", err)
} }
metrics.RegisterMetrics() metrics.RegisterMetrics()
proxier = proxierIPVS
serviceEventHandler = proxierIPVS
endpointsEventHandler = proxierIPVS
} else { } else {
klog.V(0).Info("Using userspace Proxier.") klog.V(0).Info("Using userspace Proxier.")
// This is a proxy.LoadBalancer which NewProxier needs but has methods we don't need for
// our config.EndpointsConfigHandler.
loadBalancer := userspace.NewLoadBalancerRR()
// set EndpointsConfigHandler to our loadBalancer
endpointsEventHandler = loadBalancer
// TODO this has side effects that should only happen when Run() is invoked. // TODO this has side effects that should only happen when Run() is invoked.
proxierUserspace, err := userspace.NewProxier( proxier, err = userspace.NewProxier(
loadBalancer, userspace.NewLoadBalancerRR(),
net.ParseIP(config.BindAddress), net.ParseIP(config.BindAddress),
iptInterface, iptInterface,
execer, execer,
...@@ -225,8 +211,6 @@ func newProxyServer( ...@@ -225,8 +211,6 @@ func newProxyServer(
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err) return nil, fmt.Errorf("unable to create proxier: %v", err)
} }
serviceEventHandler = proxierUserspace
proxier = proxierUserspace
} }
iptInterface.AddReloadFunc(proxier.Sync) iptInterface.AddReloadFunc(proxier.Sync)
...@@ -250,8 +234,6 @@ func newProxyServer( ...@@ -250,8 +234,6 @@ func newProxyServer(
OOMScoreAdj: config.OOMScoreAdj, OOMScoreAdj: config.OOMScoreAdj,
ResourceContainer: config.ResourceContainer, ResourceContainer: config.ResourceContainer,
ConfigSyncPeriod: config.ConfigSyncPeriod.Duration, ConfigSyncPeriod: config.ConfigSyncPeriod.Duration,
ServiceEventHandler: serviceEventHandler,
EndpointsEventHandler: endpointsEventHandler,
HealthzServer: healthzServer, HealthzServer: healthzServer,
}, nil }, nil
} }
......
...@@ -33,7 +33,6 @@ import ( ...@@ -33,7 +33,6 @@ import (
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/kubernetes/pkg/proxy" "k8s.io/kubernetes/pkg/proxy"
proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config" proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config"
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
"k8s.io/kubernetes/pkg/proxy/healthcheck" "k8s.io/kubernetes/pkg/proxy/healthcheck"
"k8s.io/kubernetes/pkg/proxy/winkernel" "k8s.io/kubernetes/pkg/proxy/winkernel"
"k8s.io/kubernetes/pkg/proxy/winuserspace" "k8s.io/kubernetes/pkg/proxy/winuserspace"
...@@ -94,13 +93,11 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi ...@@ -94,13 +93,11 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi
} }
var proxier proxy.ProxyProvider var proxier proxy.ProxyProvider
var serviceEventHandler proxyconfig.ServiceHandler
var endpointsEventHandler proxyconfig.EndpointsHandler
proxyMode := getProxyMode(string(config.Mode), winkernel.WindowsKernelCompatTester{}) proxyMode := getProxyMode(string(config.Mode), winkernel.WindowsKernelCompatTester{})
if proxyMode == proxyModeKernelspace { if proxyMode == proxyModeKernelspace {
klog.V(0).Info("Using Kernelspace Proxier.") klog.V(0).Info("Using Kernelspace Proxier.")
proxierKernelspace, err := winkernel.NewProxier( proxier, err = winkernel.NewProxier(
config.IPTables.SyncPeriod.Duration, config.IPTables.SyncPeriod.Duration,
config.IPTables.MinSyncPeriod.Duration, config.IPTables.MinSyncPeriod.Duration,
config.IPTables.MasqueradeAll, config.IPTables.MasqueradeAll,
...@@ -115,23 +112,14 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi ...@@ -115,23 +112,14 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err) return nil, fmt.Errorf("unable to create proxier: %v", err)
} }
proxier = proxierKernelspace
endpointsEventHandler = proxierKernelspace
serviceEventHandler = proxierKernelspace
} else { } else {
klog.V(0).Info("Using userspace Proxier.") klog.V(0).Info("Using userspace Proxier.")
execer := exec.New() execer := exec.New()
var netshInterface utilnetsh.Interface var netshInterface utilnetsh.Interface
netshInterface = utilnetsh.New(execer) netshInterface = utilnetsh.New(execer)
// This is a proxy.LoadBalancer which NewProxier needs but has methods we don't need for proxier, err = winuserspace.NewProxier(
// our config.EndpointsConfigHandler. winuserspace.NewLoadBalancerRR(),
loadBalancer := winuserspace.NewLoadBalancerRR()
// set EndpointsConfigHandler to our loadBalancer
endpointsEventHandler = loadBalancer
proxierUserspace, err := winuserspace.NewProxier(
loadBalancer,
net.ParseIP(config.BindAddress), net.ParseIP(config.BindAddress),
netshInterface, netshInterface,
*utilnet.ParsePortRangeOrDie(config.PortRange), *utilnet.ParsePortRangeOrDie(config.PortRange),
...@@ -142,8 +130,6 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi ...@@ -142,8 +130,6 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err) return nil, fmt.Errorf("unable to create proxier: %v", err)
} }
proxier = proxierUserspace
serviceEventHandler = proxierUserspace
} }
return &ProxyServer{ return &ProxyServer{
...@@ -159,8 +145,6 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi ...@@ -159,8 +145,6 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExi
OOMScoreAdj: config.OOMScoreAdj, OOMScoreAdj: config.OOMScoreAdj,
ResourceContainer: config.ResourceContainer, ResourceContainer: config.ResourceContainer,
ConfigSyncPeriod: config.ConfigSyncPeriod.Duration, ConfigSyncPeriod: config.ConfigSyncPeriod.Duration,
ServiceEventHandler: serviceEventHandler,
EndpointsEventHandler: endpointsEventHandler,
HealthzServer: healthzServer, HealthzServer: healthzServer,
}, nil }, nil
} }
......
...@@ -26,7 +26,6 @@ go_library( ...@@ -26,7 +26,6 @@ go_library(
"//pkg/kubelet/dockershim:go_default_library", "//pkg/kubelet/dockershim:go_default_library",
"//pkg/kubelet/types:go_default_library", "//pkg/kubelet/types:go_default_library",
"//pkg/proxy:go_default_library", "//pkg/proxy:go_default_library",
"//pkg/proxy/config:go_default_library",
"//pkg/proxy/iptables:go_default_library", "//pkg/proxy/iptables:go_default_library",
"//pkg/util/iptables:go_default_library", "//pkg/util/iptables:go_default_library",
"//pkg/util/mount:go_default_library", "//pkg/util/mount:go_default_library",
......
...@@ -27,7 +27,6 @@ import ( ...@@ -27,7 +27,6 @@ import (
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
proxyapp "k8s.io/kubernetes/cmd/kube-proxy/app" proxyapp "k8s.io/kubernetes/cmd/kube-proxy/app"
"k8s.io/kubernetes/pkg/proxy" "k8s.io/kubernetes/pkg/proxy"
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
"k8s.io/kubernetes/pkg/proxy/iptables" "k8s.io/kubernetes/pkg/proxy/iptables"
utiliptables "k8s.io/kubernetes/pkg/util/iptables" utiliptables "k8s.io/kubernetes/pkg/util/iptables"
utilnode "k8s.io/kubernetes/pkg/util/node" utilnode "k8s.io/kubernetes/pkg/util/node"
...@@ -72,13 +71,12 @@ func NewHollowProxyOrDie( ...@@ -72,13 +71,12 @@ func NewHollowProxyOrDie(
) (*HollowProxy, error) { ) (*HollowProxy, error) {
// Create proxier and service/endpoint handlers. // Create proxier and service/endpoint handlers.
var proxier proxy.ProxyProvider var proxier proxy.ProxyProvider
var serviceHandler proxyconfig.ServiceHandler var err error
var endpointsHandler proxyconfig.EndpointsHandler
if useRealProxier { if useRealProxier {
// Real proxier with fake iptables, sysctl, etc underneath it. // Real proxier with fake iptables, sysctl, etc underneath it.
//var err error //var err error
proxierIPTables, err := iptables.NewProxier( proxier, err = iptables.NewProxier(
iptInterface, iptInterface,
sysctl, sysctl,
execer, execer,
...@@ -96,13 +94,8 @@ func NewHollowProxyOrDie( ...@@ -96,13 +94,8 @@ func NewHollowProxyOrDie(
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err) return nil, fmt.Errorf("unable to create proxier: %v", err)
} }
proxier = proxierIPTables
serviceHandler = proxierIPTables
endpointsHandler = proxierIPTables
} else { } else {
proxier = &FakeProxier{} proxier = &FakeProxier{}
serviceHandler = &FakeProxier{}
endpointsHandler = &FakeProxier{}
} }
// Create a Hollow Proxy instance. // Create a Hollow Proxy instance.
...@@ -125,8 +118,6 @@ func NewHollowProxyOrDie( ...@@ -125,8 +118,6 @@ func NewHollowProxyOrDie(
OOMScoreAdj: utilpointer.Int32Ptr(0), OOMScoreAdj: utilpointer.Int32Ptr(0),
ResourceContainer: "", ResourceContainer: "",
ConfigSyncPeriod: 30 * time.Second, ConfigSyncPeriod: 30 * time.Second,
ServiceEventHandler: serviceHandler,
EndpointsEventHandler: endpointsHandler,
}, },
}, nil }, nil
} }
......
...@@ -17,6 +17,7 @@ go_library( ...@@ -17,6 +17,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/proxy", importpath = "k8s.io/kubernetes/pkg/proxy",
deps = [ deps = [
"//pkg/api/v1/service:go_default_library", "//pkg/api/v1/service:go_default_library",
"//pkg/proxy/config:go_default_library",
"//pkg/proxy/util:go_default_library", "//pkg/proxy/util:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
......
...@@ -21,10 +21,14 @@ import ( ...@@ -21,10 +21,14 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/proxy/config"
) )
// ProxyProvider is the interface provided by proxier implementations. // ProxyProvider is the interface provided by proxier implementations.
type ProxyProvider interface { type ProxyProvider interface {
config.EndpointsHandler
config.ServiceHandler
// Sync immediately synchronizes the ProxyProvider's current state to proxy rules. // Sync immediately synchronizes the ProxyProvider's current state to proxy rules.
Sync() Sync()
// SyncLoop runs periodic work. // SyncLoop runs periodic work.
......
...@@ -21,6 +21,7 @@ go_library( ...@@ -21,6 +21,7 @@ go_library(
deps = [ deps = [
"//pkg/apis/core/v1/helper:go_default_library", "//pkg/apis/core/v1/helper:go_default_library",
"//pkg/proxy:go_default_library", "//pkg/proxy:go_default_library",
"//pkg/proxy/config:go_default_library",
"//pkg/proxy/util:go_default_library", "//pkg/proxy/util:go_default_library",
"//pkg/util/conntrack:go_default_library", "//pkg/util/conntrack:go_default_library",
"//pkg/util/iptables:go_default_library", "//pkg/util/iptables:go_default_library",
......
...@@ -19,6 +19,7 @@ package userspace ...@@ -19,6 +19,7 @@ package userspace
import ( import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/proxy" "k8s.io/kubernetes/pkg/proxy"
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
"net" "net"
) )
...@@ -31,4 +32,6 @@ type LoadBalancer interface { ...@@ -31,4 +32,6 @@ type LoadBalancer interface {
DeleteService(service proxy.ServicePortName) DeleteService(service proxy.ServicePortName)
CleanupStaleStickySessions(service proxy.ServicePortName) CleanupStaleStickySessions(service proxy.ServicePortName)
ServiceHasEndpoints(service proxy.ServicePortName) bool ServiceHasEndpoints(service proxy.ServicePortName) bool
proxyconfig.EndpointsHandler
} }
...@@ -526,6 +526,22 @@ func (proxier *Proxier) OnServiceDelete(service *v1.Service) { ...@@ -526,6 +526,22 @@ func (proxier *Proxier) OnServiceDelete(service *v1.Service) {
func (proxier *Proxier) OnServiceSynced() { func (proxier *Proxier) OnServiceSynced() {
} }
func (proxier *Proxier) OnEndpointsAdd(endpoints *v1.Endpoints) {
proxier.loadBalancer.OnEndpointsAdd(endpoints)
}
func (proxier *Proxier) OnEndpointsUpdate(oldEndpoints, endpoints *v1.Endpoints) {
proxier.loadBalancer.OnEndpointsUpdate(oldEndpoints, endpoints)
}
func (proxier *Proxier) OnEndpointsDelete(endpoints *v1.Endpoints) {
proxier.loadBalancer.OnEndpointsDelete(endpoints)
}
func (proxier *Proxier) OnEndpointsSynced() {
proxier.loadBalancer.OnEndpointsSynced()
}
func sameConfig(info *ServiceInfo, service *v1.Service, port *v1.ServicePort) bool { func sameConfig(info *ServiceInfo, service *v1.Service, port *v1.ServicePort) bool {
if info.protocol != port.Protocol || info.portal.port != int(port.Port) || info.nodePort != int(port.NodePort) { if info.protocol != port.Protocol || info.portal.port != int(port.Port) || info.nodePort != int(port.NodePort) {
return false return false
......
...@@ -19,6 +19,7 @@ go_library( ...@@ -19,6 +19,7 @@ go_library(
deps = [ deps = [
"//pkg/apis/core/v1/helper:go_default_library", "//pkg/apis/core/v1/helper:go_default_library",
"//pkg/proxy:go_default_library", "//pkg/proxy:go_default_library",
"//pkg/proxy/config:go_default_library",
"//pkg/util/ipconfig:go_default_library", "//pkg/util/ipconfig:go_default_library",
"//pkg/util/netsh:go_default_library", "//pkg/util/netsh:go_default_library",
"//pkg/util/slice:go_default_library", "//pkg/util/slice:go_default_library",
......
...@@ -19,6 +19,7 @@ package winuserspace ...@@ -19,6 +19,7 @@ package winuserspace
import ( import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/proxy" "k8s.io/kubernetes/pkg/proxy"
proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
"net" "net"
) )
...@@ -30,4 +31,6 @@ type LoadBalancer interface { ...@@ -30,4 +31,6 @@ type LoadBalancer interface {
NewService(service proxy.ServicePortName, sessionAffinityType v1.ServiceAffinity, stickyMaxAgeMinutes int) error NewService(service proxy.ServicePortName, sessionAffinityType v1.ServiceAffinity, stickyMaxAgeMinutes int) error
DeleteService(service proxy.ServicePortName) DeleteService(service proxy.ServicePortName)
CleanupStaleStickySessions(service proxy.ServicePortName) CleanupStaleStickySessions(service proxy.ServicePortName)
proxyconfig.EndpointsHandler
} }
...@@ -444,6 +444,22 @@ func (proxier *Proxier) OnServiceDelete(service *v1.Service) { ...@@ -444,6 +444,22 @@ func (proxier *Proxier) OnServiceDelete(service *v1.Service) {
func (proxier *Proxier) OnServiceSynced() { func (proxier *Proxier) OnServiceSynced() {
} }
func (proxier *Proxier) OnEndpointsAdd(endpoints *v1.Endpoints) {
proxier.loadBalancer.OnEndpointsAdd(endpoints)
}
func (proxier *Proxier) OnEndpointsUpdate(oldEndpoints, endpoints *v1.Endpoints) {
proxier.loadBalancer.OnEndpointsUpdate(oldEndpoints, endpoints)
}
func (proxier *Proxier) OnEndpointsDelete(endpoints *v1.Endpoints) {
proxier.loadBalancer.OnEndpointsDelete(endpoints)
}
func (proxier *Proxier) OnEndpointsSynced() {
proxier.loadBalancer.OnEndpointsSynced()
}
func sameConfig(info *serviceInfo, service *v1.Service, protocol v1.Protocol, listenPort int) bool { func sameConfig(info *serviceInfo, service *v1.Service, protocol v1.Protocol, listenPort int) bool {
return info.protocol == protocol && info.portal.port == listenPort && info.sessionAffinityType == service.Spec.SessionAffinity return info.protocol == protocol && info.portal.port == listenPort && info.sessionAffinityType == service.Spec.SessionAffinity
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment