diff --git a/controllers/clustercache/cluster_accessor.go b/controllers/clustercache/cluster_accessor.go index 0bbc92f2380d..b9c59cf05478 100644 --- a/controllers/clustercache/cluster_accessor.go +++ b/controllers/clustercache/cluster_accessor.go @@ -27,7 +27,9 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" @@ -344,12 +346,23 @@ func (ca *clusterAccessor) HealthCheck(ctx context.Context) (bool, bool) { ca.rLock(ctx) restClient := ca.lockedState.connection.restClient + restConfig := ca.lockedState.connection.restConfig ca.rUnlock(ctx) log.V(6).Info("Run health probe") // Executing the health probe is intentionally done without a lock to avoid blocking other reconcilers. _, err := restClient.Get().AbsPath("/").Timeout(ca.config.HealthProbe.Timeout).DoRaw(ctx) + if err == nil { + // Execute health probe with a new restClient (this verifies that a new connection works). + codec := runtime.NoopEncoder{Decoder: scheme.Codecs.UniversalDecoder()} + restClientConfig := rest.CopyConfig(restConfig) + restClientConfig.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec}) + restClient, err = rest.UnversionedRESTClientFor(restClientConfig) + if err == nil { + _, err = restClient.Get().AbsPath("/").Timeout(ca.config.HealthProbe.Timeout).DoRaw(ctx) + } + } ca.lock(ctx) defer ca.unlock(ctx) diff --git a/controllers/clustercache/cluster_accessor_test.go b/controllers/clustercache/cluster_accessor_test.go index bfe5acdf1d88..d793e4fe7cb6 100644 --- a/controllers/clustercache/cluster_accessor_test.go +++ b/controllers/clustercache/cluster_accessor_test.go @@ -305,6 +305,7 @@ func TestHealthCheck(t *testing.T) { }, }) accessor.lockedState.connection = &clusterAccessorLockedConnectionState{ + restConfig: env.Config, restClient: &fake.RESTClient{ NegotiatedSerializer: scheme.Codecs, Resp: tt.restClientHTTPResponse,