Skip to content

Commit 14175f2

Browse files
kyrtapzjcaamano
authored andcommitted
(C)UDN Controller: use rate limiting instead of delayed addition, do not update conditions unnecessarily
Replace custom condition update logic with standard k8s meta.SetStatusCondition to avoid updating condtions even if they haven't changed. Use rate limiting instead of fixed interval requeuing for network-in-use errors. Signed-off-by: Patryk Diak <[email protected]>
1 parent c3ddbad commit 14175f2

File tree

3 files changed

+58
-65
lines changed

3 files changed

+58
-65
lines changed

go-controller/pkg/clustermanager/userdefinednetwork/controller.go

Lines changed: 50 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
netv1lister "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/client/listers/k8s.cni.cncf.io/v1"
1616

1717
apierrors "k8s.io/apimachinery/pkg/api/errors"
18+
"k8s.io/apimachinery/pkg/api/meta"
1819
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1920
"k8s.io/apimachinery/pkg/labels"
2021
"k8s.io/apimachinery/pkg/util/sets"
@@ -87,8 +88,6 @@ type Controller struct {
8788
eventRecorder record.EventRecorder
8889
}
8990

90-
const defaultNetworkInUseCheckInterval = 1 * time.Minute
91-
9291
func New(
9392
nadClient netv1clientset.Interface,
9493
nadInfomer netv1infomer.NetworkAttachmentDefinitionInformer,
@@ -104,18 +103,17 @@ func New(
104103
udnLister := udnInformer.Lister()
105104
cudnLister := cudnInformer.Lister()
106105
c := &Controller{
107-
nadClient: nadClient,
108-
nadLister: nadInfomer.Lister(),
109-
udnClient: udnClient,
110-
udnLister: udnLister,
111-
cudnLister: cudnLister,
112-
renderNadFn: renderNadFn,
113-
podInformer: podInformer,
114-
namespaceInformer: namespaceInformer,
115-
networkManager: networkManager,
116-
networkInUseRequeueInterval: defaultNetworkInUseCheckInterval,
117-
namespaceTracker: map[string]sets.Set[string]{},
118-
eventRecorder: eventRecorder,
106+
nadClient: nadClient,
107+
nadLister: nadInfomer.Lister(),
108+
udnClient: udnClient,
109+
udnLister: udnLister,
110+
cudnLister: cudnLister,
111+
renderNadFn: renderNadFn,
112+
podInformer: podInformer,
113+
namespaceInformer: namespaceInformer,
114+
networkManager: networkManager,
115+
namespaceTracker: map[string]sets.Set[string]{},
116+
eventRecorder: eventRecorder,
119117
}
120118
udnCfg := &controller.ControllerConfig[userdefinednetworkv1.UserDefinedNetwork]{
121119
RateLimiter: workqueue.DefaultTypedControllerRateLimiter[string](),
@@ -389,7 +387,8 @@ func (c *Controller) reconcileUDN(key string) error {
389387

390388
var networkInUse *networkInUseError
391389
if errors.As(syncErr, &networkInUse) {
392-
c.udnController.ReconcileAfter(key, c.networkInUseRequeueInterval)
390+
// Call ReconcileRateLimited directly to ensure retries without the default limits
391+
c.udnController.ReconcileRateLimited(key)
393392
return updateStatusErr
394393
}
395394

@@ -452,34 +451,34 @@ func (c *Controller) updateUserDefinedNetworkStatus(udn *userdefinednetworkv1.Us
452451

453452
networkCreatedCondition := newNetworkCreatedCondition(nad, syncError)
454453

455-
conditions, updated := updateCondition(udn.Status.Conditions, networkCreatedCondition)
454+
updated := meta.SetStatusCondition(&udn.Status.Conditions, *networkCreatedCondition)
455+
if !updated {
456+
return nil
457+
}
456458

457-
if updated {
458-
var err error
459-
conditionsApply := make([]*metaapplyv1.ConditionApplyConfiguration, len(conditions))
460-
for i := range conditions {
461-
conditionsApply[i] = &metaapplyv1.ConditionApplyConfiguration{
462-
Type: &conditions[i].Type,
463-
Status: &conditions[i].Status,
464-
LastTransitionTime: &conditions[i].LastTransitionTime,
465-
Reason: &conditions[i].Reason,
466-
Message: &conditions[i].Message,
467-
}
459+
var err error
460+
conditionsApply := make([]*metaapplyv1.ConditionApplyConfiguration, len(udn.Status.Conditions))
461+
for i, condition := range udn.Status.Conditions {
462+
conditionsApply[i] = &metaapplyv1.ConditionApplyConfiguration{
463+
Type: &condition.Type,
464+
Status: &condition.Status,
465+
LastTransitionTime: &condition.LastTransitionTime,
466+
Reason: &condition.Reason,
467+
Message: &condition.Message,
468468
}
469-
udnApplyConf := udnapplyconfkv1.UserDefinedNetwork(udn.Name, udn.Namespace).
470-
WithStatus(udnapplyconfkv1.UserDefinedNetworkStatus().
471-
WithConditions(conditionsApply...))
472-
opts := metav1.ApplyOptions{FieldManager: "user-defined-network-controller"}
473-
udn, err = c.udnClient.K8sV1().UserDefinedNetworks(udn.Namespace).ApplyStatus(context.Background(), udnApplyConf, opts)
474-
if err != nil {
475-
if apierrors.IsNotFound(err) {
476-
return nil
477-
}
478-
return fmt.Errorf("failed to update UserDefinedNetwork status: %w", err)
469+
}
470+
udnApplyConf := udnapplyconfkv1.UserDefinedNetwork(udn.Name, udn.Namespace).
471+
WithStatus(udnapplyconfkv1.UserDefinedNetworkStatus().
472+
WithConditions(conditionsApply...))
473+
opts := metav1.ApplyOptions{FieldManager: "user-defined-network-controller"}
474+
udn, err = c.udnClient.K8sV1().UserDefinedNetworks(udn.Namespace).ApplyStatus(context.Background(), udnApplyConf, opts)
475+
if err != nil {
476+
if apierrors.IsNotFound(err) {
477+
return nil
479478
}
480-
klog.Infof("Updated status UserDefinedNetwork [%s/%s]", udn.Namespace, udn.Name)
479+
return fmt.Errorf("failed to update UserDefinedNetwork status: %w", err)
481480
}
482-
481+
klog.Infof("Updated status UserDefinedNetwork [%s/%s]", udn.Namespace, udn.Name)
483482
return nil
484483
}
485484

@@ -507,21 +506,6 @@ func newNetworkCreatedCondition(nad *netv1.NetworkAttachmentDefinition, syncErro
507506
return networkCreatedCondition
508507
}
509508

510-
func updateCondition(conditions []metav1.Condition, cond *metav1.Condition) ([]metav1.Condition, bool) {
511-
if len(conditions) == 0 {
512-
return append(conditions, *cond), true
513-
}
514-
515-
idx := slices.IndexFunc(conditions, func(c metav1.Condition) bool {
516-
return (c.Type == cond.Type) &&
517-
(c.Status != cond.Status || c.Reason != cond.Reason || c.Message != cond.Message)
518-
})
519-
if idx != -1 {
520-
return slices.Replace(conditions, idx, idx+1, *cond), true
521-
}
522-
return conditions, false
523-
}
524-
525509
func (c *Controller) cudnNeedUpdate(_ *userdefinednetworkv1.ClusterUserDefinedNetwork, _ *userdefinednetworkv1.ClusterUserDefinedNetwork) bool {
526510
return true
527511
}
@@ -549,7 +533,8 @@ func (c *Controller) reconcileCUDN(key string) error {
549533

550534
var networkInUse *networkInUseError
551535
if errors.As(syncErr, &networkInUse) {
552-
c.cudnController.ReconcileAfter(key, c.networkInUseRequeueInterval)
536+
// Call ReconcileRateLimited directly to ensure retries without the default limits
537+
c.cudnController.ReconcileRateLimited(key)
553538
return updateStatusErr
554539
}
555540

@@ -688,18 +673,18 @@ func (c *Controller) updateClusterUDNStatus(cudn *userdefinednetworkv1.ClusterUs
688673

689674
networkCreatedCondition := newClusterNetworCreatedCondition(nads, syncError)
690675

691-
conditions, updated := updateCondition(cudn.Status.Conditions, networkCreatedCondition)
676+
updated := meta.SetStatusCondition(&cudn.Status.Conditions, networkCreatedCondition)
692677
if !updated {
693678
return nil
694679
}
695-
conditionsApply := make([]*metaapplyv1.ConditionApplyConfiguration, len(conditions))
696-
for i := range conditions {
680+
conditionsApply := make([]*metaapplyv1.ConditionApplyConfiguration, len(cudn.Status.Conditions))
681+
for i, condition := range cudn.Status.Conditions {
697682
conditionsApply[i] = &metaapplyv1.ConditionApplyConfiguration{
698-
Type: &conditions[i].Type,
699-
Status: &conditions[i].Status,
700-
LastTransitionTime: &conditions[i].LastTransitionTime,
701-
Reason: &conditions[i].Reason,
702-
Message: &conditions[i].Message,
683+
Type: &condition.Type,
684+
Status: &condition.Status,
685+
LastTransitionTime: &condition.LastTransitionTime,
686+
Reason: &condition.Reason,
687+
Message: &condition.Message,
703688
}
704689
}
705690
var err error
@@ -720,15 +705,15 @@ func (c *Controller) updateClusterUDNStatus(cudn *userdefinednetworkv1.ClusterUs
720705
return nil
721706
}
722707

723-
func newClusterNetworCreatedCondition(nads []netv1.NetworkAttachmentDefinition, syncError error) *metav1.Condition {
708+
func newClusterNetworCreatedCondition(nads []netv1.NetworkAttachmentDefinition, syncError error) metav1.Condition {
724709
var namespaces []string
725710
for _, nad := range nads {
726711
namespaces = append(namespaces, nad.Namespace)
727712
}
728713
affectedNamespaces := strings.Join(namespaces, ", ")
729714

730715
now := metav1.Now()
731-
condition := &metav1.Condition{
716+
condition := metav1.Condition{
732717
Type: conditionTypeNetworkCreated,
733718
Status: metav1.ConditionTrue,
734719
Reason: "NetworkAttachmentDefinitionCreated",

go-controller/pkg/clustermanager/userdefinednetwork/nad.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package userdefinednetwork
33
import (
44
"encoding/json"
55
"fmt"
6+
"slices"
67

78
netv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
89

@@ -31,6 +32,8 @@ func NetAttachDefNotInUse(nad *netv1.NetworkAttachmentDefinition, pods []*corev1
3132
}
3233
}
3334
if len(connectedPods) > 0 {
35+
// Sort the connected pods to ensure a consistent error
36+
slices.Sort(connectedPods)
3437
return fmt.Errorf("network in use by the following pods: %v", connectedPods)
3538
}
3639
return nil

go-controller/pkg/controller/controller.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const (
2727
// to reconcile through its Reconcile method
2828
type Reconciler interface {
2929
Reconcile(key string)
30+
ReconcileRateLimited(key string)
3031
ReconcileAfter(key string, duration time.Duration)
3132
addHandler() error
3233
startWorkers() error
@@ -272,6 +273,10 @@ func (c *controller[T]) Reconcile(key string) {
272273
c.queue.Add(key)
273274
}
274275

276+
func (c *controller[T]) ReconcileRateLimited(key string) {
277+
c.queue.AddRateLimited(key)
278+
}
279+
275280
func (c *controller[T]) ReconcileAfter(key string, duration time.Duration) {
276281
c.queue.AddAfter(key, duration)
277282
}

0 commit comments

Comments
 (0)