Repository: rabbitmq/cluster-operator

Issue:
Migration from Endpoints to EndpointSlice
### Name and Version

rabbitmq-cluster-operator 2.16.0

### What steps will reproduce the bug?

Kuberenetes 1.33.5 and rabbitmq-cluster-operator 2.16.0 there are a lot of messages about Endpoints deprecation on pod: `rabbitmq-cluster-operator-X` 


### What is the expected behavior?

Migration from Endpoints to EndpointSlice

### What do you see instead?

```
{"level":"info","ts":"2025-10-24T15:52:47Z","logger":"controller-runtime.cache","msg":"Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice"}
```


Discussion:

Solution patch:
diff --git a/Dockerfile b/Dockerfile
index 1d56b1c..0aea272 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,7 @@
 ARG GO_TAG=1.24
+ARG DOCKER_REGISTRY=docker.io
 # Build the manager binary
-FROM --platform=$BUILDPLATFORM golang:${GO_TAG} AS builder
+FROM --platform=$BUILDPLATFORM ${DOCKER_REGISTRY}/library/golang:${GO_TAG} AS builder
 
 WORKDIR /workspace
 
@@ -29,7 +30,9 @@ ENV GOFIPS140=$FIPS_MODE
 RUN CGO_ENABLED=0 GO111MODULE=on go build -a -tags timetzdata -o manager main.go
 
 # ---------------------------------------
-FROM alpine:latest AS etc-builder
+ARG DOCKER_REGISTRY=docker.io
+FROM ${DOCKER_REGISTRY}/library/alpine:latest AS etc-builder
+
 
 RUN echo "rabbitmq-cluster-operator:x:1000:" > /etc/group && \
     echo "rabbitmq-cluster-operator:x:1000:1000::/home/rabbitmq-cluster-operator:/usr/sbin/nologin" > /etc/passwd
diff --git a/Makefile b/Makefile
index 1a37f68..f1cbdf3 100644
--- a/Makefile
+++ b/Makefile
@@ -177,11 +177,13 @@ deploy-dev::deploy-namespace-rbac
 deploy-dev::docker-registry-secret
 deploy-dev::deploy-manager-dev
 
+CONTAINER ?= docker
+
 GIT_COMMIT := $(shell git rev-parse --short HEAD)
 deploy-kind: manifests deploy-namespace-rbac ## Load operator image and deploy operator into current KinD cluster
 	@$(call check_defined, OPERATOR_IMAGE, path to the Operator image within the registry e.g. rabbitmq/cluster-operator)
 	@$(call check_defined, DOCKER_REGISTRY_SERVER, URL of docker registry containing the Operator image e.g. registry.my-company.com)
-	docker buildx build --build-arg=GIT_COMMIT=$(GIT_COMMIT) -t $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):$(GIT_COMMIT) .
+	$(CONTAINER) buildx build --build-arg=DOCKER_REGISTRY=$(DOCKER_REGISTRY_SERVER) --build-arg=GIT_COMMIT=$(GIT_COMMIT) -t $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):$(GIT_COMMIT) .
 	kind load docker-image $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):$(GIT_COMMIT)
 	kustomize build config/crd | kubectl apply -f -
 	kustomize build config/default/overlays/kind | sed 's@((operator_docker_image))@"$(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):$(GIT_COMMIT)"@' | kubectl apply -f -
@@ -205,18 +207,18 @@ generate-installation-manifest: | $(YTT)
 docker-build: ## Build the docker image with tag `latest`
 	@$(call check_defined, OPERATOR_IMAGE, path to the Operator image within the registry e.g. rabbitmq/cluster-operator)
 	@$(call check_defined, DOCKER_REGISTRY_SERVER, URL of docker registry containing the Operator image e.g. registry.my-company.com)
-	docker buildx build --build-arg=GIT_COMMIT=$(GIT_COMMIT) -t $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):latest .
+	$(CONTAINER) buildx build --build-arg=DOCKER_REGISTRY=$(DOCKER_REGISTRY_SERVER) --build-arg=GIT_COMMIT=$(GIT_COMMIT) -t $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):latest .
 
 docker-push: ## Push the docker image with tag `latest`
 	@$(call check_defined, OPERATOR_IMAGE, path to the Operator image within the registry e.g. rabbitmq/cluster-operator)
 	@$(call check_defined, DOCKER_REGISTRY_SERVER, URL of docker registry containing the Operator image e.g. registry.my-company.com)
-	docker push $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):latest
+	$(CONTAINER) push $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):latest
 
 docker-build-dev:
 	@$(call check_defined, OPERATOR_IMAGE, path to the Operator image within the registry e.g. rabbitmq/cluster-operator)
 	@$(call check_defined, DOCKER_REGISTRY_SERVER, URL of docker registry containing the Operator image e.g. registry.my-company.com)
-	docker buildx build --build-arg=GIT_COMMIT=$(GIT_COMMIT) -t $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):$(GIT_COMMIT) .
-	docker push $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):$(GIT_COMMIT)
+	$(CONTAINER) buildx build --build-arg=DOCKER_REGISTRY=$(DOCKER_REGISTRY_SERVER) --build-arg=GIT_COMMIT=$(GIT_COMMIT) -t $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):$(GIT_COMMIT) .
+	$(CONTAINER) push $(DOCKER_REGISTRY_SERVER)/$(OPERATOR_IMAGE):$(GIT_COMMIT)
 
 # https://github.com/cert-manager/cmctl/releases
 # Cert Manager now publishes CMCTL independently from cert-manager
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index 837112d..1159938 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -68,6 +68,13 @@ rules:
   - list
   - update
   - watch
+- apiGroups:
+  - discovery.k8s.io
+  resources:
+  - endpointslices
+  verbs:
+  - get
+  - list
 - apiGroups:
   - rabbitmq.com
   resources:
diff --git a/controllers/rabbitmqcluster_controller.go b/controllers/rabbitmqcluster_controller.go
index 33397a0..0e72afc 100644
--- a/controllers/rabbitmqcluster_controller.go
+++ b/controllers/rabbitmqcluster_controller.go
@@ -30,6 +30,7 @@ import (
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/record"
 
+	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/types"
 
 	clientretry "k8s.io/client-go/util/retry"
@@ -43,6 +44,7 @@ import (
 	rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/v2/api/v1beta1"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
+	discoveryv1 "k8s.io/api/discovery/v1"
 	rbacv1 "k8s.io/api/rbac/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
@@ -77,7 +79,6 @@ type RabbitmqClusterReconciler struct {
 // +kubebuilder:rbac:groups="",resources=pods/exec,verbs=create
 // +kubebuilder:rbac:groups="",resources=pods,verbs=update;get;list;watch
 // +kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch;create;update
-// +kubebuilder:rbac:groups="",resources=endpoints,verbs=get;watch;list
 // +kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;list;watch;create;update;delete
 // +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update
 // +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update
@@ -88,6 +89,8 @@ type RabbitmqClusterReconciler struct {
 // +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update
 // +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,verbs=get;list;watch;create;update
 // +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=roles,verbs=get;list;watch;create;update
+// +kubebuilder:rbac:groups="discovery.k8s.io",resources=endpointslices,verbs=get;list
+// +kubebuilder:rbac:groups="",resources=endpoints,verbs=get;watch;list
 // +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update
 
 func (r *RabbitmqClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
@@ -342,7 +345,8 @@ func (r *RabbitmqClusterReconciler) updateStatusConditions(ctx context.Context,
 
 func (r *RabbitmqClusterReconciler) getChildResources(ctx context.Context, rmq *rabbitmqv1beta1.RabbitmqCluster) ([]runtime.Object, error) {
 	sts := &appsv1.StatefulSet{}
-	endPoints := &corev1.Endpoints{}
+	endpointSliceList := &discoveryv1.EndpointSliceList{}
+	endpointSlice := &discoveryv1.EndpointSlice{}
 
 	if err := r.Get(ctx,
 		types.NamespacedName{Name: rmq.ChildResourceName("server"), Namespace: rmq.Namespace},
@@ -352,15 +356,25 @@ func (r *RabbitmqClusterReconciler) getChildResources(ctx context.Context, rmq *
 		sts = nil
 	}
 
-	if err := r.Get(ctx,
-		types.NamespacedName{Name: rmq.ChildResourceName(resource.ServiceSuffix), Namespace: rmq.Namespace},
-		endPoints); err != nil && !k8serrors.IsNotFound(err) {
+	selector, err := labels.Parse(fmt.Sprintf("%s=%s", discoveryv1.LabelServiceName, rmq.Name))
+	if err != nil {
 		return nil, err
-	} else if k8serrors.IsNotFound(err) {
-		endPoints = nil
 	}
 
-	return []runtime.Object{sts, endPoints}, nil
+	listOptions := client.ListOptions{
+		LabelSelector: selector,
+		Namespace:     rmq.Namespace,
+	}
+
+	if err := r.List(ctx, endpointSliceList, &listOptions); err != nil {
+		return nil, err
+	} else if len(endpointSliceList.Items) == 0 {
+		endpointSlice = nil
+	} else {
+		endpointSlice = &endpointSliceList.Items[0]
+	}
+
+	return []runtime.Object{sts, endpointSlice}, nil
 }
 
 func (r *RabbitmqClusterReconciler) setReconcileSuccess(ctx context.Context, rabbitmqCluster *rabbitmqv1beta1.RabbitmqCluster, condition corev1.ConditionStatus, reason, msg string) {
diff --git a/go.mod b/go.mod
index 212f263..9769701 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/go-logr/logr v1.4.3
 	github.com/go-stomp/stomp v2.1.4+incompatible
 	github.com/michaelklishin/rabbit-hole/v2 v2.16.0
-	github.com/onsi/ginkgo/v2 v2.27.1
+	github.com/onsi/ginkgo/v2 v2.27.2
 	github.com/onsi/gomega v1.38.2
 	github.com/rabbitmq/amqp091-go v1.10.0
 	github.com/rabbitmq/rabbitmq-stream-go-client v1.6.1
@@ -150,7 +150,6 @@ require (
 	github.com/zmap/zlint/v3 v3.6.0 // indirect
 	go.opentelemetry.io/otel v1.35.0 // indirect
 	go.opentelemetry.io/otel/trace v1.35.0 // indirect
-	go.uber.org/automaxprocs v1.6.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	go.uber.org/zap v1.27.0 // indirect
 	go.yaml.in/yaml/v2 v2.4.2 // indirect
diff --git a/go.sum b/go.sum
index af215a5..3efc419 100644
--- a/go.sum
+++ b/go.sum
@@ -384,8 +384,8 @@ github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+
 github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
 github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
 github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
-github.com/onsi/ginkgo/v2 v2.27.1 h1:0LJC8MpUSQnfnp4n/3W3GdlmJP3ENGF0ZPzjQGLPP7s=
-github.com/onsi/ginkgo/v2 v2.27.1/go.mod h1:wmy3vCqiBjirARfVhAqFpYt8uvX0yaFe+GudAqqcCqA=
+github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
+github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
@@ -427,8 +427,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
 github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg=
-github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
-github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
 github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
 github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
 github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
@@ -574,8 +572,6 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt
 go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
 go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
 go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
-go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
-go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
 go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
diff --git a/internal/status/cluster_available.go b/internal/status/cluster_available.go
index 0b104ce..0228247 100644
--- a/internal/status/cluster_available.go
+++ b/internal/status/cluster_available.go
@@ -13,13 +13,14 @@ import (
 	"time"
 
 	corev1 "k8s.io/api/core/v1"
+	discoveryv1 "k8s.io/api/discovery/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
 type ClusterAvailableConditionManager struct {
-	condition RabbitmqClusterCondition
-	endpoints *corev1.Endpoints
+	condition     RabbitmqClusterCondition
+	endpointslice *discoveryv1.EndpointSlice
 }
 
 func ClusterAvailableCondition(resources []runtime.Object,
@@ -32,7 +33,7 @@ func ClusterAvailableCondition(resources []runtime.Object,
 
 	for _, res := range resources {
 		switch resource := res.(type) {
-		case *corev1.Endpoints:
+		case *discoveryv1.EndpointSlice:
 			if resource == nil {
 				condition.Status = corev1.ConditionUnknown
 				condition.Reason = "CouldNotRetrieveEndpoints"
@@ -40,8 +41,8 @@ func ClusterAvailableCondition(resources []runtime.Object,
 				goto assignLastTransitionTime
 			}
 
-			for _, subset := range resource.Subsets {
-				if len(subset.Addresses) > 0 {
+			for _, endpoint := range resource.Endpoints {
+				if len(endpoint.Addresses) > 0 {
 					condition.Status = corev1.ConditionTrue
 					condition.Reason = "AtLeastOneEndpointAvailable"
 					goto assignLastTransitionTime
diff --git a/internal/status/zz_generated.deepcopy.go b/internal/status/zz_generated.deepcopy.go
index 87ca68b..bffe76e 100644
--- a/internal/status/zz_generated.deepcopy.go
+++ b/internal/status/zz_generated.deepcopy.go
@@ -15,16 +15,16 @@ This product may include a number of subcomponents with separate copyright notic
 package status
 
 import (
-	"k8s.io/api/core/v1"
+	"k8s.io/api/discovery/v1"
 )
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ClusterAvailableConditionManager) DeepCopyInto(out *ClusterAvailableConditionManager) {
 	*out = *in
 	in.condition.DeepCopyInto(&out.condition)
-	if in.endpoints != nil {
-		in, out := &in.endpoints, &out.endpoints
-		*out = new(v1.Endpoints)
+	if in.endpointslice != nil {
+		in, out := &in.endpointslice, &out.endpointslice
+		*out = new(v1.EndpointSlice)
 		(*in).DeepCopyInto(*out)
 	}
 }
diff --git a/main.go b/main.go
index d7edea3..0cb8aa5 100644
--- a/main.go
+++ b/main.go
@@ -24,6 +24,7 @@ import (
 
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
+	discoveryv1 "k8s.io/api/discovery/v1"
 	rbacv1 "k8s.io/api/rbac/v1"
 
 	"k8s.io/klog/v2"
@@ -153,7 +154,7 @@ func main() {
 		&corev1.ConfigMap{}:                {Label: rmqSelector},
 		&corev1.Secret{}:                   {Label: rmqSelector},
 		&corev1.ServiceAccount{}:           {Label: rmqSelector},
-		&corev1.Endpoints{}:                {Label: rmqSelector},
+		&discoveryv1.EndpointSlice{}:       {Label: rmqSelector},
 		&rbacv1.Role{}:                     {Label: rmqSelector},
 		&rbacv1.RoleBinding{}:              {Label: rmqSelector},
 	}



Test patch:
diff --git a/api/v1beta1/rabbitmqcluster_status_test.go b/api/v1beta1/rabbitmqcluster_status_test.go
index 728c6b5..90f6baf 100644
--- a/api/v1beta1/rabbitmqcluster_status_test.go
+++ b/api/v1beta1/rabbitmqcluster_status_test.go
@@ -6,6 +6,7 @@ import (
 	"github.com/rabbitmq/cluster-operator/v2/internal/status"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
+	discoveryv1 "k8s.io/api/discovery/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -40,19 +41,17 @@ var _ = Describe("RabbitmqClusterStatus", func() {
 			Conditions:         nil,
 		}
 
-		endPoints := &corev1.Endpoints{
-			Subsets: []corev1.EndpointSubset{
+		endPointSlice := &discoveryv1.EndpointSlice{
+			Endpoints: []discoveryv1.Endpoint{
 				{
-					Addresses: []corev1.EndpointAddress{
-						{
-							IP: "127.0.0.1",
-						},
+					Addresses: []string{
+						"127.0.0.1",
 					},
 				},
 			},
 		}
 
-		rabbitmqClusterStatus.SetConditions([]runtime.Object{sts, endPoints})
+		rabbitmqClusterStatus.SetConditions([]runtime.Object{sts, endPointSlice})
 
 		Expect(rabbitmqClusterStatus.Conditions).To(HaveLen(4))
 		Expect(rabbitmqClusterStatus.Conditions[0].Type).To(Equal(status.AllReplicasReady))
diff --git a/api/v1beta1/rabbitmqcluster_types_test.go b/api/v1beta1/rabbitmqcluster_types_test.go
index 27e8d86..fe5c36a 100644
--- a/api/v1beta1/rabbitmqcluster_types_test.go
+++ b/api/v1beta1/rabbitmqcluster_types_test.go
@@ -14,6 +14,7 @@ import (
 	"github.com/rabbitmq/cluster-operator/v2/internal/status"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
+	discoveryv1 "k8s.io/api/discovery/v1"
 	k8sresource "k8s.io/apimachinery/pkg/api/resource"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/utils/ptr"
@@ -484,19 +485,17 @@ var _ = Describe("RabbitmqCluster", func() {
 				Conditions:         nil,
 			}
 
-			endPoints := &corev1.Endpoints{
-				Subsets: []corev1.EndpointSubset{
+			endPointSlice := &discoveryv1.EndpointSlice{
+				Endpoints: []discoveryv1.Endpoint{
 					{
-						Addresses: []corev1.EndpointAddress{
-							{
-								IP: "127.0.0.1",
-							},
+						Addresses: []string{
+							"127.0.0.1",
 						},
 					},
 				},
 			}
 
-			rabbitmqClusterStatus.SetConditions([]runtime.Object{statefulset, endPoints})
+			rabbitmqClusterStatus.SetConditions([]runtime.Object{statefulset, endPointSlice})
 
 			Expect(rabbitmqClusterStatus.Conditions).To(HaveLen(4))
 			Expect(rabbitmqClusterStatus.Conditions[0].Type).To(Equal(status.AllReplicasReady))
diff --git a/internal/status/all_replicas_ready_test.go b/internal/status/all_replicas_ready_test.go
index 9cb6c25..ba20c99 100644
--- a/internal/status/all_replicas_ready_test.go
+++ b/internal/status/all_replicas_ready_test.go
@@ -17,6 +17,7 @@ import (
 	rabbitmqstatus "github.com/rabbitmq/cluster-operator/v2/internal/status"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
+	discoveryv1 "k8s.io/api/discovery/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 )
@@ -44,7 +45,7 @@ var _ = Describe("AllReplicasReady", func() {
 			})
 
 			It("returns the expected condition", func() {
-				condition := rabbitmqstatus.AllReplicasReadyCondition([]runtime.Object{&corev1.Endpoints{}, sts}, oldCondition)
+				condition := rabbitmqstatus.AllReplicasReadyCondition([]runtime.Object{&discoveryv1.EndpointSlice{}, sts}, oldCondition)
 
 				By("having status true and reason message", func() {
 					Expect(condition.Status).To(Equal(corev1.ConditionTrue))
@@ -112,7 +113,7 @@ var _ = Describe("AllReplicasReady", func() {
 				})
 
 				It("updates the transition time", func() {
-					condition := rabbitmqstatus.AllReplicasReadyCondition([]runtime.Object{&corev1.Endpoints{}, sts}, oldCondition)
+					condition := rabbitmqstatus.AllReplicasReadyCondition([]runtime.Object{&discoveryv1.EndpointSlice{}, sts}, oldCondition)
 					Expect(condition.LastTransitionTime).ToNot(Equal(emptyTime))
 				})
 			})
diff --git a/internal/status/cluster_available_test.go b/internal/status/cluster_available_test.go
index b968954..22b28fe 100644
--- a/internal/status/cluster_available_test.go
+++ b/internal/status/cluster_available_test.go
@@ -16,39 +16,33 @@ import (
 	. "github.com/onsi/gomega"
 	rabbitmqstatus "github.com/rabbitmq/cluster-operator/v2/internal/status"
 	corev1 "k8s.io/api/core/v1"
+	discoveryv1 "k8s.io/api/discovery/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
 var _ = Describe("ClusterAvailable", func() {
 	var (
-		childServiceEndpoints *corev1.Endpoints
-		existingCondition     *rabbitmqstatus.RabbitmqClusterCondition
+		childServiceEndpointSlice *discoveryv1.EndpointSlice
+		existingCondition         *rabbitmqstatus.RabbitmqClusterCondition
 	)
 
 	BeforeEach(func() {
-		childServiceEndpoints = &corev1.Endpoints{}
+		childServiceEndpointSlice = &discoveryv1.EndpointSlice{}
 	})
 
 	Context("condition status and reason", func() {
 		When("at least one service endpoint is published", func() {
 			BeforeEach(func() {
-				childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+				childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 					{
-						Addresses: []corev1.EndpointAddress{
-							{
-								IP: "1.2.3.4",
-							},
-							{
-								IP: "5.6.7.8",
-							},
-						},
+						Addresses: []string{"1.2.3.4", "5.6.7.8"},
 					},
 				}
 			})
 
 			It("returns a condition with state true", func() {
-				condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpoints}, existingCondition)
+				condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpointSlice}, existingCondition)
 
 				Expect(condition.Status).To(Equal(corev1.ConditionTrue))
 				Expect(condition.Reason).To(Equal("AtLeastOneEndpointAvailable"))
@@ -57,15 +51,15 @@ var _ = Describe("ClusterAvailable", func() {
 
 		When("no service endpoint is published", func() {
 			BeforeEach(func() {
-				childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+				childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 					{
-						Addresses: []corev1.EndpointAddress{},
+						Addresses: []string{},
 					},
 				}
 			})
 
 			It("returns a condition with state false", func() {
-				condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+				condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 
 				Expect(condition.Status).To(Equal(corev1.ConditionFalse))
 				Expect(condition.Reason).To(Equal("NoEndpointsAvailable"))
@@ -75,11 +69,11 @@ var _ = Describe("ClusterAvailable", func() {
 
 		When("service endpoints do not exist", func() {
 			BeforeEach(func() {
-				childServiceEndpoints = nil
+				childServiceEndpointSlice = nil
 			})
 
 			It("returns a condition with state unknown", func() {
-				condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+				condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 				Expect(condition.Status).To(Equal(corev1.ConditionUnknown))
 				Expect(condition.Reason).To(Equal("CouldNotRetrieveEndpoints"))
 				Expect(condition.Message).NotTo(BeEmpty())
@@ -108,22 +102,15 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("remains true", func() {
 				BeforeEach(func() {
-					childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+					childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 						{
-							Addresses: []corev1.EndpointAddress{
-								{
-									IP: "1.2.3.4",
-								},
-								{
-									IP: "5.6.7.8",
-								},
-							},
+							Addresses: []string{"1.2.3.4", "5.6.7.8"},
 						},
 					}
 				})
 
 				It("does not update transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpointSlice}, existingCondition)
 
 					Expect(existingCondition).NotTo(BeNil())
 					existingConditionTime := existingCondition.LastTransitionTime.DeepCopy()
@@ -133,15 +120,15 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("transitions to false", func() {
 				BeforeEach(func() {
-					childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+					childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 						{
-							Addresses: []corev1.EndpointAddress{},
+							Addresses: []string{},
 						},
 					}
 				})
 
 				It("updates transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 
 					Expect(existingCondition).NotTo(BeNil())
 					existingConditionTime := existingCondition.LastTransitionTime.DeepCopy()
@@ -152,11 +139,11 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("transitions to unknown", func() {
 				BeforeEach(func() {
-					childServiceEndpoints = nil
+					childServiceEndpointSlice = nil
 				})
 
 				It("updates transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 
 					Expect(existingCondition).NotTo(BeNil())
 					existingConditionTime := existingCondition.LastTransitionTime.DeepCopy()
@@ -178,22 +165,15 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("transitions to true", func() {
 				BeforeEach(func() {
-					childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+					childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 						{
-							Addresses: []corev1.EndpointAddress{
-								{
-									IP: "1.2.3.4",
-								},
-								{
-									IP: "5.6.7.8",
-								},
-							},
+							Addresses: []string{"1.2.3.4", "5.6.7.8"},
 						},
 					}
 				})
 
 				It("updates transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpointSlice}, existingCondition)
 
 					Expect(existingCondition).NotTo(BeNil())
 					existingConditionTime := existingCondition.LastTransitionTime.DeepCopy()
@@ -204,15 +184,15 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("remains false", func() {
 				BeforeEach(func() {
-					childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+					childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 						{
-							Addresses: []corev1.EndpointAddress{},
+							Addresses: []string{},
 						},
 					}
 				})
 
 				It("does not update transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 
 					Expect(existingCondition).NotTo(BeNil())
 					existingConditionTime := existingCondition.LastTransitionTime.DeepCopy()
@@ -222,11 +202,11 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("transitions	to unknown", func() {
 				BeforeEach(func() {
-					childServiceEndpoints = nil
+					childServiceEndpointSlice = nil
 				})
 
 				It("updates transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 
 					Expect(existingCondition).NotTo(BeNil())
 					existingConditionTime := existingCondition.LastTransitionTime.DeepCopy()
@@ -248,22 +228,15 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("transitions to true", func() {
 				BeforeEach(func() {
-					childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+					childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 						{
-							Addresses: []corev1.EndpointAddress{
-								{
-									IP: "1.2.3.4",
-								},
-								{
-									IP: "5.6.7.8",
-								},
-							},
+							Addresses: []string{"1.2.3.4", "5.6.7.8"},
 						},
 					}
 				})
 
 				It("updates transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpointSlice}, existingCondition)
 
 					Expect(existingCondition).NotTo(BeNil())
 					existingConditionTime := existingCondition.LastTransitionTime.DeepCopy()
@@ -274,15 +247,15 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("transitions to false", func() {
 				BeforeEach(func() {
-					childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+					childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 						{
-							Addresses: []corev1.EndpointAddress{},
+							Addresses: []string{},
 						},
 					}
 				})
 
 				It("updates transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 
 					Expect(existingCondition).NotTo(BeNil())
 					existingConditionTime := existingCondition.LastTransitionTime.DeepCopy()
@@ -293,11 +266,11 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("remains unknown", func() {
 				BeforeEach(func() {
-					childServiceEndpoints = nil
+					childServiceEndpointSlice = nil
 				})
 
 				It("does not update transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 
 					Expect(existingCondition).NotTo(BeNil())
 					existingConditionTime := existingCondition.LastTransitionTime.DeepCopy()
@@ -316,22 +289,15 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("transitions to true", func() {
 				BeforeEach(func() {
-					childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+					childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 						{
-							Addresses: []corev1.EndpointAddress{
-								{
-									IP: "1.2.3.4",
-								},
-								{
-									IP: "5.6.7.8",
-								},
-							},
+							Addresses: []string{"1.2.3.4", "5.6.7.8"},
 						},
 					}
 				})
 
 				It("updates transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{&corev1.Pod{}, childServiceEndpointSlice}, existingCondition)
 
 					Expect(condition.LastTransitionTime).ToNot(Equal(emptyTime))
 				})
@@ -339,15 +305,15 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("transitions to false", func() {
 				BeforeEach(func() {
-					childServiceEndpoints.Subsets = []corev1.EndpointSubset{
+					childServiceEndpointSlice.Endpoints = []discoveryv1.Endpoint{
 						{
-							Addresses: []corev1.EndpointAddress{},
+							Addresses: []string{},
 						},
 					}
 				})
 
 				It("updates transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 
 					Expect(condition.LastTransitionTime).ToNot(Equal(emptyTime))
 				})
@@ -355,11 +321,11 @@ var _ = Describe("ClusterAvailable", func() {
 
 			When("transitions to unknown", func() {
 				BeforeEach(func() {
-					childServiceEndpoints = nil
+					childServiceEndpointSlice = nil
 				})
 
 				It("updates transition time", func() {
-					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpoints}, existingCondition)
+					condition := rabbitmqstatus.ClusterAvailableCondition([]runtime.Object{childServiceEndpointSlice}, existingCondition)
 
 					Expect(condition.LastTransitionTime).ToNot(Equal(emptyTime))
 				})