mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-06 10:43:56 +00:00
Merge pull request #128929 from orange30/master
fix: kube-proxy EndpointSliceCache memory is leaked
This commit is contained in:
commit
aa931aa635
@ -149,6 +149,9 @@ func (cache *EndpointSliceCache) checkoutChanges() map[types.NamespacedName]*end
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete(esTracker.pending, name)
|
delete(esTracker.pending, name)
|
||||||
|
if len(esTracker.applied) == 0 && len(esTracker.pending) == 0 {
|
||||||
|
delete(cache.trackerByServiceMap, serviceNN)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
change.current = cache.getEndpointsMap(serviceNN, esTracker.applied)
|
change.current = cache.getEndpointsMap(serviceNN, esTracker.applied)
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
discovery "k8s.io/api/discovery/v1"
|
discovery "k8s.io/api/discovery/v1"
|
||||||
@ -559,3 +560,107 @@ func (cmc *cacheMutationCheck) Check(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEndpointSliceCacheClearedCorrectly(t *testing.T) {
|
||||||
|
initEndpointsPorts := func(eps *discovery.EndpointSlice) {
|
||||||
|
eps.Endpoints = []discovery.Endpoint{{
|
||||||
|
Addresses: []string{"1.1.1.1"},
|
||||||
|
NodeName: ptr.To(testHostname),
|
||||||
|
}}
|
||||||
|
eps.Ports = []discovery.EndpointPort{{
|
||||||
|
Name: ptr.To("n1"),
|
||||||
|
Port: ptr.To[int32](11),
|
||||||
|
Protocol: ptr.To(v1.ProtocolUDP),
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
currEndpointSlices []*discovery.EndpointSlice
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "one endpoint slice",
|
||||||
|
currEndpointSlices: []*discovery.EndpointSlice{
|
||||||
|
makeTestEndpointSlice("ns1", "ep1", 1, initEndpointsPorts),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "two endpoint slices, same namespace",
|
||||||
|
currEndpointSlices: []*discovery.EndpointSlice{
|
||||||
|
makeTestEndpointSlice("ns1", "ep1", 1, initEndpointsPorts),
|
||||||
|
makeTestEndpointSlice("ns1", "ep2", 2, initEndpointsPorts),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "two endpoint slices, same service",
|
||||||
|
currEndpointSlices: []*discovery.EndpointSlice{
|
||||||
|
makeTestEndpointSlice("ns1", "ep1", 1, initEndpointsPorts),
|
||||||
|
makeTestEndpointSlice("ns1", "ep1", 2, initEndpointsPorts),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "two endpoint slices, different namespace",
|
||||||
|
currEndpointSlices: []*discovery.EndpointSlice{
|
||||||
|
makeTestEndpointSlice("ns1", "ep1", 1, initEndpointsPorts),
|
||||||
|
makeTestEndpointSlice("ns2", "ep1", 2, initEndpointsPorts),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
fp := newFakeProxier(v1.IPv4Protocol, time.Time{})
|
||||||
|
fp.hostname = testHostname
|
||||||
|
|
||||||
|
for _, epSlice := range tc.currEndpointSlices {
|
||||||
|
fp.addEndpointSlice(epSlice)
|
||||||
|
}
|
||||||
|
fp.endpointsMap.Update(fp.endpointsChanges)
|
||||||
|
|
||||||
|
for _, epSlice := range tc.currEndpointSlices {
|
||||||
|
fp.deleteEndpointSlice(epSlice)
|
||||||
|
}
|
||||||
|
fp.endpointsMap.Update(fp.endpointsChanges)
|
||||||
|
|
||||||
|
if len(fp.endpointsChanges.endpointSliceCache.trackerByServiceMap) != 0 {
|
||||||
|
t.Errorf("expected: endpointSliceCache does not have any entries, got: %v", fp.endpointsChanges.endpointSliceCache.trackerByServiceMap)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSameServiceEndpointSliceCacheClearedCorrectly(t *testing.T) {
|
||||||
|
initEndpointsPorts := func(eps *discovery.EndpointSlice) {
|
||||||
|
eps.Endpoints = []discovery.Endpoint{{
|
||||||
|
Addresses: []string{"1.1.1.1"},
|
||||||
|
NodeName: ptr.To(testHostname),
|
||||||
|
}}
|
||||||
|
eps.Ports = []discovery.EndpointPort{{
|
||||||
|
Name: ptr.To("n1"),
|
||||||
|
Port: ptr.To[int32](11),
|
||||||
|
Protocol: ptr.To(v1.ProtocolUDP),
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
currEndpointSlices := []*discovery.EndpointSlice{
|
||||||
|
makeTestEndpointSlice("ns1", "svc1", 1, initEndpointsPorts),
|
||||||
|
makeTestEndpointSlice("ns1", "svc1", 2, initEndpointsPorts),
|
||||||
|
}
|
||||||
|
|
||||||
|
fp := newFakeProxier(v1.IPv4Protocol, time.Time{})
|
||||||
|
fp.hostname = testHostname
|
||||||
|
|
||||||
|
for _, epSlice := range currEndpointSlices {
|
||||||
|
fp.addEndpointSlice(epSlice)
|
||||||
|
}
|
||||||
|
fp.endpointsMap.Update(fp.endpointsChanges)
|
||||||
|
|
||||||
|
// only delete the first endpoint slice
|
||||||
|
fp.deleteEndpointSlice(currEndpointSlices[0])
|
||||||
|
|
||||||
|
fp.endpointsMap.Update(fp.endpointsChanges)
|
||||||
|
|
||||||
|
if len(fp.endpointsChanges.endpointSliceCache.trackerByServiceMap) != 1 {
|
||||||
|
t.Errorf("expected: endpointSliceCache to have one entries, got: %v", fp.endpointsChanges.endpointSliceCache.trackerByServiceMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -900,3 +900,23 @@ func TestBuildServiceMapServiceUpdate(t *testing.T) {
|
|||||||
t.Errorf("expected healthcheck ports length 0, got %v", healthCheckNodePorts)
|
t.Errorf("expected healthcheck ports length 0, got %v", healthCheckNodePorts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServiceCacheLeaks(t *testing.T) {
|
||||||
|
fp := newFakeProxier(v1.IPv4Protocol, time.Time{})
|
||||||
|
|
||||||
|
service := makeTestService("ns1", "svc1", func(svc *v1.Service) {
|
||||||
|
svc.Spec.Type = v1.ServiceTypeClusterIP
|
||||||
|
svc.Spec.ClusterIP = "172.16.55.4"
|
||||||
|
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "p1", "UDP", 1234, 4321, 0)
|
||||||
|
svc.Spec.Ports = addTestPort(svc.Spec.Ports, "p2", "TCP", 1235, 5321, 0)
|
||||||
|
})
|
||||||
|
fp.addService(service)
|
||||||
|
if len(fp.serviceChanges.items) != 1 {
|
||||||
|
t.Errorf("Found %d items on the cache, 1 expected", len(fp.serviceChanges.items))
|
||||||
|
}
|
||||||
|
|
||||||
|
fp.deleteService(service)
|
||||||
|
if len(fp.serviceChanges.items) > 0 {
|
||||||
|
t.Errorf("Found %d items on the cache, 0 expected", len(fp.serviceChanges.items))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user