Skip to content

Commit 45164f5

Browse files
committed
nfd-gc: use paging when listing CRs
List NodeFeature and NodeResourceTopology objects in pages of 200 items. This reduces memory consumption and eliminates timeouts (on the apiserver side) in big clusters of thousands of nodes.
1 parent 57f1b79 commit 45164f5

File tree

1 file changed

+35
-24
lines changed

1 file changed

+35
-24
lines changed

pkg/nfd-gc/nfd-gc.go

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"k8s.io/apimachinery/pkg/api/errors"
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2828
"k8s.io/apimachinery/pkg/labels"
29+
"k8s.io/apimachinery/pkg/runtime/schema"
2930
"k8s.io/apimachinery/pkg/util/sets"
3031
metadataclient "k8s.io/client-go/metadata"
3132
"k8s.io/client-go/metadata/metadatainformer"
@@ -152,37 +153,47 @@ func (n *nfdGarbageCollector) garbageCollect() {
152153
nodeNames.Insert(meta.Name)
153154
}
154155

155-
// Handle NodeFeature objects
156-
objMetas, err := n.client.Resource(gvrNF).List(context.TODO(), metav1.ListOptions{})
157-
if errors.IsNotFound(err) {
158-
klog.V(2).InfoS("NodeFeature CRD does not exist")
159-
} else if err != nil {
160-
klog.ErrorS(err, "failed to list NodeFeature objects")
161-
} else {
162-
for _, nf := range objMetas.Items {
163-
nodeName, ok := nf.GetLabels()[nfdv1alpha1.NodeFeatureObjNodeNameLabel]
164-
if !ok {
165-
klog.InfoS("node name label missing from NodeFeature object", "nodefeature", klog.KObj(&nf))
156+
listAndHandle := func(gvr schema.GroupVersionResource, handler func(metav1.PartialObjectMetadata)) {
157+
opts := metav1.ListOptions{
158+
Limit: 200,
159+
}
160+
for {
161+
rsp, err := n.client.Resource(gvr).List(context.TODO(), opts)
162+
if errors.IsNotFound(err) {
163+
klog.V(2).InfoS("resource does not exist", "resource", gvr)
164+
break
165+
} else if err != nil {
166+
klog.ErrorS(err, "failed to list objects", "resource", gvr)
167+
break
166168
}
167-
if !nodeNames.Has(nodeName) {
168-
n.deleteNodeFeature(nf.Namespace, nf.Name)
169+
for _, item := range rsp.Items {
170+
handler(item)
169171
}
172+
173+
if rsp.ListMeta.Continue == "" {
174+
break
175+
}
176+
opts.Continue = rsp.ListMeta.Continue
170177
}
171178
}
172179

180+
// Handle NodeFeature objects
181+
listAndHandle(gvrNF, func(meta metav1.PartialObjectMetadata) {
182+
nodeName, ok := meta.GetLabels()[nfdv1alpha1.NodeFeatureObjNodeNameLabel]
183+
if !ok {
184+
klog.InfoS("node name label missing from NodeFeature object", "nodefeature", klog.KObj(&meta))
185+
}
186+
if !nodeNames.Has(nodeName) {
187+
n.deleteNodeFeature(meta.Namespace, meta.Name)
188+
}
189+
})
190+
173191
// Handle NodeResourceTopology objects
174-
objMetas, err = n.client.Resource(gvrNRT).List(context.TODO(), metav1.ListOptions{})
175-
if errors.IsNotFound(err) {
176-
klog.V(2).InfoS("NodeResourceTopology CRD does not exist")
177-
} else if err != nil {
178-
klog.ErrorS(err, "failed to list NodeResourceTopology objects")
179-
} else {
180-
for _, nrt := range objMetas.Items {
181-
if !nodeNames.Has(nrt.Name) {
182-
n.deleteNRT(nrt.Name)
183-
}
192+
listAndHandle(gvrNRT, func(meta metav1.PartialObjectMetadata) {
193+
if !nodeNames.Has(meta.Name) {
194+
n.deleteNRT(meta.Name)
184195
}
185-
}
196+
})
186197
}
187198

188199
// periodicGC runs garbage collector at every gcPeriod to make sure we haven't missed any node

0 commit comments

Comments
 (0)