diff --git a/cmd/kube-proxy/app/server.go b/cmd/kube-proxy/app/server.go index 50b9787f5ac..0d371adcca7 100644 --- a/cmd/kube-proxy/app/server.go +++ b/cmd/kube-proxy/app/server.go @@ -59,8 +59,8 @@ type ProxyServer struct { Recorder record.EventRecorder HostnameOverride string ForceUserspaceProxy bool - // Reference to this node. - nodeRef *api.ObjectReference + SyncPeriod time.Duration + nodeRef *api.ObjectReference // Reference to this node. } // NewProxyServer creates a new ProxyServer object with default parameters @@ -71,6 +71,7 @@ func NewProxyServer() *ProxyServer { HealthzBindAddress: net.ParseIP("127.0.0.1"), OOMScoreAdj: qos.KubeProxyOomScoreAdj, ResourceContainer: "/kube-proxy", + SyncPeriod: 5 * time.Second, } } @@ -86,6 +87,7 @@ func (s *ProxyServer) AddFlags(fs *pflag.FlagSet) { fs.Var(&s.PortRange, "proxy-port-range", "Range of host ports (beginPort-endPort, inclusive) that may be consumed in order to proxy service traffic. If unspecified (0-0) then ports will be randomly chosen.") fs.StringVar(&s.HostnameOverride, "hostname-override", s.HostnameOverride, "If non-empty, will use this string as identification instead of the actual hostname.") fs.BoolVar(&s.ForceUserspaceProxy, "legacy-userspace-proxy", true, "Use the legacy userspace proxy (instead of the pure iptables proxy).") + fs.DurationVar(&s.SyncPeriod, "iptables-sync-period", 5*time.Second, "How often iptables rules are refreshed (e.g. '5s', '1m', '2h22m'). Must be greater than 0.") } // Run runs the specified ProxyServer. This should never exit. @@ -157,7 +159,7 @@ func (s *ProxyServer) Run(_ []string) error { if !s.ForceUserspaceProxy && shouldUseIptables { glog.V(2).Info("Using iptables Proxier.") - proxierIptables, err := iptables.NewProxier(utiliptables.New(exec.New(), protocol)) + proxierIptables, err := iptables.NewProxier(utiliptables.New(exec.New(), protocol), s.SyncPeriod) if err != nil { glog.Fatalf("Unable to create proxier: %v", err) } @@ -171,7 +173,7 @@ func (s *ProxyServer) Run(_ []string) error { // set EndpointsConfigHandler to our loadBalancer endpointsHandler = loadBalancer - proxierUserspace, err := userspace.NewProxier(loadBalancer, s.BindAddress, utiliptables.New(exec.New(), protocol), s.PortRange) + proxierUserspace, err := userspace.NewProxier(loadBalancer, s.BindAddress, utiliptables.New(exec.New(), protocol), s.PortRange, s.SyncPeriod) if err != nil { glog.Fatalf("Unable to create proxer: %v", err) } diff --git a/hack/verify-flags/known-flags.txt b/hack/verify-flags/known-flags.txt index 57cf9439c03..ff0a0401efe 100644 --- a/hack/verify-flags/known-flags.txt +++ b/hack/verify-flags/known-flags.txt @@ -118,6 +118,7 @@ image-gc-low-threshold insecure-bind-address insecure-port insecure-skip-tls-verify +iptables-sync-period jenkins-host jenkins-jobs km-path diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index 7a5e38564e6..42162fda377 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -108,6 +108,7 @@ func newServiceInfo(service proxy.ServicePortName) *serviceInfo { type Proxier struct { mu sync.Mutex // protects serviceMap serviceMap map[proxy.ServicePortName]*serviceInfo + syncPeriod time.Duration iptables utiliptables.Interface haveReceivedServiceUpdate bool // true once we've seen an OnServiceUpdate event haveReceivedEndpointsUpdate bool // true once we've seen an OnEndpointsUpdate event @@ -121,12 +122,13 @@ var _ proxy.ProxyProvider = &Proxier{} // An error will be returned if iptables fails to update or acquire the initial lock. // Once a proxier is created, it will keep iptables up to date in the background and // will not terminate if a particular iptables call fails. -func NewProxier(ipt utiliptables.Interface) (*Proxier, error) { +func NewProxier(ipt utiliptables.Interface, syncPeriod time.Duration) (*Proxier, error) { glog.V(2).Info("Tearing down userspace rules. Errors here are acceptable.") // remove iptables rules/chains from the userspace Proxier tearDownUserspaceIptables(ipt) return &Proxier{ serviceMap: make(map[proxy.ServicePortName]*serviceInfo), + syncPeriod: syncPeriod, iptables: ipt, }, nil } @@ -205,12 +207,9 @@ func ipsEqual(lhs, rhs []string) bool { return true } -// How often we sync iptables -const syncIntervalIptables = 5 * time.Second - // SyncLoop runs periodic work. This is expected to run as a goroutine or as the main loop of the app. It does not return. func (proxier *Proxier) SyncLoop() { - t := time.NewTicker(syncIntervalIptables) + t := time.NewTicker(proxier.syncPeriod) defer t.Stop() for { <-t.C diff --git a/pkg/proxy/userspace/proxier.go b/pkg/proxy/userspace/proxier.go index 716689da875..d08276769a5 100644 --- a/pkg/proxy/userspace/proxier.go +++ b/pkg/proxy/userspace/proxier.go @@ -69,6 +69,7 @@ type Proxier struct { loadBalancer LoadBalancer mu sync.Mutex // protects serviceMap serviceMap map[proxy.ServicePortName]*serviceInfo + syncPeriod time.Duration portMapMutex sync.Mutex portMap map[portMapKey]proxy.ServicePortName numProxyLoops int32 // use atomic ops to access this; mostly for testing @@ -110,7 +111,7 @@ func IsProxyLocked(err error) bool { // if iptables fails to update or acquire the initial lock. Once a proxier is // created, it will keep iptables up to date in the background and will not // terminate if a particular iptables call fails. -func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, pr util.PortRange) (*Proxier, error) { +func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, pr util.PortRange, syncPeriod time.Duration) (*Proxier, error) { if listenIP.Equal(localhostIPv4) || listenIP.Equal(localhostIPv6) { return nil, ErrProxyOnLocalhost } @@ -123,10 +124,10 @@ func NewProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.In proxyPorts := newPortAllocator(pr) glog.V(2).Infof("Setting proxy IP to %v and initializing iptables", hostIP) - return createProxier(loadBalancer, listenIP, iptables, hostIP, proxyPorts) + return createProxier(loadBalancer, listenIP, iptables, hostIP, proxyPorts, syncPeriod) } -func createProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, hostIP net.IP, proxyPorts PortAllocator) (*Proxier, error) { +func createProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables.Interface, hostIP net.IP, proxyPorts PortAllocator, syncPeriod time.Duration) (*Proxier, error) { // convenient to pass nil for tests.. if proxyPorts == nil { proxyPorts = newPortAllocator(util.PortRange{}) @@ -146,6 +147,7 @@ func createProxier(loadBalancer LoadBalancer, listenIP net.IP, iptables iptables loadBalancer: loadBalancer, serviceMap: make(map[proxy.ServicePortName]*serviceInfo), portMap: make(map[portMapKey]proxy.ServicePortName), + syncPeriod: syncPeriod, listenIP: listenIP, iptables: iptables, hostIP: hostIP, @@ -166,12 +168,9 @@ func tearDownIptablesProxierRules(ipt iptables.Interface) { } } -// The periodic interval for checking the state of things. -const syncInterval = 5 * time.Second - // SyncLoop runs periodic work. This is expected to run as a goroutine or as the main loop of the app. It does not return. func (proxier *Proxier) SyncLoop() { - t := time.NewTicker(syncInterval) + t := time.NewTicker(proxier.syncPeriod) defer t.Stop() for { <-t.C diff --git a/pkg/proxy/userspace/proxier_test.go b/pkg/proxy/userspace/proxier_test.go index 46a5d6f8bd2..54b8e41d766 100644 --- a/pkg/proxy/userspace/proxier_test.go +++ b/pkg/proxy/userspace/proxier_test.go @@ -223,7 +223,7 @@ func TestTCPProxy(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -250,7 +250,7 @@ func TestUDPProxy(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -282,7 +282,7 @@ func TestMultiPortProxy(t *testing.T) { }}, }}) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -309,7 +309,7 @@ func TestMultiPortOnServiceUpdate(t *testing.T) { serviceQ := proxy.ServicePortName{NamespacedName: types.NamespacedName{Namespace: "testnamespace", Name: "echo"}, Port: "q"} serviceX := proxy.ServicePortName{NamespacedName: types.NamespacedName{Namespace: "testnamespace", Name: "echo"}, Port: "x"} - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -372,7 +372,7 @@ func TestTCPProxyStop(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -410,7 +410,7 @@ func TestUDPProxyStop(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -448,7 +448,7 @@ func TestTCPProxyUpdateDelete(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -485,7 +485,7 @@ func TestUDPProxyUpdateDelete(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -522,7 +522,7 @@ func TestTCPProxyUpdateDeleteUpdate(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -574,7 +574,7 @@ func TestUDPProxyUpdateDeleteUpdate(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -626,7 +626,7 @@ func TestTCPProxyUpdatePort(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -674,7 +674,7 @@ func TestUDPProxyUpdatePort(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -719,7 +719,7 @@ func TestProxyUpdatePublicIPs(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) } @@ -771,7 +771,7 @@ func TestProxyUpdatePortal(t *testing.T) { }, }) - p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil) + p, err := createProxier(lb, net.ParseIP("0.0.0.0"), &fakeIptables{}, net.ParseIP("127.0.0.1"), nil, time.Minute) if err != nil { t.Fatal(err) }