diff --git a/pkg/controller/endpoint/endpoints_controller.go b/pkg/controller/endpoint/endpoints_controller.go index 2c91d491911..b090d676223 100644 --- a/pkg/controller/endpoint/endpoints_controller.go +++ b/pkg/controller/endpoint/endpoints_controller.go @@ -472,9 +472,18 @@ func (e *EndpointController) syncService(key string) error { createEndpoints := len(currentEndpoints.ResourceVersion) == 0 + // Compare the sorted subsets and labels + // Remove the HeadlessService label from the endpoints if it exists, + // as this won't be set on the service itself + // and will cause a false negative in this diff check. + // But first check if it has that label to avoid expensive copies. + compareLabels := currentEndpoints.Labels + if _, ok := currentEndpoints.Labels[v1.IsHeadlessService]; ok { + compareLabels = utillabels.CloneAndRemoveLabel(currentEndpoints.Labels, v1.IsHeadlessService) + } if !createEndpoints && apiequality.Semantic.DeepEqual(currentEndpoints.Subsets, subsets) && - apiequality.Semantic.DeepEqual(currentEndpoints.Labels, service.Labels) { + apiequality.Semantic.DeepEqual(compareLabels, service.Labels) { klog.V(5).Infof("endpoints are equal for %s/%s, skipping update", service.Namespace, service.Name) return nil } diff --git a/pkg/controller/endpoint/endpoints_controller_test.go b/pkg/controller/endpoint/endpoints_controller_test.go index 705c10b6e0c..1b3e15948ca 100644 --- a/pkg/controller/endpoint/endpoints_controller_test.go +++ b/pkg/controller/endpoint/endpoints_controller_test.go @@ -383,6 +383,33 @@ func TestSyncEndpointsProtocolTCP(t *testing.T) { endpointsHandler.ValidateRequest(t, "/api/v1/namespaces/"+ns+"/endpoints/foo", "PUT", &data) } +func TestSyncEndpointsHeadlessServiceLabel(t *testing.T) { + ns := metav1.NamespaceDefault + testServer, endpointsHandler := makeTestServer(t, ns) + defer testServer.Close() + endpoints := newController(testServer.URL, 0*time.Second) + endpoints.endpointsStore.Add(&v1.Endpoints{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: ns, + ResourceVersion: "1", + Labels: map[string]string{ + v1.IsHeadlessService: "", + }, + }, + Subsets: []v1.EndpointSubset{}, + }) + endpoints.serviceStore.Add(&v1.Service{ + ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: ns}, + Spec: v1.ServiceSpec{ + Selector: map[string]string{"foo": "bar"}, + Ports: []v1.ServicePort{{Port: 80}}, + }, + }) + endpoints.syncService(ns + "/foo") + endpointsHandler.ValidateRequestCount(t, 0) +} + func TestSyncEndpointsProtocolUDP(t *testing.T) { ns := "other" testServer, endpointsHandler := makeTestServer(t, ns)