Debounce kubernetes service endpoint updates

Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
pull/7215/head
Brad Davidson 2 years ago committed by Brad Davidson
parent ece4d8e45c
commit 2992477c4b

@ -35,6 +35,10 @@ import (
"k8s.io/kubernetes/pkg/cluster/ports"
)
var (
endpointDebounceDelay = time.Second
)
type agentTunnel struct {
client kubernetes.Interface
cidrs cidranger.Ranger
@ -306,9 +310,14 @@ func (a *agentTunnel) watchEndpoints(ctx context.Context, apiServerReady <-chan
<-done
}()
var cancelUpdate context.CancelFunc
for {
select {
case <-ctx.Done():
if cancelUpdate != nil {
cancelUpdate()
}
return
case ev, ok := <-watch.ResultChan():
endpoint, ok := ev.Object.(*v1.Endpoints)
@ -317,9 +326,29 @@ func (a *agentTunnel) watchEndpoints(ctx context.Context, apiServerReady <-chan
continue
}
if cancelUpdate != nil {
cancelUpdate()
}
var debounceCtx context.Context
debounceCtx, cancelUpdate = context.WithCancel(ctx)
// When joining the cluster, the apiserver adds, removes, and then readds itself to
// the endpoint list several times. This causes a bit of thrashing if we react to
// endpoint changes immediately. Instead, perform the endpoint update in a
// goroutine that sleeps for a short period before checking for changes and updating
// the proxy addresses. If another update occurs, the previous update operation
// will be cancelled and a new one queued.
go func() {
select {
case <-time.After(endpointDebounceDelay):
case <-debounceCtx.Done():
return
}
newAddresses := util.GetAddresses(endpoint)
if reflect.DeepEqual(newAddresses, proxy.SupervisorAddresses()) {
continue
return
}
proxy.Update(newAddresses)
@ -339,6 +368,7 @@ func (a *agentTunnel) watchEndpoints(ctx context.Context, apiServerReady <-chan
logrus.Infof("Stopped tunnel to %s", address)
}
}
}()
}
}
}

Loading…
Cancel
Save