Repository: scylladb/scylla-operator
Pull request #1005 (2022-08-03 15:04:14)

Promote PodDisruptionBudgets from V1Beta1 to V1
<!-- Please take a look at our [Contributing](https://github.com/scylladb/scylla-operator/blob/master/docs/contributing.md)
documentation before submitting a Pull Request!
Thank you for contributing to the Scylla Operator! -->

**Description of your changes:** 
During the apply of PodDisruptionBudgets the following warning occured:
"policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget".

To fix this, all the PDBs will now come from "k8s.io/api/policy/v1" package.


zimnx: Please port our PDBs in helm charts and manifests
zimnx: > > Please port our PDBs in helm charts and manifests
> 
> PDBs in helm charts and manifests ported

`deploy` directory is autogenerated, please extract generated changes to separate commit. You can trigger generation via `make update`
Choraden: > `deploy` directory is autogenerated, please extract generated changes to separate commit. You can trigger generation via `make update`

Right, thanks! 
zimnx: > > `deploy` directory is autogenerated, please extract generated changes to separate commit. You can trigger generation via `make update`
> 
> Right, thanks!

`examples` are also autogenerated, sorry for not pointing it out in previous comment. Please extract it too.
Choraden: > > > `deploy` directory is autogenerated, please extract generated changes to separate commit. You can trigger generation via `make update`
> > 
> > 
> > Right, thanks!
> 
> `examples` are also autogenerated, sorry for not pointing it out in previous comment. Please extract it too.
Not a problem, examples extracted. 
Choraden: > i think pdb v1 exists since 1.21 (pls double check)

correct

Which releases do you want me to bump? v1.7 only?


tnozicka: > Which releases do you want me to bump? v1.7 only?

You are shipping your changes to master, which is what's gonna be in 1.8 so you need to make a new column for 1.8 where you bump the requirements.
Choraden: Regarding the comments, I bumped: 
- Scylla OS to `>=4.6`
- Manager to `>=2.6`
- Monitoring `>=4.0`
vponomaryov: > > Which releases do you want me to bump? v1.7 only?
> 
> You are shipping your changes to master, which is what's gonna be in 1.8 so you need to make a new column for 1.8 where you bump the requirements.

I think this fix must also be ported back to the `v1.7.x` operator. Because the latest K8S version is not compatible with the latest operator version `already`.
So, I think we should either drop support for the `v1.20-` version or make the operator be smart enough and use different API versions on different K8S versions.
tnozicka: I don't wanna mess with multiple API version for a one timer. Given we have already claimed 1.7 will work on >=1.20 we should update it to `>=1.20 && < 1.25`. We'll support 1.25 in v1.8.
tnozicka: let's do it in this PR, the rest lgtm
Choraden: Should I apply the upper bound to earlier releases too? If so, is `<1.25` right to all of them? 

Patch:
diff --git a/deploy/manager/dev/10_controller_pdb.yaml b/deploy/manager/dev/10_controller_pdb.yaml
index ea8faca72..26ef238ac 100644
--- a/deploy/manager/dev/10_controller_pdb.yaml
+++ b/deploy/manager/dev/10_controller_pdb.yaml
@@ -1,4 +1,4 @@
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: scylla-manager-controller
diff --git a/deploy/manager/prod/10_controller_pdb.yaml b/deploy/manager/prod/10_controller_pdb.yaml
index ea8faca72..26ef238ac 100644
--- a/deploy/manager/prod/10_controller_pdb.yaml
+++ b/deploy/manager/prod/10_controller_pdb.yaml
@@ -1,4 +1,4 @@
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: scylla-manager-controller
diff --git a/deploy/operator/10_operator.pdb.yaml b/deploy/operator/10_operator.pdb.yaml
index a49eef267..8c11c15d7 100644
--- a/deploy/operator/10_operator.pdb.yaml
+++ b/deploy/operator/10_operator.pdb.yaml
@@ -1,4 +1,4 @@
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: scylla-operator
diff --git a/deploy/operator/10_webhookserver.pdb.yaml b/deploy/operator/10_webhookserver.pdb.yaml
index 963aedfd6..f320eafd3 100644
--- a/deploy/operator/10_webhookserver.pdb.yaml
+++ b/deploy/operator/10_webhookserver.pdb.yaml
@@ -1,4 +1,4 @@
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: webhook-server
diff --git a/docs/source/releases.md b/docs/source/releases.md
index 4f1f69b2b..9ef103b08 100644
--- a/docs/source/releases.md
+++ b/docs/source/releases.md
@@ -46,10 +46,10 @@ GA images aren't build from scratch but rather promoted from an existing release
 
 Support matrix table shows the version requirements for a particular **scylla-operator** version. Be sure to match these requirements, otherwise some functionality will not work.
 
-|                    | v1.7        | v1.6        | v1.5        | v1.4        | v1.3        | v1.2        | v1.1        | v1.0       |
-| :----------------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :---------: | :--------: |
-| Kubernetes         | `>=1.20`    | `>=1.19.10` | `>=1.19.10` | `>=1.19.10` | `>=1.19`    | `>=1.19`    | `>=1.11`    | `>=1.11`   |
-| Scylla OS          | `>=4.3`     | `>=4.3`     | `>=4.3`     | `>=4.3`     | `>=4.2`     | `>=4.2`     | `>=4.0`     | `>=4.0`    |
-| Scylla Enterprise  | `>=2021.1`  | `>=2021.1`  | `>=2021.1`  | `>=2021.1`  | `>=2020.1`  | `>=2020.1`  | `>=2020.1`  | `>=2020.1` |
-| Scylla Manager     | `>=2.2`     | `>=2.2`     | `>=2.2`     | `>=2.2`     | `>=2.2`     | `>=2.2`     | `>=2.2`     | `>=2.2`    |
-| Scylla Monitoring  | `>=3.0`     | `>=3.0`     | `>=1.0`     | `>=1.0`     | `>=1.0`     | `>=1.0`     | `>=1.0`     | `>=1.0`    |
+|                   |    v1.8    |       v1.7        |         v1.6         |    v1.5     |    v1.4     |    v1.3    |    v1.2    |    v1.1    |    v1.0    |
+|:-----------------:|:----------:|:-----------------:|:--------------------:|:-----------:|:-----------:|:----------:|:----------:|:----------:|:----------:|
+|    Kubernetes     |  `>=1.21`  | `>=1.20 && <1.25` | `>=1.19.10 && <1.25` | `>=1.19.10` | `>=1.19.10` |  `>=1.19`  |  `>=1.19`  |  `>=1.11`  |  `>=1.11`  |
+|     Scylla OS     |  `>=4.6`   |      `>=4.3`      |       `>=4.3`        |   `>=4.3`   |   `>=4.3`   |  `>=4.2`   |  `>=4.2`   |  `>=4.0`   |  `>=4.0`   |
+| Scylla Enterprise | `>=2021.1` |    `>=2021.1`     |      `>=2021.1`      | `>=2021.1`  | `>=2021.1`  | `>=2020.1` | `>=2020.1` | `>=2020.1` | `>=2020.1` |
+|  Scylla Manager   |  `>=2.6`   |      `>=2.2`      |       `>=2.2`        |   `>=2.2`   |   `>=2.2`   |  `>=2.2`   |  `>=2.2`   |  `>=2.2`   |  `>=2.2`   |
+| Scylla Monitoring |  `>=4.0`   |      `>=3.0`      |       `>=3.0`        |   `>=1.0`   |   `>=1.0`   |  `>=1.0`   |  `>=1.0`   |  `>=1.0`   |  `>=1.0`   |
diff --git a/examples/common/manager.yaml b/examples/common/manager.yaml
index 3d4df8fb9..9c95f9972 100644
--- a/examples/common/manager.yaml
+++ b/examples/common/manager.yaml
@@ -96,7 +96,7 @@ metadata:
   name: scylla-manager
 
 ---
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: scylla-manager-controller
diff --git a/examples/common/operator.yaml b/examples/common/operator.yaml
index eff54c006..104639bb2 100644
--- a/examples/common/operator.yaml
+++ b/examples/common/operator.yaml
@@ -2466,7 +2466,7 @@ spec:
   selfSigned: {}
 
 ---
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: scylla-operator
@@ -2519,7 +2519,7 @@ webhooks:
     - scyllaclusters
 
 ---
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: webhook-server
diff --git a/helm/scylla-manager/templates/controller_pdb.yaml b/helm/scylla-manager/templates/controller_pdb.yaml
index c2c191107..ca5e3aa57 100644
--- a/helm/scylla-manager/templates/controller_pdb.yaml
+++ b/helm/scylla-manager/templates/controller_pdb.yaml
@@ -1,4 +1,4 @@
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: scylla-manager-controller
diff --git a/helm/scylla-operator/templates/operator.pdb.yaml b/helm/scylla-operator/templates/operator.pdb.yaml
index 16ecd5c26..58149fe86 100644
--- a/helm/scylla-operator/templates/operator.pdb.yaml
+++ b/helm/scylla-operator/templates/operator.pdb.yaml
@@ -1,5 +1,5 @@
 {{- if gt .Values.replicas 1.0 }}
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: scylla-operator
diff --git a/helm/scylla-operator/templates/webhookserver.pdb.yaml b/helm/scylla-operator/templates/webhookserver.pdb.yaml
index 7272e95de..607bd7e16 100644
--- a/helm/scylla-operator/templates/webhookserver.pdb.yaml
+++ b/helm/scylla-operator/templates/webhookserver.pdb.yaml
@@ -1,5 +1,5 @@
 {{- if gt .Values.webhookServerReplicas 1.0 }}
-apiVersion: policy/v1beta1
+apiVersion: policy/v1
 kind: PodDisruptionBudget
 metadata:
   name: webhook-server
diff --git a/pkg/cmd/operator/operator.go b/pkg/cmd/operator/operator.go
index ac543a4e7..f6cc998c9 100644
--- a/pkg/cmd/operator/operator.go
+++ b/pkg/cmd/operator/operator.go
@@ -183,7 +183,7 @@ func (o *OperatorOptions) run(ctx context.Context, streams genericclioptions.IOS
 		kubeInformers.Core().V1().ServiceAccounts(),
 		kubeInformers.Rbac().V1().RoleBindings(),
 		kubeInformers.Apps().V1().StatefulSets(),
-		kubeInformers.Policy().V1beta1().PodDisruptionBudgets(),
+		kubeInformers.Policy().V1().PodDisruptionBudgets(),
 		kubeInformers.Networking().V1().Ingresses(),
 		scyllaInformers.Scylla().V1().ScyllaClusters(),
 		o.OperatorImage,
diff --git a/pkg/controller/scyllacluster/controller.go b/pkg/controller/scyllacluster/controller.go
index 1d8d279e1..050c256ce 100644
--- a/pkg/controller/scyllacluster/controller.go
+++ b/pkg/controller/scyllacluster/controller.go
@@ -15,7 +15,7 @@ import (
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	networkingv1 "k8s.io/api/networking/v1"
-	policyv1beta1 "k8s.io/api/policy/v1beta1"
+	policyv1 "k8s.io/api/policy/v1"
 	rbacv1 "k8s.io/api/rbac/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -26,14 +26,14 @@ import (
 	appsv1informers "k8s.io/client-go/informers/apps/v1"
 	corev1informers "k8s.io/client-go/informers/core/v1"
 	networkingv1informers "k8s.io/client-go/informers/networking/v1"
-	policyv1beta1informers "k8s.io/client-go/informers/policy/v1beta1"
+	policyv1informers "k8s.io/client-go/informers/policy/v1"
 	rbacv1informers "k8s.io/client-go/informers/rbac/v1"
 	"k8s.io/client-go/kubernetes"
 	corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
 	appsv1listers "k8s.io/client-go/listers/apps/v1"
 	corev1listers "k8s.io/client-go/listers/core/v1"
 	networkingv1listers "k8s.io/client-go/listers/networking/v1"
-	policyv1beta1listers "k8s.io/client-go/listers/policy/v1beta1"
+	policyv1listers "k8s.io/client-go/listers/policy/v1"
 	rbacv1listers "k8s.io/client-go/listers/rbac/v1"
 	"k8s.io/client-go/tools/cache"
 	"k8s.io/client-go/tools/record"
@@ -69,7 +69,7 @@ type Controller struct {
 	serviceAccountLister corev1listers.ServiceAccountLister
 	roleBindingLister    rbacv1listers.RoleBindingLister
 	statefulSetLister    appsv1listers.StatefulSetLister
-	pdbLister            policyv1beta1listers.PodDisruptionBudgetLister
+	pdbLister            policyv1listers.PodDisruptionBudgetLister
 	ingressLister        networkingv1listers.IngressLister
 	scyllaLister         scyllav1listers.ScyllaClusterLister
 
@@ -89,7 +89,7 @@ func NewController(
 	serviceAccountInformer corev1informers.ServiceAccountInformer,
 	roleBindingInformer rbacv1informers.RoleBindingInformer,
 	statefulSetInformer appsv1informers.StatefulSetInformer,
-	pdbInformer policyv1beta1informers.PodDisruptionBudgetInformer,
+	pdbInformer policyv1informers.PodDisruptionBudgetInformer,
 	ingressInformer networkingv1informers.IngressInformer,
 	scyllaClusterInformer scyllav1informers.ScyllaClusterInformer,
 	operatorImage string,
@@ -639,14 +639,14 @@ func (scc *Controller) deleteStatefulSet(obj interface{}) {
 }
 
 func (scc *Controller) addPodDisruptionBudget(obj interface{}) {
-	pdb := obj.(*policyv1beta1.PodDisruptionBudget)
+	pdb := obj.(*policyv1.PodDisruptionBudget)
 	klog.V(4).InfoS("Observed addition of PodDisruptionBudget", "PodDisruptionBudget", klog.KObj(pdb))
 	scc.enqueueOwner(pdb)
 }
 
 func (scc *Controller) updatePodDisruptionBudget(old, cur interface{}) {
-	oldPDB := old.(*policyv1beta1.PodDisruptionBudget)
-	currentPDB := cur.(*policyv1beta1.PodDisruptionBudget)
+	oldPDB := old.(*policyv1.PodDisruptionBudget)
+	currentPDB := cur.(*policyv1.PodDisruptionBudget)
 
 	if currentPDB.UID != oldPDB.UID {
 		key, err := keyFunc(oldPDB)
@@ -665,14 +665,14 @@ func (scc *Controller) updatePodDisruptionBudget(old, cur interface{}) {
 }
 
 func (scc *Controller) deletePodDisruptionBudget(obj interface{}) {
-	pdb, ok := obj.(*policyv1beta1.PodDisruptionBudget)
+	pdb, ok := obj.(*policyv1.PodDisruptionBudget)
 	if !ok {
 		tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
 		if !ok {
 			utilruntime.HandleError(fmt.Errorf("couldn't get object from tombstone %#v", obj))
 			return
 		}
-		pdb, ok = tombstone.Obj.(*policyv1beta1.PodDisruptionBudget)
+		pdb, ok = tombstone.Obj.(*policyv1.PodDisruptionBudget)
 		if !ok {
 			utilruntime.HandleError(fmt.Errorf("tombstone contained object that is not a PodDisruptionBudget %#v", obj))
 			return
diff --git a/pkg/controller/scyllacluster/resource.go b/pkg/controller/scyllacluster/resource.go
index dcdc0e594..e6847287e 100644
--- a/pkg/controller/scyllacluster/resource.go
+++ b/pkg/controller/scyllacluster/resource.go
@@ -12,7 +12,7 @@ import (
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	networkingv1 "k8s.io/api/networking/v1"
-	"k8s.io/api/policy/v1beta1"
+	policyv1 "k8s.io/api/policy/v1"
 	rbacv1 "k8s.io/api/rbac/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/api/resource"
@@ -619,9 +619,9 @@ func agentContainer(r scyllav1.RackSpec, c *scyllav1.ScyllaCluster) corev1.Conta
 	return cnt
 }
 
-func MakePodDisruptionBudget(c *scyllav1.ScyllaCluster) *v1beta1.PodDisruptionBudget {
+func MakePodDisruptionBudget(c *scyllav1.ScyllaCluster) *policyv1.PodDisruptionBudget {
 	maxUnavailable := intstr.FromInt(1)
-	return &v1beta1.PodDisruptionBudget{
+	return &policyv1.PodDisruptionBudget{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      naming.PodDisruptionBudgetName(c),
 			Namespace: c.Namespace,
@@ -630,7 +630,7 @@ func MakePodDisruptionBudget(c *scyllav1.ScyllaCluster) *v1beta1.PodDisruptionBu
 			},
 			Labels: naming.ClusterLabels(c),
 		},
-		Spec: v1beta1.PodDisruptionBudgetSpec{
+		Spec: policyv1.PodDisruptionBudgetSpec{
 			MaxUnavailable: &maxUnavailable,
 			Selector:       metav1.SetAsLabelSelector(naming.ClusterLabels(c)),
 		},
diff --git a/pkg/controller/scyllacluster/sync.go b/pkg/controller/scyllacluster/sync.go
index 99f534057..0517c8827 100644
--- a/pkg/controller/scyllacluster/sync.go
+++ b/pkg/controller/scyllacluster/sync.go
@@ -11,7 +11,7 @@ import (
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	networkingv1 "k8s.io/api/networking/v1"
-	policyv1beta1 "k8s.io/api/policy/v1beta1"
+	policyv1 "k8s.io/api/policy/v1"
 	rbacv1 "k8s.io/api/rbac/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -241,7 +241,7 @@ func (sac *Controller) getRoleBindings(ctx context.Context, sc *scyllav1.ScyllaC
 	return cm.ClaimRoleBindings(roleBindings)
 }
 
-func (scc *Controller) getPDBs(ctx context.Context, sc *scyllav1.ScyllaCluster) (map[string]*policyv1beta1.PodDisruptionBudget, error) {
+func (scc *Controller) getPDBs(ctx context.Context, sc *scyllav1.ScyllaCluster) (map[string]*policyv1.PodDisruptionBudget, error) {
 	// List all Pdbs to find even those that no longer match our selector.
 	// They will be orphaned in ClaimPdbs().
 	pdbs, err := scc.pdbLister.PodDisruptionBudgets(sc.Namespace).List(labels.Everything())
diff --git a/pkg/controller/scyllacluster/sync_pdb.go b/pkg/controller/scyllacluster/sync_pdb.go
index 160b641d8..c27f31a52 100644
--- a/pkg/controller/scyllacluster/sync_pdb.go
+++ b/pkg/controller/scyllacluster/sync_pdb.go
@@ -6,7 +6,7 @@ import (
 
 	scyllav1 "github.com/scylladb/scylla-operator/pkg/api/scylla/v1"
 	"github.com/scylladb/scylla-operator/pkg/resourceapply"
-	policyv1beta1 "k8s.io/api/policy/v1beta1"
+	policyv1 "k8s.io/api/policy/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	utilerrors "k8s.io/apimachinery/pkg/util/errors"
 )
@@ -15,7 +15,7 @@ func (scc *Controller) syncPodDisruptionBudgets(
 	ctx context.Context,
 	sc *scyllav1.ScyllaCluster,
 	status *scyllav1.ScyllaClusterStatus,
-	pdbs map[string]*policyv1beta1.PodDisruptionBudget,
+	pdbs map[string]*policyv1.PodDisruptionBudget,
 ) (*scyllav1.ScyllaClusterStatus, error) {
 	var err error
 
@@ -34,7 +34,7 @@ func (scc *Controller) syncPodDisruptionBudgets(
 		}
 
 		propagationPolicy := metav1.DeletePropagationBackground
-		err = scc.kubeClient.PolicyV1beta1().PodDisruptionBudgets(pdb.Namespace).Delete(ctx, pdb.Name, metav1.DeleteOptions{
+		err = scc.kubeClient.PolicyV1().PodDisruptionBudgets(pdb.Namespace).Delete(ctx, pdb.Name, metav1.DeleteOptions{
 			Preconditions: &metav1.Preconditions{
 				UID: &pdb.UID,
 			},
@@ -48,7 +48,7 @@ func (scc *Controller) syncPodDisruptionBudgets(
 	}
 
 	// TODO: Remove forced ownership in v1.5 (#672)
-	_, _, err = resourceapply.ApplyPodDisruptionBudget(ctx, scc.kubeClient.PolicyV1beta1(), scc.pdbLister, scc.eventRecorder, requiredPDB, true)
+	_, _, err = resourceapply.ApplyPodDisruptionBudget(ctx, scc.kubeClient.PolicyV1(), scc.pdbLister, scc.eventRecorder, requiredPDB, true)
 	if err != nil {
 		return status, fmt.Errorf("can't apply pdb: %w", err)
 	}
diff --git a/pkg/controllertools/pdbmanager.go b/pkg/controllertools/pdbmanager.go
index de163623e..98108b0c4 100644
--- a/pkg/controllertools/pdbmanager.go
+++ b/pkg/controllertools/pdbmanager.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 
 	kubecontroller "github.com/scylladb/scylla-operator/pkg/thirdparty/k8s.io/kubernetes/pkg/controller"
-	policyv1beta1 "k8s.io/api/policy/v1beta1"
+	policyv1 "k8s.io/api/policy/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
@@ -29,7 +29,7 @@ type RealPodDisruptionBudgetControl struct {
 var _ PodDisruptionBudgetControlInterface = &RealPodDisruptionBudgetControl{}
 
 func (r RealPodDisruptionBudgetControl) PatchPodDisruptionBudget(ctx context.Context, namespace, name string, pt types.PatchType, data []byte, options metav1.PatchOptions) error {
-	_, err := r.KubeClient.PolicyV1beta1().PodDisruptionBudgets(namespace).Patch(ctx, name, pt, data, options)
+	_, err := r.KubeClient.PolicyV1().PodDisruptionBudgets(namespace).Patch(ctx, name, pt, data, options)
 	return err
 }
 
@@ -60,18 +60,18 @@ func NewPodDisruptionBudgetControllerRefManager(
 	}
 }
 
-func (m *PodDisruptionBudgetControllerRefManager) ClaimPodDisruptionBudgets(podDisruptionBudgets []*policyv1beta1.PodDisruptionBudget) (map[string]*policyv1beta1.PodDisruptionBudget, error) {
+func (m *PodDisruptionBudgetControllerRefManager) ClaimPodDisruptionBudgets(podDisruptionBudgets []*policyv1.PodDisruptionBudget) (map[string]*policyv1.PodDisruptionBudget, error) {
 	match := func(obj metav1.Object) bool {
 		return m.Selector.Matches(labels.Set(obj.GetLabels()))
 	}
 	adopt := func(obj metav1.Object) error {
-		return m.AdoptPodDisruptionBudget(obj.(*policyv1beta1.PodDisruptionBudget))
+		return m.AdoptPodDisruptionBudget(obj.(*policyv1.PodDisruptionBudget))
 	}
 	release := func(obj metav1.Object) error {
-		return m.ReleasePodDisruptionBudget(obj.(*policyv1beta1.PodDisruptionBudget))
+		return m.ReleasePodDisruptionBudget(obj.(*policyv1.PodDisruptionBudget))
 	}
 
-	claimedMap := make(map[string]*policyv1beta1.PodDisruptionBudget, len(podDisruptionBudgets))
+	claimedMap := make(map[string]*policyv1.PodDisruptionBudget, len(podDisruptionBudgets))
 	var errors []error
 	for _, podDisruptionBudget := range podDisruptionBudgets {
 		ok, err := m.ClaimObject(podDisruptionBudget, match, adopt, release)
@@ -86,7 +86,7 @@ func (m *PodDisruptionBudgetControllerRefManager) ClaimPodDisruptionBudgets(podD
 	return claimedMap, utilerrors.NewAggregate(errors)
 }
 
-func (m *PodDisruptionBudgetControllerRefManager) AdoptPodDisruptionBudget(podDisruptionBudget *policyv1beta1.PodDisruptionBudget) error {
+func (m *PodDisruptionBudgetControllerRefManager) AdoptPodDisruptionBudget(podDisruptionBudget *policyv1.PodDisruptionBudget) error {
 	err := m.CanAdopt()
 	if err != nil {
 		return fmt.Errorf("can't adopt PodDisruptionBudget %v/%v (%v): %v", podDisruptionBudget.Namespace, podDisruptionBudget.Name, podDisruptionBudget.UID, err)
@@ -102,7 +102,7 @@ func (m *PodDisruptionBudgetControllerRefManager) AdoptPodDisruptionBudget(podDi
 	return m.PodDisruptionBudgetControl.PatchPodDisruptionBudget(m.ctx, podDisruptionBudget.Namespace, podDisruptionBudget.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{})
 }
 
-func (m *PodDisruptionBudgetControllerRefManager) ReleasePodDisruptionBudget(podDisruptionBudget *policyv1beta1.PodDisruptionBudget) error {
+func (m *PodDisruptionBudgetControllerRefManager) ReleasePodDisruptionBudget(podDisruptionBudget *policyv1.PodDisruptionBudget) error {
 	klog.V(2).InfoS("Patching PodDisruptionBudget to remove its controllerRef",
 		"PodDisruptionBudget",
 		klog.KObj(podDisruptionBudget),
diff --git a/pkg/resourceapply/policy.go b/pkg/resourceapply/policy.go
index ab9e8d19d..2634f858e 100644
--- a/pkg/resourceapply/policy.go
+++ b/pkg/resourceapply/policy.go
@@ -8,11 +8,11 @@ import (
 
 	"github.com/scylladb/scylla-operator/pkg/naming"
 	"github.com/scylladb/scylla-operator/pkg/resourcemerge"
-	policyv1beta1 "k8s.io/api/policy/v1beta1"
+	policyv1 "k8s.io/api/policy/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	policyv1beta1client "k8s.io/client-go/kubernetes/typed/policy/v1beta1"
-	policyv1beta1listers "k8s.io/client-go/listers/policy/v1beta1"
+	policyv1client "k8s.io/client-go/kubernetes/typed/policy/v1"
+	policyv1listers "k8s.io/client-go/listers/policy/v1"
 	"k8s.io/client-go/tools/record"
 	"k8s.io/klog/v2"
 )
@@ -22,12 +22,12 @@ import (
 // would be adopted but the old objects may not have correct labels that we need to fix in the new version.
 func ApplyPodDisruptionBudget(
 	ctx context.Context,
-	client policyv1beta1client.PodDisruptionBudgetsGetter,
-	lister policyv1beta1listers.PodDisruptionBudgetLister,
+	client policyv1client.PodDisruptionBudgetsGetter,
+	lister policyv1listers.PodDisruptionBudgetLister,
 	recorder record.EventRecorder,
-	required *policyv1beta1.PodDisruptionBudget,
+	required *policyv1.PodDisruptionBudget,
 	forceOwnership bool,
-) (*policyv1beta1.PodDisruptionBudget, bool, error) {
+) (*policyv1.PodDisruptionBudget, bool, error) {
 	requiredControllerRef := metav1.GetControllerOfNoCopy(required)
 	if requiredControllerRef == nil {
 		return nil, false, fmt.Errorf("poddisruptionbudget %q is missing controllerRef", naming.ObjRef(required))


Test patch:
diff --git a/pkg/resourceapply/policy_test.go b/pkg/resourceapply/policy_test.go
index 5a61acf85..1f4dca6e6 100644
--- a/pkg/resourceapply/policy_test.go
+++ b/pkg/resourceapply/policy_test.go
@@ -8,7 +8,7 @@ import (
 	"time"
 
 	"github.com/google/go-cmp/cmp"
-	policyv1beta1 "k8s.io/api/policy/v1beta1"
+	policyv1 "k8s.io/api/policy/v1"
 	"k8s.io/apimachinery/pkg/api/equality"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -16,7 +16,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 	"k8s.io/client-go/kubernetes/fake"
-	policyv1beta1listers "k8s.io/client-go/listers/policy/v1beta1"
+	policyv1listers "k8s.io/client-go/listers/policy/v1"
 	"k8s.io/client-go/tools/cache"
 	"k8s.io/client-go/tools/record"
 	"k8s.io/utils/pointer"
@@ -24,8 +24,8 @@ import (
 
 func TestApplyPodDisruptionBudget(t *testing.T) {
 	// Using a generating function prevents unwanted mutations.
-	newPDB := func() *policyv1beta1.PodDisruptionBudget {
-		return &policyv1beta1.PodDisruptionBudget{
+	newPDB := func() *policyv1.PodDisruptionBudget {
+		return &policyv1.PodDisruptionBudget{
 			ObjectMeta: metav1.ObjectMeta{
 				Namespace: "default",
 				Name:      "test",
@@ -41,7 +41,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 					},
 				},
 			},
-			Spec: policyv1beta1.PodDisruptionBudgetSpec{
+			Spec: policyv1.PodDisruptionBudgetSpec{
 				Selector: &metav1.LabelSelector{
 					MatchLabels: map[string]string{},
 				},
@@ -49,7 +49,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		}
 	}
 
-	newPDBWithHash := func() *policyv1beta1.PodDisruptionBudget {
+	newPDBWithHash := func() *policyv1.PodDisruptionBudget {
 		pdb := newPDB()
 		utilruntime.Must(SetHashAnnotation(pdb))
 		return pdb
@@ -59,9 +59,9 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		name            string
 		existing        []runtime.Object
 		cache           []runtime.Object // nil cache means autofill from the client
-		required        *policyv1beta1.PodDisruptionBudget
+		required        *policyv1.PodDisruptionBudget
 		forceOwnership  bool
-		expectedPDB     *policyv1beta1.PodDisruptionBudget
+		expectedPDB     *policyv1.PodDisruptionBudget
 		expectedChanged bool
 		expectedErr     error
 		expectedEvents  []string
@@ -111,7 +111,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		{
 			name:     "fails to create the pdb without a controllerRef",
 			existing: nil,
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.OwnerReferences = nil
 				return pdb
@@ -126,12 +126,12 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 			existing: []runtime.Object{
 				newPDB(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Spec.Selector.MatchLabels["foo"] = "bar"
 				return pdb
 			}(),
-			expectedPDB: func() *policyv1beta1.PodDisruptionBudget {
+			expectedPDB: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Spec.Selector.MatchLabels["foo"] = "bar"
 				utilruntime.Must(SetHashAnnotation(pdb))
@@ -146,12 +146,12 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 			existing: []runtime.Object{
 				newPDBWithHash(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Labels["foo"] = "bar"
 				return pdb
 			}(),
-			expectedPDB: func() *policyv1beta1.PodDisruptionBudget {
+			expectedPDB: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Labels["foo"] = "bar"
 				utilruntime.Must(SetHashAnnotation(pdb))
@@ -164,7 +164,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		{
 			name: "won't update the pdb if an admission changes the sts",
 			existing: []runtime.Object{
-				func() *policyv1beta1.PodDisruptionBudget {
+				func() *policyv1.PodDisruptionBudget {
 					pdb := newPDBWithHash()
 					// Simulate admission by changing a value after the hash is computed.
 					pdb.Spec.Selector.MatchLabels["foo"] = "admissionchange"
@@ -172,7 +172,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 				}(),
 			},
 			required: newPDB(),
-			expectedPDB: func() *policyv1beta1.PodDisruptionBudget {
+			expectedPDB: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDBWithHash()
 				// Simulate admission by changing a value after the hash is computed.
 				pdb.Spec.Selector.MatchLabels["foo"] = "admissionchange"
@@ -186,19 +186,19 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 			// We test propagating the RV from required in all the other tests.
 			name: "specifying no RV will use the one from the existing object",
 			existing: []runtime.Object{
-				func() *policyv1beta1.PodDisruptionBudget {
+				func() *policyv1.PodDisruptionBudget {
 					pdb := newPDBWithHash()
 					pdb.ResourceVersion = "21"
 					return pdb
 				}(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.ResourceVersion = ""
 				pdb.Labels["foo"] = "bar"
 				return pdb
 			}(),
-			expectedPDB: func() *policyv1beta1.PodDisruptionBudget {
+			expectedPDB: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.ResourceVersion = "21"
 				pdb.Labels["foo"] = "bar"
@@ -215,27 +215,27 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 			cache: []runtime.Object{
 				newPDBWithHash(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Labels["foo"] = "bar"
 				return pdb
 			}(),
 			expectedPDB:     nil,
 			expectedChanged: false,
-			expectedErr:     fmt.Errorf("can't update pdb: %w", apierrors.NewNotFound(policyv1beta1.Resource("poddisruptionbudgets"), "test")),
+			expectedErr:     fmt.Errorf("can't update pdb: %w", apierrors.NewNotFound(policyv1.Resource("poddisruptionbudgets"), "test")),
 			expectedEvents:  []string{`Warning UpdatePodDisruptionBudgetFailed Failed to update PodDisruptionBudget default/test: poddisruptionbudgets.policy "test" not found`},
 		},
 		{
 			name: "update fails if the existing object has no ownerRef",
 			existing: []runtime.Object{
-				func() *policyv1beta1.PodDisruptionBudget {
+				func() *policyv1.PodDisruptionBudget {
 					pdb := newPDB()
 					pdb.OwnerReferences = nil
 					utilruntime.Must(SetHashAnnotation(pdb))
 					return pdb
 				}(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Labels["foo"] = "bar"
 				return pdb
@@ -248,20 +248,20 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		{
 			name: "forced update succeeds if the existing object has no ownerRef",
 			existing: []runtime.Object{
-				func() *policyv1beta1.PodDisruptionBudget {
+				func() *policyv1.PodDisruptionBudget {
 					pdb := newPDB()
 					pdb.OwnerReferences = nil
 					utilruntime.Must(SetHashAnnotation(pdb))
 					return pdb
 				}(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Labels["foo"] = "bar"
 				return pdb
 			}(),
 			forceOwnership: true,
-			expectedPDB: func() *policyv1beta1.PodDisruptionBudget {
+			expectedPDB: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Labels["foo"] = "bar"
 				utilruntime.Must(SetHashAnnotation(pdb))
@@ -274,18 +274,18 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		{
 			name: "update succeeds to replace ownerRef kind",
 			existing: []runtime.Object{
-				func() *policyv1beta1.PodDisruptionBudget {
+				func() *policyv1.PodDisruptionBudget {
 					pdb := newPDB()
 					pdb.OwnerReferences[0].Kind = "WrongKind"
 					utilruntime.Must(SetHashAnnotation(pdb))
 					return pdb
 				}(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				return pdb
 			}(),
-			expectedPDB: func() *policyv1beta1.PodDisruptionBudget {
+			expectedPDB: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				utilruntime.Must(SetHashAnnotation(pdb))
 				return pdb
@@ -297,14 +297,14 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		{
 			name: "update fails if the existing object is owned by someone else",
 			existing: []runtime.Object{
-				func() *policyv1beta1.PodDisruptionBudget {
+				func() *policyv1.PodDisruptionBudget {
 					pdb := newPDB()
 					pdb.OwnerReferences[0].UID = "42"
 					utilruntime.Must(SetHashAnnotation(pdb))
 					return pdb
 				}(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Labels["foo"] = "bar"
 				return pdb
@@ -317,14 +317,14 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		{
 			name: "forced update fails if the existing object is owned by someone else",
 			existing: []runtime.Object{
-				func() *policyv1beta1.PodDisruptionBudget {
+				func() *policyv1.PodDisruptionBudget {
 					pdb := newPDB()
 					pdb.OwnerReferences[0].UID = "42"
 					utilruntime.Must(SetHashAnnotation(pdb))
 					return pdb
 				}(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Labels["foo"] = "bar"
 				return pdb
@@ -338,7 +338,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		{
 			name: "all label and annotation keys are kept when the hash matches",
 			existing: []runtime.Object{
-				func() *policyv1beta1.PodDisruptionBudget {
+				func() *policyv1.PodDisruptionBudget {
 					pdb := newPDB()
 					pdb.Annotations = map[string]string{
 						"a-1":  "a-alpha",
@@ -360,7 +360,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 					return pdb
 				}(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Annotations = map[string]string{
 					"a-1":  "a-alpha",
@@ -375,7 +375,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 				return pdb
 			}(),
 			forceOwnership: false,
-			expectedPDB: func() *policyv1beta1.PodDisruptionBudget {
+			expectedPDB: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Annotations = map[string]string{
 					"a-1":  "a-alpha",
@@ -403,7 +403,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 		{
 			name: "only managed label and annotation keys are updated when the hash changes",
 			existing: []runtime.Object{
-				func() *policyv1beta1.PodDisruptionBudget {
+				func() *policyv1.PodDisruptionBudget {
 					pdb := newPDB()
 					pdb.Annotations = map[string]string{
 						"a-1":  "a-alpha",
@@ -423,7 +423,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 					return pdb
 				}(),
 			},
-			required: func() *policyv1beta1.PodDisruptionBudget {
+			required: func() *policyv1.PodDisruptionBudget {
 				pdb := newPDB()
 				pdb.Annotations = map[string]string{
 					"a-1":  "a-alpha-x",
@@ -438,7 +438,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 				return pdb
 			}(),
 			forceOwnership: true,
-			expectedPDB: func() *policyv1beta1.PodDisruptionBudget {
+			expectedPDB: func() *policyv1.PodDisruptionBudget {
 				podDisruptionBudget := newPDB()
 				podDisruptionBudget.Annotations = map[string]string{
 					"a-1":  "a-alpha-x",
@@ -485,7 +485,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 					recorder := record.NewFakeRecorder(10)
 
 					pdbCache := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
-					pdbLister := policyv1beta1listers.NewPodDisruptionBudgetLister(pdbCache)
+					pdbLister := policyv1listers.NewPodDisruptionBudgetLister(pdbCache)
 
 					if tc.cache != nil {
 						for _, obj := range tc.cache {
@@ -495,7 +495,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 							}
 						}
 					} else {
-						pdbList, err := client.PolicyV1beta1().PodDisruptionBudgets("").List(ctx, metav1.ListOptions{
+						pdbList, err := client.PolicyV1().PodDisruptionBudgets("").List(ctx, metav1.ListOptions{
 							LabelSelector: labels.Everything().String(),
 						})
 						if err != nil {
@@ -510,7 +510,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 						}
 					}
 
-					gotSts, gotChanged, gotErr := ApplyPodDisruptionBudget(ctx, client.PolicyV1beta1(), pdbLister, recorder, tc.required, tc.forceOwnership)
+					gotSts, gotChanged, gotErr := ApplyPodDisruptionBudget(ctx, client.PolicyV1(), pdbLister, recorder, tc.required, tc.forceOwnership)
 					if !reflect.DeepEqual(gotErr, tc.expectedErr) {
 						t.Fatalf("expected %v, got %v", tc.expectedErr, gotErr)
 					}
@@ -521,7 +521,7 @@ func TestApplyPodDisruptionBudget(t *testing.T) {
 
 					// Make sure such object was actually created.
 					if gotSts != nil {
-						createdSts, err := client.PolicyV1beta1().PodDisruptionBudgets(gotSts.Namespace).Get(ctx, gotSts.Name, metav1.GetOptions{})
+						createdSts, err := client.PolicyV1().PodDisruptionBudgets(gotSts.Namespace).Get(ctx, gotSts.Name, metav1.GetOptions{})
 						if err != nil {
 							t.Error(err)
 						}
diff --git a/test/e2e/set/scyllacluster/verify.go b/test/e2e/set/scyllacluster/verify.go
index eba356d5d..f3e3d1fb8 100644
--- a/test/e2e/set/scyllacluster/verify.go
+++ b/test/e2e/set/scyllacluster/verify.go
@@ -11,7 +11,7 @@ import (
 	"github.com/scylladb/scylla-operator/test/e2e/framework"
 	"github.com/scylladb/scylla-operator/test/e2e/utils"
 	appsv1 "k8s.io/api/apps/v1"
-	policyv1beta1 "k8s.io/api/policy/v1beta1"
+	policyv1 "k8s.io/api/policy/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/kubernetes"
 	corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -63,7 +63,7 @@ func verifyStatefulset(sts *appsv1.StatefulSet) {
 	o.Expect(sts.Status.CurrentRevision).To(o.Equal(sts.Status.UpdateRevision))
 }
 
-func verifyPodDisruptionBudget(sc *scyllav1.ScyllaCluster, pdb *policyv1beta1.PodDisruptionBudget) {
+func verifyPodDisruptionBudget(sc *scyllav1.ScyllaCluster, pdb *policyv1.PodDisruptionBudget) {
 	o.Expect(pdb.ObjectMeta.OwnerReferences).To(o.BeEquivalentTo(
 		[]metav1.OwnerReference{
 			{
@@ -110,7 +110,7 @@ func verifyScyllaCluster(ctx context.Context, kubeClient kubernetes.Interface, s
 		o.Expect(sc.Status.Upgrade.FromVersion).To(o.Equal(sc.Status.Upgrade.ToVersion))
 	}
 
-	pdb, err := kubeClient.PolicyV1beta1().PodDisruptionBudgets(sc.Namespace).Get(ctx, naming.PodDisruptionBudgetName(sc), metav1.GetOptions{})
+	pdb, err := kubeClient.PolicyV1().PodDisruptionBudgets(sc.Namespace).Get(ctx, naming.PodDisruptionBudgetName(sc), metav1.GetOptions{})
 	o.Expect(err).NotTo(o.HaveOccurred())
 	verifyPodDisruptionBudget(sc, pdb)