mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2025-03-16 21:38:23 +00:00
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.
This commit is contained in:
parent
57f1b79856
commit
45164f580a
1 changed files with 36 additions and 25 deletions
|
@ -26,6 +26,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
metadataclient "k8s.io/client-go/metadata"
|
metadataclient "k8s.io/client-go/metadata"
|
||||||
"k8s.io/client-go/metadata/metadatainformer"
|
"k8s.io/client-go/metadata/metadatainformer"
|
||||||
|
@ -152,37 +153,47 @@ func (n *nfdGarbageCollector) garbageCollect() {
|
||||||
nodeNames.Insert(meta.Name)
|
nodeNames.Insert(meta.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle NodeFeature objects
|
listAndHandle := func(gvr schema.GroupVersionResource, handler func(metav1.PartialObjectMetadata)) {
|
||||||
objMetas, err := n.client.Resource(gvrNF).List(context.TODO(), metav1.ListOptions{})
|
opts := metav1.ListOptions{
|
||||||
if errors.IsNotFound(err) {
|
Limit: 200,
|
||||||
klog.V(2).InfoS("NodeFeature CRD does not exist")
|
}
|
||||||
} else if err != nil {
|
for {
|
||||||
klog.ErrorS(err, "failed to list NodeFeature objects")
|
rsp, err := n.client.Resource(gvr).List(context.TODO(), opts)
|
||||||
} else {
|
if errors.IsNotFound(err) {
|
||||||
for _, nf := range objMetas.Items {
|
klog.V(2).InfoS("resource does not exist", "resource", gvr)
|
||||||
nodeName, ok := nf.GetLabels()[nfdv1alpha1.NodeFeatureObjNodeNameLabel]
|
break
|
||||||
if !ok {
|
} else if err != nil {
|
||||||
klog.InfoS("node name label missing from NodeFeature object", "nodefeature", klog.KObj(&nf))
|
klog.ErrorS(err, "failed to list objects", "resource", gvr)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
if !nodeNames.Has(nodeName) {
|
for _, item := range rsp.Items {
|
||||||
n.deleteNodeFeature(nf.Namespace, nf.Name)
|
handler(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rsp.ListMeta.Continue == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
opts.Continue = rsp.ListMeta.Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle NodeResourceTopology objects
|
// Handle NodeFeature objects
|
||||||
objMetas, err = n.client.Resource(gvrNRT).List(context.TODO(), metav1.ListOptions{})
|
listAndHandle(gvrNF, func(meta metav1.PartialObjectMetadata) {
|
||||||
if errors.IsNotFound(err) {
|
nodeName, ok := meta.GetLabels()[nfdv1alpha1.NodeFeatureObjNodeNameLabel]
|
||||||
klog.V(2).InfoS("NodeResourceTopology CRD does not exist")
|
if !ok {
|
||||||
} else if err != nil {
|
klog.InfoS("node name label missing from NodeFeature object", "nodefeature", klog.KObj(&meta))
|
||||||
klog.ErrorS(err, "failed to list NodeResourceTopology objects")
|
|
||||||
} else {
|
|
||||||
for _, nrt := range objMetas.Items {
|
|
||||||
if !nodeNames.Has(nrt.Name) {
|
|
||||||
n.deleteNRT(nrt.Name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if !nodeNames.Has(nodeName) {
|
||||||
|
n.deleteNodeFeature(meta.Namespace, meta.Name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Handle NodeResourceTopology objects
|
||||||
|
listAndHandle(gvrNRT, func(meta metav1.PartialObjectMetadata) {
|
||||||
|
if !nodeNames.Has(meta.Name) {
|
||||||
|
n.deleteNRT(meta.Name)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// periodicGC runs garbage collector at every gcPeriod to make sure we haven't missed any node
|
// periodicGC runs garbage collector at every gcPeriod to make sure we haven't missed any node
|
||||||
|
|
Loading…
Add table
Reference in a new issue