@@ -1375,6 +1375,18 @@ func (r *SliceGwReconciler) ReconcileGatewayDeployments(ctx context.Context, sli
1375
1375
}
1376
1376
}
1377
1377
1378
+ // Create PodDisruptionBudget for slice gateway's pod to at least have 1 instance of pods on each worker
1379
+ // when disruption has occurred.
1380
+ //
1381
+ // Note: This should run an attempt to create PDB regardless of whether current reconciliation creating deployments
1382
+ // as the request could've been requeued due to failure at the creation of PDB.
1383
+ if err = r .createPodDisruptionBudgetForSliceGatewayPods (ctx , sliceName , sliceGw ); err != nil {
1384
+ log .Error (err , "Failed to create PodDisruptionBudget for SliceGW deployments" ,
1385
+ "SliceName" , sliceName , "SliceGwName" , sliceGwName )
1386
+
1387
+ return ctrl.Result {}, err , true
1388
+ }
1389
+
1378
1390
// Reconcile deployment to node port mapping for gw client deployments
1379
1391
if isClient (sliceGw ) {
1380
1392
for _ , deployment := range deployments .Items {
@@ -1534,3 +1546,56 @@ func (r *SliceGwReconciler) ReconcileIntermediateGatewayDeployments(ctx context.
1534
1546
1535
1547
return ctrl.Result {}, nil , false
1536
1548
}
1549
+
1550
+ // createPodDisruptionBudgetForSliceGatewayPods checks for PodDisruptionBudget objects in the cluster that match the
1551
+ // slice gateway pods, and if missing, it creates a PDB with minimum availability of 1 so at least one pod remains in
1552
+ // case of a disruption.
1553
+ func (r * SliceGwReconciler ) createPodDisruptionBudgetForSliceGatewayPods (ctx context.Context ,
1554
+ sliceName string , sliceGateway * kubeslicev1beta1.SliceGateway ) error {
1555
+ log := r .Log .WithValues ("sliceName" , sliceName , "sliceGwName" , sliceGateway .Name )
1556
+
1557
+ // List PDBs in cluster that match the slice gateway pods
1558
+ pdbs , err := listPodDisruptionBudgetForSliceGateway (ctx , r .Client , sliceName , sliceGateway .Name )
1559
+ if err != nil && ! apierrors .IsNotFound (err ) {
1560
+ log .Error (err , "failed to list PodDisruptionBudgets that match the slice gateway" )
1561
+
1562
+ // When some unexpected error occurred, return the error for requeuing the request
1563
+ return err
1564
+ }
1565
+
1566
+ // Check if PDB already exists that matches the current slice gateway
1567
+ if len (pdbs ) > 0 {
1568
+ // PodDisruptionBudget matching the slice gateway already exists. Skipping creation.
1569
+ return nil
1570
+ }
1571
+
1572
+ // Create PDB manifest with minimum availability of 1 pod
1573
+ pdb := constructPodDisruptionBudget (sliceName , sliceGateway .Name , DefaultMinAvailablePodsInPDB )
1574
+
1575
+ // Set SliceGateway instance as the owner and controller for PDB
1576
+ if err = ctrl .SetControllerReference (sliceGateway , pdb , r .Scheme ); err != nil {
1577
+ log .Error (err , "Failed to set slice gateway as owner to PodDisruptionBudget" ,
1578
+ "pdb" , pdb .Name )
1579
+
1580
+ return fmt .Errorf ("failed to set slice gateway %q as owner to PodDisruptionBudget %q: %v" ,
1581
+ sliceGateway .Name , pdb .Name , err )
1582
+ }
1583
+
1584
+ // Create PDB for slice gateway's pod to have at least 1 pod on each worker when disruption occurs
1585
+ if err = r .Create (ctx , pdb ); err != nil {
1586
+ if apierrors .IsAlreadyExists (err ) {
1587
+ // PDB is already exists. So, ignoring the current request.
1588
+ return nil
1589
+ }
1590
+
1591
+ log .Error (err , "PodDisruptionBudget creation failed" , "pdb" , pdb .Name )
1592
+
1593
+ // When any other unexpected error occurred when attempting to create PDB, fail the request
1594
+ return fmt .Errorf ("failed to create PodDisruptionBudget for SliceGW pods: %v" , err )
1595
+ }
1596
+
1597
+ // PDB created successfully
1598
+ log .Info ("PodDisruptionBudget for slice gateway pods created successfully" )
1599
+
1600
+ return nil
1601
+ }
0 commit comments