kube-proxy network programming latency on restarts

kube-proxy expose the metric network_programming_duration_seconds,
that is defined as the time it takes to program the network since
a a service or pod has changed. It uses an annotation on the endpoints
/endpointslices to calculate when the endpoint was created, however,
on restarts, kube-proxy process all the endpoints again, no matter
when those were generated, polluting the metrics.

To be safe, kube-proxy will estimate the latency only for those
endpoints that were generated after it started.
This commit is contained in:
Antonio Ojea
2021-04-07 19:09:59 +02:00
parent b0abe89ae2
commit ef76be37de
3 changed files with 42 additions and 16 deletions

View File

@@ -20,10 +20,11 @@ import (
"net"
"reflect"
"testing"
"time"
"github.com/davecgh/go-spew/spew"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
@@ -511,12 +512,21 @@ type FakeProxier struct {
hostname string
}
func newFakeProxier(ipFamily v1.IPFamily) *FakeProxier {
func newFakeProxier(ipFamily v1.IPFamily, t time.Time) *FakeProxier {
return &FakeProxier{
serviceMap: make(ServiceMap),
serviceChanges: NewServiceChangeTracker(nil, ipFamily, nil, nil),
endpointsMap: make(EndpointsMap),
endpointsChanges: NewEndpointChangeTracker(testHostname, nil, ipFamily, nil, false, nil),
serviceMap: make(ServiceMap),
serviceChanges: NewServiceChangeTracker(nil, ipFamily, nil, nil),
endpointsMap: make(EndpointsMap),
endpointsChanges: &EndpointChangeTracker{
hostname: testHostname,
items: make(map[types.NamespacedName]*endpointsChange),
makeEndpointInfo: nil,
ipFamily: ipFamily,
recorder: nil,
lastChangeTriggerTimes: make(map[types.NamespacedName][]time.Time),
trackerStartTime: t,
processEndpointsMapChange: nil,
},
}
}
@@ -539,7 +549,7 @@ func (fake *FakeProxier) deleteService(service *v1.Service) {
}
func TestServiceMapUpdateHeadless(t *testing.T) {
fp := newFakeProxier(v1.IPv4Protocol)
fp := newFakeProxier(v1.IPv4Protocol, time.Time{})
makeServiceMap(fp,
makeTestService("ns2", "headless", func(svc *v1.Service) {
@@ -570,7 +580,7 @@ func TestServiceMapUpdateHeadless(t *testing.T) {
}
func TestUpdateServiceTypeExternalName(t *testing.T) {
fp := newFakeProxier(v1.IPv4Protocol)
fp := newFakeProxier(v1.IPv4Protocol, time.Time{})
makeServiceMap(fp,
makeTestService("ns2", "external-name", func(svc *v1.Service) {
@@ -595,7 +605,7 @@ func TestUpdateServiceTypeExternalName(t *testing.T) {
}
func TestBuildServiceMapAddRemove(t *testing.T) {
fp := newFakeProxier(v1.IPv4Protocol)
fp := newFakeProxier(v1.IPv4Protocol, time.Time{})
services := []*v1.Service{
makeTestService("ns2", "cluster-ip", func(svc *v1.Service) {
@@ -698,7 +708,7 @@ func TestBuildServiceMapAddRemove(t *testing.T) {
}
func TestBuildServiceMapServiceUpdate(t *testing.T) {
fp := newFakeProxier(v1.IPv4Protocol)
fp := newFakeProxier(v1.IPv4Protocol, time.Time{})
servicev1 := makeTestService("ns1", "svc1", func(svc *v1.Service) {
svc.Spec.Type = v1.ServiceTypeClusterIP