Просмотр исходного кода

Node.Labels Concurrent Modification Fix (#4050)

Signed-off-by: Sean Holcomb <seanholcomb@gmail.com>
Co-authored-by: Sean Holcomb <seanholcomb@gmail.com>
Matt Bolt 11 часов назад
Родитель
Сommit
5d605008bd

+ 2 - 1
pkg/cloud/aws/provider.go

@@ -8,6 +8,7 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"maps"
 	"net/http"
 	"os"
 	"regexp"
@@ -944,7 +945,7 @@ func (aws *AWS) DownloadPricingData() error {
 	storageClasses := aws.Clientset.GetAllStorageClasses()
 	storageClassMap := make(map[string]map[string]string)
 	for _, storageClass := range storageClasses {
-		params := storageClass.Parameters
+		params := maps.Clone(storageClass.Parameters)
 		if params != nil {
 			params["provisioner"] = storageClass.Provisioner
 		}

+ 3 - 3
pkg/costmodel/costmodel.go

@@ -289,7 +289,7 @@ func (cm *CostModel) ComputeCostData(start, end time.Time) (map[string]*CostData
 			}
 
 			nsAnnotations := namespaceAnnotationsMapping[ns+","+clusterID]
-			podAnnotations := pod.Annotations
+			podAnnotations := maps.Clone(pod.Annotations)
 			if podAnnotations == nil {
 				podAnnotations = make(map[string]string)
 			}
@@ -821,7 +821,7 @@ func (cm *CostModel) addPVData(pvClaimMapping map[string]*PersistentVolumeClaimD
 	storageClasses := cache.GetAllStorageClasses()
 	storageClassMap := make(map[string]map[string]string)
 	for _, storageClass := range storageClasses {
-		params := storageClass.Parameters
+		params := maps.Clone(storageClass.Parameters)
 		storageClassMap[storageClass.Name] = params
 		if storageClass.Annotations["storageclass.kubernetes.io/is-default-class"] == "true" || storageClass.Annotations["storageclass.beta.kubernetes.io/is-default-class"] == "true" {
 			storageClassMap["default"] = params
@@ -952,7 +952,7 @@ func (cm *CostModel) GetNodeCost() (map[string]*costAnalyzerCloud.Node, error) {
 	}
 	for _, n := range nodeList {
 		name := n.Name
-		nodeLabels := n.Labels
+		nodeLabels := maps.Clone(n.Labels)
 		if nodeLabels == nil {
 			log.Warnf("GetNodeCost: Found node '%s' with no labels", name)
 			nodeLabels = make(map[string]string)

+ 2 - 1
pkg/costmodel/metrics.go

@@ -1,6 +1,7 @@
 package costmodel
 
 import (
+	"maps"
 	"math"
 	"strconv"
 	"strings"
@@ -708,7 +709,7 @@ func (cmme *CostModelMetricsEmitter) Start() bool {
 			storageClasses := cmme.KubeClusterCache.GetAllStorageClasses()
 			storageClassMap := make(map[string]map[string]string)
 			for _, storageClass := range storageClasses {
-				params := storageClass.Parameters
+				params := maps.Clone(storageClass.Parameters)
 				storageClassMap[storageClass.Name] = params
 				if storageClass.Annotations["storageclass.kubernetes.io/is-default-class"] == "true" || storageClass.Annotations["storageclass.beta.kubernetes.io/is-default-class"] == "true" {
 					storageClassMap["default"] = params

+ 4 - 0
pkg/metrics/podlabelmetrics.go

@@ -1,6 +1,8 @@
 package metrics
 
 import (
+	"maps"
+
 	"github.com/opencost/opencost/core/pkg/clustercache"
 	"github.com/opencost/opencost/core/pkg/util/promutil"
 	"github.com/prometheus/client_golang/prometheus"
@@ -85,6 +87,8 @@ func (kpmc KubePodLabelsCollector) Collect(ch chan<- prometheus.Metric) {
 		if _, disabled := disabledMetrics["kube_pod_labels"]; !disabled {
 			podLabels := pod.Labels
 			if kpmc.metricsConfig.UseLabelsWhitelist {
+				// only clone the map if we need to remove labels
+				podLabels = maps.Clone(pod.Labels)
 				kpmc.UpdateWhitelist()
 				for lname := range pod.Labels {
 					if _, ok := kpmc.labelsWhitelist[lname]; !ok {